void CShaderObject::BindStateMatrix(const char* paramName, unsigned int matrix) { // Check and validate bind status // if(!m_bIsBound) return; // Get and validate bind point // int bind_point = glGetUniformLocation(m_shaderObject, paramName); if(bind_point < 0) return; mat4 MV, P, F; mat4_load_identity(MV); mat4_load_identity(P); if(matrix & MATRIX_MODELVIEW) glGetFloatv(GL_MODELVIEW_MATRIX, MV); if(matrix & MATRIX_PROJECTION) glGetFloatv(GL_PROJECTION_MATRIX, P); mat4_mul_mat4(P, MV, F); if(matrix & MATRIX_TRANSPOSE) mat4_transpose(F); glUniformMatrix4fv(bind_point, 1, false, F); }
mat4 transform_get_view_matrix(transform2D* trans) { mat4 mat = create_mat4(); mat4_rotate(&mat, trans->angle, 0); mat4_transpose(&mat); mat.data[12] = (-trans->x * mat.data[0]) - (trans->y * mat.data[4]); mat.data[13] = (-trans->y * mat.data[0]) + (trans->y * mat.data[4]); // TODO: Take scale into account return mat; }
mat3 *GFX_get_normal_matrix( void ) { mat4 mat; mat4_copy_mat4( &mat, GFX_get_modelview_matrix() ); mat4_invert_full( &mat ); mat4_transpose( &mat ); mat3_copy_mat4( &gfx.normal_matrix, &mat ); return &gfx.normal_matrix; }
void render_debug(geometry *in, mat4_t model, mat4_t view, mat4_t projection) { glUseProgram(in->debug_geometry.program); float mvp[16]; mat4_multiply(projection, view, mvp); mat4_multiply(mvp, model , mvp); float normal_matrix[16]; mat4_multiply(view, model , normal_matrix); mat4_inverse(normal_matrix, normal_matrix); mat4_transpose(normal_matrix, normal_matrix); glUniformMatrix4fv(in->debug_geometry.uniform.mvp_matrix, 1, GL_FALSE, mvp); glDrawArrays(GL_LINES, 0, in->vertex_count * 2); }
static void redraw(struct glwin *win) { struct glwin_thread_state thread_state; glwin_get_thread_state(&thread_state); glwin_make_current(win, g_ctx); lua_State *L = g_L; static bool gl_init_attempted = false; static bool gl_init_result = false; if (!gl_init_attempted) { gl_init_result = glb_glcore_init(3, 3); } if (!gl_init_result) { printf("Failed to initialize OpenGL bindings\n"); exit(-1); return; } glViewport(0, 0, win->width, win->height); glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); lua_getglobal(L, "b2l_data"); //1 if (!lua_istable(L, -1)) { lua_pop(L, 1); goto end; } lua_getfield(L, -1, "objects"); //2 lua_getglobal(L, "current_object"); //3 if (!lua_isstring(L, -1)) { lua_pop(L, 3); goto end; } const char *current_object = lua_tostring(L, -1); lua_getfield(L, -2, current_object); //4 if (lua_isnil(L, -1)) { lua_pop(L, 4); goto end; } lua_getfield(L, -1, "type"); //5 if(strcmp(lua_tostring(L, -1), "MESH")) { lua_pop(L, 5); goto end; } lua_getfield(L, -2, "data"); //6 lua_getfield(L, -6, "meshes"); //7 lua_getfield(L, -1, lua_tostring(L, -2)); //8 if (lua_isnil(L, -1)) { lua_pop(L, 8); goto end; } if (!g_gl_state.initialized) init_gl_state(); if (g_gl_state.recompile_shaders) g_gl_state.program_valid = recompile_shaders(); if (!g_gl_state.initialized || !g_gl_state.program_valid) { lua_pop(L, 8); goto end; } g_gl_state.recompile_shaders = false; glUseProgram(g_gl_state.program); glBindVertexArray(g_gl_state.vao); if (g_gl_state.blob_updated) { glBufferData(GL_ARRAY_BUFFER, g_gl_state.blob_size, g_gl_state.blob ,GL_STATIC_DRAW); g_gl_state.blob_updated = false; } lua_getfield(L, -1, "vertex_normal_array_offset"); //9 int vertex_normal_array_offset = lua_tointeger(L, -1); lua_getfield(L, -2, "uv_array_offset"); //10 int uv_array_offset = lua_tointeger(L, -1); lua_getfield(L, -3, "uv_layers"); //11 lua_len(L, -1); //12 int num_uv_layers = lua_tointeger(L, -1); int tangent_array_offset; if (num_uv_layers > 0) { lua_getfield(L, -5, "tangent_array_offset"); tangent_array_offset = lua_tointeger(L, -1); lua_pop(L, 1); } lua_getfield(L, -5, "vertex_co_array_offset"); //13 int vertex_co_array_offset = lua_tointeger(L, -1); lua_getfield(L, -6, "weights_per_vertex"); //14 int weights_per_vertex = lua_tointeger(L, -1); int weights_array_offset; if (weights_per_vertex > 0) { lua_getfield(L, -7, "weights_array_offset"); weights_array_offset = lua_tointeger(L, -1); lua_pop(L, 1); } else { weights_array_offset = -1; } lua_getfield(L, -11, "vertex_groups"); //15 int num_vertex_groups; if (lua_isnil(L, -1)) { num_vertex_groups = 0; } else { lua_len(L, -1); num_vertex_groups = lua_tointeger(L, -1); lua_pop(L, 1); } glBindVertexBuffer(NORMAL, g_gl_state.vbo, vertex_normal_array_offset, sizeof(float) * 3); if (num_uv_layers > 0) { glBindVertexBuffer(UV, g_gl_state.vbo, uv_array_offset, sizeof(float) * 2 * num_uv_layers); glBindVertexBuffer(TANGENT, g_gl_state.vbo, tangent_array_offset, sizeof(float) * 4); } glBindVertexBuffer(POS, g_gl_state.vbo, vertex_co_array_offset, sizeof(float) * 3); if (weights_per_vertex > 0) glBindVertexBuffer(WEIGHTS, g_gl_state.vbo, weights_array_offset, weights_per_vertex * 4); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_gl_state.vbo); if (g_gl_state.normal_index >= 0) { glEnableVertexAttribArray(g_gl_state.normal_index); glVertexAttribFormat(g_gl_state.normal_index, 3, GL_FLOAT, GL_FALSE, 0); glVertexAttribBinding(g_gl_state.normal_index, NORMAL); } if (g_gl_state.uv_index >= 0) { glEnableVertexAttribArray(g_gl_state.uv_index); glVertexAttribFormat(g_gl_state.uv_index, 2, GL_FLOAT, GL_FALSE, 0); glVertexAttribBinding(g_gl_state.uv_index, UV); } if (g_gl_state.pos_index >= 0) { glEnableVertexAttribArray(g_gl_state.pos_index); glVertexAttribFormat(g_gl_state.pos_index, 3, GL_FLOAT, GL_FALSE, 0); glVertexAttribBinding(g_gl_state.pos_index, POS); } int i = 0; for (i = 0; i < 6; i++) { if (g_gl_state.weights_index[i] >= 0 && weights_per_vertex > 0) { glEnableVertexAttribArray(g_gl_state.weights_index[i]); glVertexAttribIFormat(g_gl_state.weights_index[i], 2, GL_SHORT, 4 * i); glVertexAttribBinding(g_gl_state.weights_index[i], WEIGHTS); } } if (num_uv_layers > 0 && g_gl_state.tangent_index >= 0) { glEnableVertexAttribArray(g_gl_state.tangent_index); glVertexAttribFormat(g_gl_state.tangent_index, 4, GL_FLOAT, GL_FALSE, 0); glVertexAttribBinding(g_gl_state.tangent_index, TANGENT); } struct mat4 view; struct mat4 model; struct quaternion next; quaternion_mul(&q_delta, &q_cur, &next); quaternion_to_mat4(&next, &view); view.v[3][3] = 1; mat4_identity(&model); model.v[3][0] = g_offset[0] + g_offset_next[0]; model.v[3][1] = g_offset[1] + g_offset_next[1]; model.v[3][2] = g_offset[2] + g_offset_next[2]; glUniformMatrix4fv(glGetUniformLocation(g_gl_state.program, "model"), 1, GL_FALSE, (GLfloat *)&model); struct mat4 ident; mat4_identity(&ident); glUniformMatrix4fv(glGetUniformLocation(g_gl_state.program, "view"), 1, GL_FALSE, (GLfloat *)&view); float zoom = exp(g_log_zoom); float zr = 100; struct mat4 proj; mat4_zero(&proj); proj.v[0][0] = 1.0/zoom; proj.v[1][1] = 1.0*win->width/(zoom*win->height); proj.v[2][2] = 1.0/zr; proj.v[3][3] = 1.0; glUniformMatrix4fv(glGetUniformLocation(g_gl_state.program, "proj"), 1, GL_FALSE, (GLfloat *)&proj); if (weights_per_vertex > 0) { static int render_count = 0; render_count++; double frame; int frame_start; int frame_end; lua_getglobal(L, "frame_start"); //16 frame_start = lua_tointeger(L, -1); lua_getglobal(L, "frame_end"); //17 frame_end = lua_tointeger(L, -1); lua_getglobal(L, "frame_delta"); //18 frame = frame_start + lua_tonumber(L, -1); int frame_i = floorf(frame); double frame_fract = frame - frame_i; lua_getfield(L, -18, "scenes"); //19 lua_getglobal(L, "current_scene"); //20 lua_getfield(L, -2, lua_tostring(L, -1)); //21 if (!lua_istable(L, -1)) { lua_pop(L, 20); goto end; } lua_getfield(L, -1, "objects"); lua_getfield(L, -1, current_object); lua_getfield(L, -1, "vertex_group_transform_array_offset"); int offset = lua_tointeger(L, -1); lua_pop(L, 9); int stride = sizeof(float) * 4 * 4 * num_vertex_groups; int i; for (i = 0; i < num_vertex_groups; i++) { struct mat4 res; struct mat4 M1; struct mat4 M2; struct mat4 *base = (struct mat4 *)(g_gl_state.blob + offset + (i * sizeof(float) * 4 * 4) + frame_i * stride); struct mat4 *next = (struct mat4 *)(g_gl_state.blob + offset + (i * sizeof(float) * 4 * 4) + (frame_i + 1) * stride); if (frame_i == (frame_end-1)) { next = (struct mat4 *)(g_gl_state.blob + offset + i * sizeof(float) * 4 * 4 + (frame_start) * stride); } else if (frame_fract == 0) { next = base; } #if USE_SLERP struct mat4 temp; mat4_zero(&temp); temp.v[3][3] = 1; M1 = *base; M2 = *next; spherical_lerp(M1.v[0], M2.v[0], frame_fract, temp.v[0]); spherical_lerp(M1.v[1], M2.v[1], frame_fract, temp.v[1]); spherical_lerp(M1.v[2], M2.v[2], frame_fract, temp.v[2]); mat4_transpose(&temp, &res); float v1[3]; float v2[3]; v1[0] = M1.v[0][3]; v1[1] = M1.v[1][3]; v1[2] = M1.v[2][3]; v2[0] = M2.v[0][3]; v2[1] = M2.v[1][3]; v2[2] = M2.v[2][3]; lerp(v1, v2, frame_fract, res.v[3]); #else mat4_zero(&res); res.v[3][3] = 1; mat4_transpose(base, &M1); mat4_transpose(next, &M2); lerp(M1.v[0], M2.v[0], frame_fract, res.v[0]); lerp(M1.v[1], M2.v[1], frame_fract, res.v[1]); lerp(M1.v[2], M2.v[2], frame_fract, res.v[2]); lerp(M1.v[3], M2.v[3], frame_fract, res.v[3]); #endif glUniformMatrix4fv(g_gl_state.groups_index + i, 1, /*num_vertex_groups, */ GL_FALSE, (GLfloat *)&res); } } lua_getglobal(L, "controls"); //16 int controls = lua_gettop(L); lua_getglobal(L, "materials"); //17 int materials = lua_gettop(L); lua_getfield(L, -10, "index_array_offset"); //18 int index_array_offset = lua_tointeger(L, -1); lua_getfield(L, -11, "submeshes"); //19 lua_len(L, -1); //20 int num_submeshes = lua_tointeger(L, -1); for (i = 0; i < num_submeshes; i++) { lua_rawgeti(L, -2, i + 1); lua_getfield(L, -1, "material_name"); const char *material_name = lua_tostring(L, -1); lua_getfield(L, -2, "triangle_no"); int triangle_no = lua_tointeger(L, -1); lua_getfield(L, -3, "triangle_count"); int triangle_count = lua_tointeger(L, -1); lua_getfield(L, materials, material_name); lua_getfield(L, -1, "params"); lua_pushnil(L); /* first key */ while (lua_next(L, -2)) { int variable = lua_gettop(L); const char *variable_name = lua_tostring(L, variable - 1); int uniform_loc = glGetUniformLocation(g_gl_state.program, variable_name); if (uniform_loc == -1) { lua_pop(L, 1); continue; } lua_getfield(L, variable, "value"); int value = variable + 1; lua_getfield(L, variable, "datatype"); const char *datatype = strdup(lua_tostring(L, -1)); lua_pop(L, 1); if (!strcmp(datatype, "bool")) { int bool_value = lua_toboolean(L, value); glUniform1i(uniform_loc, bool_value); } else if (!strcmp(datatype, "vec3")) { lua_rawgeti(L, value, 1); lua_rawgeti(L, value, 2); lua_rawgeti(L, value, 3); float val[3]; val[0] = (float)lua_tonumber(L, -3); val[1] = (float)lua_tonumber(L, -2); val[2] = (float)lua_tonumber(L, -1); glUniform3fv(uniform_loc, 1, val); lua_pop(L, 3); } else if (!strcmp(datatype, "float")) { float fval = lua_tonumber(L, value); glUniform1f(uniform_loc, fval); } else if (!strcmp(datatype, "sampler2D")) { lua_getfield(L, controls, variable_name); int control = lua_gettop(L); lua_getfield(L, control, "needs_upload"); int needs_upload = lua_toboolean(L, -1); lua_pop(L, 1); if (needs_upload) { int texunit; GdkPixbuf *pbuf; lua_getfield(L, control, "texunit"); texunit = lua_tointeger(L, -1) - 1; lua_pop(L, 1); lua_getfield(L, control, "pbuf"); lua_getfield(L, -1, "_native"); pbuf = (GdkPixbuf *)lua_touserdata(L, -1); lua_pop(L, 2); glActiveTexture(GL_TEXTURE0 + texunit); glBindTexture(GL_TEXTURE_2D, g_texture_names[texunit]); int width = gdk_pixbuf_get_width(pbuf); int height = gdk_pixbuf_get_height(pbuf); int n_chan = gdk_pixbuf_get_n_channels(pbuf); glPixelStorei(GL_UNPACK_ROW_LENGTH, gdk_pixbuf_get_rowstride(pbuf)/ n_chan); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, /* level */ n_chan > 3 ? GL_RGBA : GL_RGB, width, height, 0, /* border */ n_chan > 3 ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, gdk_pixbuf_get_pixels(pbuf)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glGenerateMipmap(GL_TEXTURE_2D); glUniform1i(uniform_loc, texunit); lua_pushboolean(L, 0); lua_setfield(L, control, "needs_upload"); } lua_pop(L, 1); } free((void *)datatype); lua_pop(L, 2); } //while (lua_next(L, -2) != 0) glDrawElements(GL_TRIANGLES, 3 * triangle_count, GL_UNSIGNED_SHORT, (void *)((int64_t)index_array_offset) + 3 * 2 * triangle_no); lua_pop(L, 6); } lua_pop(L, 20); end: { GLenum err = glGetError(); if (err) printf("render_scene GL error = %d\n", err); } glwin_swap_buffers(g_win); glwin_set_thread_state(&thread_state); g_need_redraw = false; return; }
animation* ani_load_file(char* filename) { int state = STATE_LOAD_EMPTY; animation* a = animation_new(); skeleton* base = skeleton_new(); frame* f = NULL; SDL_RWops* file = SDL_RWFromFile(filename, "r"); if(file == NULL) { error("Could not load file %s", filename); } char line[1024]; while(SDL_RWreadline(file, line, 1024)) { if (state == STATE_LOAD_EMPTY) { int version; if (sscanf(line, "version %i", &version) > 0) { if (version != 1) { error("Can't load ani file '%s'. Don't know how to load version %i\n", filename, version); } } if (strstr(line, "nodes")) { state = STATE_LOAD_NODES; } if (strstr(line, "skeleton")) { state = STATE_LOAD_SKELETON; } } else if (state == STATE_LOAD_NODES) { char name[1024]; int id, parent; if (sscanf(line, "%i \"%[^\"]\" %i", &id, name, &parent) == 3) { skeleton_joint_add(base, name, parent); } if (strstr(line, "end")) { state = STATE_LOAD_EMPTY; } } else if (state == STATE_LOAD_SKELETON) { float time; if (sscanf(line, "time %f", &time) == 1) { f = animation_add_frame(a, base->rest_pose); } int id; float x, y, z, rx, ry, rz; if (sscanf(line, "%i %f %f %f %f %f %f", &id, &x, &y, &z, &rx, &ry, &rz) > 0) { f->joint_positions[id] = vec3_new(x, z, y); mat4 rotation = mat4_rotation_euler(rx, ry, rz); mat4 handedflip = mat4_new(1,0,0,0, 0,0,1,0, 0,1,0,0, 0,0,0,1); rotation = mat4_mul_mat4(handedflip, rotation); rotation = mat4_mul_mat4(rotation, handedflip); rotation = mat4_transpose(rotation); f->joint_rotations[id] = mat4_to_quat(rotation); } if (strstr(line, "end")) { state = STATE_LOAD_EMPTY; } } } SDL_RWclose(file); skeleton_delete(base); return a; }
static int _llfunc_mat4_transpose(lua_State *L) { mat4 *m = (mat4*)userdata_get_or_die(L, 1); mat4_transpose(m); return 0; }
/* How do you find the adjoint of a 4x4 matrix? Find the cofactor (determinant of the signed minor) of each entry, keeping in mind the sign array (starting with + in the upper left corner): [+ - + -] [- + - +] [+ - + -] [- + - +] // // 11 12 13 14 // 21 22 23 24 // 31 32 33 34 // 41 42 43 44 // // c = adjoint(a) */ void mat4_adjoint(mat4 &c, const mat4 &a) { mat3 m3; mat4 m4; // Create matrix of minors // Apply +- pattern to create matrix of cofactors // 11 m3.m11 = a.m22; m3.m12 = a.m23; m3.m13 = a.m24; m3.m21 = a.m32; m3.m22 = a.m33; m3.m23 = a.m34; m3.m31 = a.m42; m3.m32 = a.m43; m3.m33 = a.m44; m4.m11 = mat3_determinant(m3); // 12 m3.m11 = a.m21; m3.m12 = a.m23; m3.m13 = a.m24; m3.m21 = a.m31; m3.m22 = a.m33; m3.m23 = a.m34; m3.m31 = a.m41; m3.m32 = a.m43; m3.m33 = a.m44; m4.m12 = -mat3_determinant(m3); // 13 m3.m11 = a.m21; m3.m12 = a.m22; m3.m13 = a.m24; m3.m21 = a.m31; m3.m22 = a.m32; m3.m23 = a.m34; m3.m31 = a.m41; m3.m32 = a.m42; m3.m33 = a.m44; m4.m13 = mat3_determinant(m3); // 14 m3.m11 = a.m21; m3.m12 = a.m22; m3.m13 = a.m23; m3.m21 = a.m31; m3.m22 = a.m32; m3.m23 = a.m33; m3.m31 = a.m41; m3.m32 = a.m42; m3.m33 = a.m43; m4.m14 = -mat3_determinant(m3); // 21 m3.m11 = a.m12; m3.m12 = a.m13; m3.m13 = a.m14; m3.m21 = a.m32; m3.m22 = a.m33; m3.m23 = a.m34; m3.m31 = a.m42; m3.m32 = a.m43; m3.m33 = a.m44; m4.m21 = -mat3_determinant(m3); // 22 m3.m11 = a.m11; m3.m12 = a.m13; m3.m13 = a.m14; m3.m21 = a.m31; m3.m22 = a.m33; m3.m23 = a.m34; m3.m31 = a.m41; m3.m32 = a.m43; m3.m33 = a.m44; m4.m22 = mat3_determinant(m3); // 23 m3.m11 = a.m11; m3.m12 = a.m12; m3.m13 = a.m14; m3.m21 = a.m31; m3.m22 = a.m32; m3.m23 = a.m34; m3.m31 = a.m41; m3.m32 = a.m42; m3.m33 = a.m44; m4.m23 = -mat3_determinant(m3); // 24 m3.m11 = a.m11; m3.m12 = a.m12; m3.m13 = a.m13; m3.m21 = a.m31; m3.m22 = a.m32; m3.m23 = a.m33; m3.m31 = a.m41; m3.m32 = a.m42; m3.m33 = a.m43; m4.m24 = mat3_determinant(m3); // 31 m3.m11 = a.m12; m3.m12 = a.m13; m3.m13 = a.m14; m3.m21 = a.m22; m3.m22 = a.m23; m3.m23 = a.m24; m3.m31 = a.m42; m3.m32 = a.m43; m3.m33 = a.m44; m4.m31 = mat3_determinant(m3); // 32 m3.m11 = a.m11; m3.m12 = a.m13; m3.m13 = a.m14; m3.m21 = a.m21; m3.m22 = a.m23; m3.m23 = a.m24; m3.m31 = a.m41; m3.m32 = a.m43; m3.m33 = a.m44; m4.m32 = -mat3_determinant(m3); // 33 m3.m11 = a.m11; m3.m12 = a.m12; m3.m13 = a.m14; m3.m21 = a.m21; m3.m22 = a.m22; m3.m23 = a.m24; m3.m31 = a.m41; m3.m32 = a.m42; m3.m33 = a.m44; m4.m33 = mat3_determinant(m3); // 34 m3.m11 = a.m11; m3.m12 = a.m12; m3.m13 = a.m13; m3.m21 = a.m21; m3.m22 = a.m22; m3.m23 = a.m23; m3.m31 = a.m41; m3.m32 = a.m42; m3.m33 = a.m43; m4.m34 = -mat3_determinant(m3); // 41 m3.m11 = a.m12; m3.m12 = a.m13; m3.m13 = a.m14; m3.m21 = a.m22; m3.m22 = a.m23; m3.m23 = a.m24; m3.m31 = a.m32; m3.m32 = a.m33; m3.m33 = a.m34; m4.m41 = -mat3_determinant(m3); // 42 m3.m11 = a.m11; m3.m12 = a.m13; m3.m13 = a.m14; m3.m21 = a.m21; m3.m22 = a.m23; m3.m23 = a.m24; m3.m31 = a.m31; m3.m32 = a.m33; m3.m33 = a.m34; m4.m42 = mat3_determinant(m3); // 43 m3.m11 = a.m11; m3.m12 = a.m12; m3.m13 = a.m14; m3.m21 = a.m21; m3.m22 = a.m22; m3.m23 = a.m24; m3.m31 = a.m31; m3.m32 = a.m32; m3.m33 = a.m34; m4.m43 = -mat3_determinant(m3); // 44 m3.m11 = a.m11; m3.m12 = a.m12; m3.m13 = a.m13; m3.m21 = a.m21; m3.m22 = a.m22; m3.m23 = a.m23; m3.m31 = a.m31; m3.m32 = a.m32; m3.m33 = a.m33; m4.m44 = mat3_determinant(m3); // create adjoint by transposing mat4_transpose(c, m4); }
void hostviewport_render( struct arena* vp, struct style* aa, struct arena* win, struct style* st) { int j; struct datapair* mod; float cammvp[4*4]; float w,h,x0,y0,x1,y1; w = win->fbwidth; h = win->fbheight; x0 = w * st->vc[0]; //0 y0 = h * st->vc[1]; //0 x1 = w * st->vq[0]; //0.5 y1 = h * st->vq[1]; //1 // vp->width = vp->fbwidth = x1; vp->height = vp->fbheight = y1; glViewport(x0, y0, x1, y1); // struct relation* rel; struct arena* ctxnode; rel = vp->orel0; while(1){ if(0 == rel)break; if(_win_ == rel->dsttype){ ctxnode = (void*)(rel->dstchip); if(ctxnode)goto found; break; } rel = samesrcnextdst(rel); } return; found: fixmatrix(cammvp, vp); mat4_transpose((void*)cammvp); //solid mod = ctxnode->gl_solid; for(j=0;j<64;j++) { if(0 == mod[j].src.vbuf)continue; display_eachpass(&mod[j].dst, &mod[j].src, vp, cammvp); } //opaque glDepthMask(GL_FALSE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); mod = ctxnode->gl_opaque; for(j=0;j<64;j++) { if(0 == mod[j].src.vbuf)continue; display_eachpass(&mod[j].dst, &mod[j].src, vp, cammvp); } glDisable(GL_BLEND); glDepthMask(GL_TRUE); }
static bool ray_surface_intersect(Ray ray, const Surface *surf, Hit *hit) { float ts[2] = {-HUGE_VAL, -HUGE_VAL}, t; Vec3 tnormals[2] = {{0,0,0},{0,0,0}}, tnormal; Ray tray; Mat4 normal_matrix; Shape *shape = surf->shape; int hits; mat4_copy(normal_matrix, surf->world_to_model); mat4_transpose(normal_matrix); tray.origin = mat4_transform3_homo(surf->world_to_model, ray.origin); tray.direction = mat4_transform3_hetero(surf->world_to_model, ray.direction); tray.near = ray.near; tray.far = ray.far; switch(shape->type) { case SHAPE_PLANE: hits = ray_plane_intersect(tray, shape->u.plane, ts, tnormals); break; case SHAPE_DISK: hits = ray_disk_intersect(tray, shape->u.disk, ts, tnormals); break; case SHAPE_SPHERE: hits = ray_sphere_intersect(tray, shape->u.sphere, ts, tnormals); break; case SHAPE_CYLINDER: hits = ray_cylinder_intersect(tray, shape->u.cylinder, ts, tnormals); break; case SHAPE_CONE: hits = ray_cone_intersect(tray, shape->u.cone, ts, tnormals); break; case SHAPE_MESH: hits = ray_mesh_intersect(tray, shape->u.mesh, ts, tnormals); break; default: printf("Unknown shape\n"); return false; break; } /* We're looking for the smallest hit that is between the near and far * planes of the ray. */ if (hits == 0) return false; if (hits == 1) { if (ts[0] < ray.near || ts[0] > ray.far) return false; t = ts[0]; tnormal = tnormals[0]; } else if (hits == 2) { bool t0_ok = ts[0] >= ray.near && ts[0] <= ray.far; bool t1_ok = ts[1] >= ray.near && ts[1] <= ray.far; if (!t0_ok && !t1_ok) { return false; } else if (t0_ok && !t1_ok) { t = ts[0]; tnormal = tnormals[0]; } else if (!t0_ok && t1_ok) { t = ts[1]; tnormal = tnormals[1]; } else { if (ts[0] < ts[1]) { t = ts[0]; tnormal = tnormals[0]; } else { t = ts[1]; tnormal = tnormals[1]; } } } else { printf("General t finding code unimplemented\n"); return false; } hit->t = t; hit->position = vec3_add(ray.origin, vec3_scale(t, ray.direction)); hit->normal = vec3_normalize(mat4_transform3_hetero(normal_matrix, tnormal)); return true; }