static void upload_gbuffer_uniforms(GLuint shdr, float viewport[2], mat4* view, mat4* proj) { glUniform1i(glGetUniformLocation(shdr, "gbuf.depth"), 0); glUniform1i(glGetUniformLocation(shdr, "gbuf.normal"), 1); glUniform1i(glGetUniformLocation(shdr, "gbuf.albedo"), 2); glUniform1i(glGetUniformLocation(shdr, "gbuf.roughness_metallic"), 3); glUniform2fv(glGetUniformLocation(shdr, "u_screen"), 1, viewport); mat4 inv_view_proj = mat4_inverse(mat4_mul_mat4(*proj, *view)); glUniformMatrix4fv(glGetUniformLocation(shdr, "u_inv_view_proj"), 1, GL_FALSE, inv_view_proj.m); }
Vec3 Util_GetMouseRay(int screenWidth, int screenHeigth, Mat4 *viewMatrix, Mat4 *projectionMatrix, int mouseX, int mouseY) { Vec4 eyeCoords; Vec3 mouseRay; /* Normalized device coords NOTE: -y becouse for SDL y = 0 is the top of the screen */ GLfloat normalX = ( 2.0f * (GLfloat)mouseX ) / (GLfloat) screenWidth - 1.0f; GLfloat normalY = 1.0f - (2.0f * (GLfloat)mouseY) / (GLfloat) screenHeigth; /* clipCoords include 4th component */ Vec4 clipCoords = { normalX, normalY, -1.0f, 1.0f }; /* Remove perpective */ { Mat4 invertedProjection = mat4_inverse(projectionMatrix); eyeCoords = mat4_mul_vec4(&invertedProjection, &clipCoords); eyeCoords.z = -1.0f; eyeCoords.w = 0.0f; } /* Remove view matrix*/ { Mat4 invertedViewMatrix = mat4_inverse(viewMatrix); Vec4 temp = mat4_mul_vec4(&invertedViewMatrix, &eyeCoords); mouseRay.x = temp.x; mouseRay.y = temp.y; mouseRay.z = temp.z; mouseRay = vec3_normalize(&mouseRay); } /* Return the ray in world coordinates */ return mouseRay; }
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); }
int main(int argc, char **argv) { for (int i = 1; i < argc; i += 1) { if (!strcmp(argv[i], "-help")) { printf("option: -help -list\n"); printf("selection: all || test_name || skip_test_name\n"); return 0; } } uint num_test_performed = 0; m_scope_exit(printf("Performed %d tests\n", num_test_performed)); m_test(math) { m_case(matrix) { mat4 m = mat4{} * mat4_identity(); m_assert(m == mat4{}); m = mat4_identity(); mat4 m_inv = mat4_inverse(m); m_assert(m == m_inv); } } }
vec3_t vec3_unproject(vec3_t vec, mat4_t view, mat4_t proj, vec4_t viewport, vec3_t dest) { if (!dest) { dest = vec; } mat4_t m = mat4_create(NULL); double *v = malloc(sizeof(double) * 4); v[0] = (vec[0] - viewport[0]) * 2.0 / viewport[2] - 1.0; v[1] = (vec[1] - viewport[1]) * 2.0 / viewport[3] - 1.0; v[2] = 2.0 * vec[2] - 1.0; v[3] = 1.0; mat4_multiply(proj, view, m); if(!mat4_inverse(m, NULL)) { return NULL; } mat4_multiplyVec4(m, v, NULL); if(v[3] == 0.0) { return NULL; } dest[0] = v[0] / v[3]; dest[1] = v[1] / v[3]; dest[2] = v[2] / v[3]; return dest; }
void test_mat4() { /* // Matrix local m = vec.Mat4.frustum(-10, 10, -10, 10, -10, 10) local m = vec.Mat4.perspective(90, 1, 1, 100) local m = vec.Mat4.lookAt(vec.Vec3(10, 9, 8), vec.Vec3(1, 2, 3), vec.Vec3(0, 1, 0)) local m = vec.Mat4.ortho(-10, 100, -10, 10, -10, 10) local m = vec.Mat4.identity() local m = vec.Mat4.translate(vec.Vec3(1, 2, 3)) local m = vec.Mat4.scale(1, 2, 3) local m = vec.Mat4.rotate(vec.Quat.new(1, 2, 3, 8)) local m = vec.Mat4.perspective(90, 1, 1, 100):inverse() local a = vec.Mat4.translate(vec.Vec3(1, 2, 3)) local b = vec.Mat4.perspective(90, 1, 1, 100) local m = a * b local v3 = m * vec.Vec4(1, 2, 3, 4) */ struct vec3 eye = {0, -15, 30}; struct vec3 at = {0, 0, 0}; struct vec3 up = {0, 1, 0}; struct mat4 m = mat4_look(&eye, &at, &up); struct vec4 zero = {0, 0, 0, 1}; struct vec4 v4 = mat4_mul_vec4(&m, &zero); assert(v4.x == 0); assert(v4.y == 0); assert((v4.z - (-33.541019)) < 0.00001); struct mat4 inv = mat4_inverse(&m); struct vec4 v5 = mat4_mul_vec4(&inv, &zero); assert(v5.x == 0); assert(v5.y - (-15) < 0.00001); assert(v5.z - (30) < 0.00001); }
void update_game(Game* G) { float delta_time = (float)get_delta_time(G->timer); int ii; _control_camera(G, delta_time); set_view_matrix(G->graphics, mat4_inverse(transform_get_matrix(G->camera))); /* Dynamic Lights */ if(G->dynamic_lights) { G->sun_light.position = mat3_mul_vector(vec3_create(5,5,0), mat3_rotation_y((float)get_running_time(G->timer)*0.5f)); G->light_transform += delta_time; for(ii=0;ii<NUM_LIGHTS;++ii) { if(ii % 2) G->lights[ii].position.z = sinf((G->light_transform + ii * 1.0f)/2.0f) * 10.0f; else G->lights[ii].position.x = sinf((G->light_transform + ii * 1.0f)/2.0f) * 10.0f; } } add_light(G->graphics, G->sun_light); for(ii=0;ii<NUM_LIGHTS;++ii) { add_light(G->graphics, G->lights[ii]); } render_scene(G->scene, G->graphics); G->tap_timer += delta_time; /* Calculate FPS */ G->fps_time += delta_time; G->fps_count++; if(G->fps_time >= 1.0f) { G->fps = G->fps_count/G->fps_time; system_log("FPS: %f\n", G->fps); G->fps_time -= 1.0f; G->fps_count = 0; } { int width, height; float scale = 50.0f; float x = -G->width/2.0f; float y = G->height/2.0f-scale; char buffer[256] = {0}; // FPS sprintf(buffer, "FPS: %.2f", G->fps); add_string(G->ui, x, y, scale, buffer); y -= scale; // Renderer switch(renderer_type(G->graphics)) { case kForward: add_string(G->ui, x, y, scale, "Forward renderer"); break; case kLightPrePass: add_string(G->ui, x, y, scale, "Deferred Lighting"); break; case kDeferred: add_string(G->ui, x, y, scale, "Deferred Shading"); break; default: assert(!"Invalid renderer"); break; } y -= scale; // Resolution graphics_size(G->graphics, &width, &height); sprintf(buffer, "%dx%d", width, height); add_string(G->ui, x, y, scale, buffer); } }
static int _llfunc_mat4_inverse(lua_State *L) { mat4 *m = (mat4*)userdata_get_or_die(L, 1); mat4_inverse(m); return 0; }
void render_update(double last_frame_time) { static int isolevel_offset = 1; matrix4f model_inv_mat4; matrix3f model_inv_mat3; vector3f camera_pos; IF_FAILED(init); mat4(modelmat, 1.0f); last_time = last_frame_time; // обновляем камеру (позицию и т.п) update_camera(last_frame_time); // поулчаем параметры камеры camera_pos = camera_get_position(&camera); camera_get_view_matrix(&camera, viewmat); camera_get_projection_matrix(&camera, projectionmat); // обновляем вращение объекта (arcball) update_object_orientation(); mat4_mult2(modelmat, rotmat, modelmat); // смещаем объект matrix4f translatemat; mat4_translate(translatemat, -0.5f, -0.5f, -0.5f); mat4_mult2(modelmat, modelmat, translatemat); // вращаем источник света if(light_animate) { light_rot_angle += light_rot_step; if(light_rot_angle > 360.0f) light_rot_angle = 0.0f; } matrix4f light_mat; mat4_rotate_axis(light_mat, light_rot_angle, vec3f(0.0f, 1.0f, 0.0f)); new_light_position = mat4_mult_vec3(light_mat, light_position); // изменяем изо-уровень if(isolevel_animate) { isolevel += isolevel_step * isolevel_offset; if(isolevel_begin <= isolevel_end) { if(isolevel >= isolevel_end) isolevel_offset = -1; else if(isolevel < isolevel_begin) isolevel_offset = 1; } else { if(isolevel < isolevel_end) isolevel_offset = 1; else if(isolevel >= isolevel_begin) isolevel_offset = -1; } } mat4_inverse(model_inv_mat4, modelmat); mat4_submat(model_inv_mat3, 3, 3, model_inv_mat4); // обновляем вершинные буферы if(isolevel_animate) render_update_mc(); shader_program_bind(&program); // устанавливаем юниформы glUniformMatrix4fv(uniform_modelmat, 1, GL_TRUE, (const GLfloat *) modelmat); glUniformMatrix4fv(uniform_viewmat, 1, GL_TRUE, (const GLfloat *) viewmat); glUniformMatrix4fv(uniform_projectionmat, 1, GL_TRUE, (const GLfloat *) projectionmat); glUniformMatrix3fv(uniform_model_inv, 1, GL_TRUE, (const GLfloat *) model_inv_mat3); glUniform3f(uniform_light_pos, new_light_position.x, new_light_position.y, new_light_position.z); glUniform3f(uniform_viewer_pos, camera_pos.x, camera_pos.y, camera_pos.z); glUniform1f(uniform_coef_ambient, coef_ambient); glUniform1f(uniform_coef_diffuse, coef_diffuse); glUniform1f(uniform_coef_specular, coef_specular); glUniform1f(uniform_material_shininess, material_shininess); glUniform1f(uniform_coef_gamma, coef_gamma); glUniform3f(uniform_material_front_color, material_front_color.x, material_front_color.y, material_front_color.z); glUniform3f(uniform_material_back_color, material_back_color.x, material_back_color.y, material_back_color.z); glUniform3f(uniform_light_color, light_color.x, light_color.y, light_color.z); glUniform3f(uniform_light_spec_color, light_spec_color.x, light_spec_color.y, light_spec_color.z); shader_program_unbind(&program); }