static void deferred_renderer_use_material(material* mat, shader_program* PROG) { /* Set material parameters */ int tex_counter = 0; for(int i = 0; i < mat->keys->num_items; i++) { char* key = list_get(mat->keys, i); int* type = dictionary_get(mat->types, key); void* property = dictionary_get(mat->properties, key); GLint loc = glGetUniformLocation(shader_program_handle(PROG), key); GLint world_matrix_u = glGetUniformLocation(shader_program_handle(PROG), "world_matrix"); glUniformMatrix4fv(world_matrix_u, 1, 0, WORLD_MATRIX); GLint proj_matrix_u = glGetUniformLocation(shader_program_handle(PROG), "proj_matrix"); glUniformMatrix4fv(proj_matrix_u, 1, 0, PROJ_MATRIX); GLint view_matrix_u = glGetUniformLocation(shader_program_handle(PROG), "view_matrix"); glUniformMatrix4fv(view_matrix_u, 1, 0, VIEW_MATRIX); if (*type == mat_type_texture) { glUniform1i(loc, tex_counter); glActiveTexture(GL_TEXTURE0 + tex_counter); glBindTexture(GL_TEXTURE_2D, texture_handle(property)); tex_counter++; } else if (*type == mat_type_int) { glUniform1i(loc, *((int*)property)); } else if (*type == mat_type_float) { glUniform1f(loc, *((float*)property)); } else if (*type == mat_type_vector2) { vector2 v = *((vector2*)property); glUniform2f(loc, v.x, v.y); } else if (*type == mat_type_vector3) { vector3 v = *((vector3*)property); glUniform3f(loc, v.x, v.y, v.z); } else if (*type == mat_type_vector4) { vector4 v = *((vector4*)property); glUniform4f(loc, v.w, v.x, v.y, v.z); } else { /* Do nothing */ } } }
void deferred_renderer_render_light(light* l) { matrix_4x4 viewm = camera_view_matrix(CAMERA); matrix_4x4 projm = camera_proj_matrix(CAMERA, graphics_viewport_ratio() ); vector4 light_pos = v4(l->position.x, l->position.y, l->position.z, 1); light_pos = m44_mul_v4(viewm, light_pos); light_pos = m44_mul_v4(projm, light_pos); light_pos = v4_div(light_pos, light_pos.w); glUseProgram(shader_program_handle(PROGRAM_UI)); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0, graphics_viewport_width(), graphics_viewport_height(), 0, -1, 1); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); float top = ((-light_pos.y + 1) / 2) * graphics_viewport_height() - 8; float bot = ((-light_pos.y + 1) / 2) * graphics_viewport_height() + 8; float left = ((light_pos.x + 1) / 2) * graphics_viewport_width() - 8; float right = ((light_pos.x + 1) / 2) * graphics_viewport_width() + 8; texture* lightbulb = asset_load_get("$CORANGE/ui/lightbulb.dds"); glActiveTexture(GL_TEXTURE0 + 0 ); glBindTexture(GL_TEXTURE_2D, texture_handle(lightbulb)); glEnable(GL_TEXTURE_2D); glUniform1i(glGetUniformLocation(shader_program_handle(PROGRAM_UI), "diffuse"), 0); glUniform1f(glGetUniformLocation(shader_program_handle(PROGRAM_UI), "alpha_test"), 0.5); glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3f(left, top, -light_pos.z); glTexCoord2f(0.0f, 1.0f); glVertex3f(left, bot, -light_pos.z); glTexCoord2f(1.0f, 1.0f); glVertex3f(right, bot, -light_pos.z); glTexCoord2f(1.0f, 0.0f); glVertex3f(right, top, -light_pos.z); glEnd(); glActiveTexture(GL_TEXTURE0 + 0 ); glDisable(GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glUseProgram(0); }
void shader_program_print_info(shader_program* p) { GLuint shaders[128]; int num_shaders = 0; glGetAttachedShaders(shader_program_handle(p), 128, &num_shaders, shaders); debug("Program %i has %i shaders", shader_program_handle(p), num_shaders); for(int i = 0; i < num_shaders; i++) { debug("| Shader %i: %i", i, shaders[i]); } }
void deferred_renderer_begin() { glBindFramebuffer(GL_FRAMEBUFFER, fbo); deferred_renderer_setup_camera(); GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 }; glDrawBuffers(3, buffers); glClearColor(0.2, 0.2, 0.2, 1.0f); glClearDepth(1.0f); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glUseProgram(shader_program_handle(PROGRAM_CLEAR)); GLint start = glGetUniformLocation(shader_program_handle(PROGRAM_CLEAR), "start"); GLint end = glGetUniformLocation(shader_program_handle(PROGRAM_CLEAR), "end"); glUniform4f(start, 0.5, 0.5, 0.5, 1.0); glUniform4f(end, 0.0, 0.0, 0.0, 1.0); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(-1.0, 1.0, -1.0, 1.0, -1, 1); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glBegin(GL_QUADS); glVertex3f(-1.0, -1.0, 0.0f); glVertex3f(1.0, -1.0, 0.0f); glVertex3f(1.0, 1.0, 0.0f); glVertex3f(-1.0, 1.0, 0.0f); glEnd(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glUseProgram(0); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); }
void shader_program_set_float(shader_program* p, char* name, float val) { GLint location = glGetUniformLocation(shader_program_handle(p), name); if ( location == -1) { warning("Shader has no uniform called '%s'", name); } else { glUniform1f(location, val); } }
void shader_program_set_vec4(shader_program* p, char* name, vec4 val) { GLint location = glGetUniformLocation(shader_program_handle(p), name); if ( location == -1) { warning("Shader has no uniform called '%s'", name); } else { glUniform4f(location, val.x, val.y, val.z, val.w); } }
void shader_program_set_mat3(shader_program* p, char* name, mat3 val) { GLint location = glGetUniformLocation(shader_program_handle(p), name); if ( location == -1) { warning("Shader has no uniform called '%s'", name); } else { glUniformMatrix3fv(location, 1, GL_TRUE, (float*)&val); } }
void shader_program_set_float_array(shader_program* p, char* name, float* vals, int count) { GLint location = glGetUniformLocation(shader_program_handle(p), name); if ( location == -1) { warning("Shader has no uniform called '%s'", name); } else { glUniform1fv(location, count, vals); } }
void shader_program_set_mat4_array(shader_program* p, char* name, mat4* vals, int count) { GLint location = glGetUniformLocation(shader_program_handle(p), name); if ( location == -1) { warning("Shader has no uniform called '%s'", name); } else { glUniformMatrix4fv(location, count, GL_TRUE, (float*)vals); } }
void shader_program_disable_attribute(shader_program* p, char* name) { GLint attr = glGetAttribLocation(shader_program_handle(p), name); if (attr == -1) { warning("Shader has no attribute called '%s'", name); } else { glDisableVertexAttribArray(attr); } }
void shader_program_link(shader_program* program) { GLint count = -1; glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &count); glProgramParameteri(shader_program_handle(program), GL_GEOMETRY_VERTICES_OUT, count); glLinkProgram(shader_program_handle(program)); shader_program_print_log(program); GLint is_linked = false; glGetProgramiv(shader_program_handle(program), GL_LINK_STATUS, &is_linked); if (!is_linked) { error("Error linking shader program!"); } }
GLint shader_program_get_attribute(shader_program* p, char* name) { GLint attr = glGetAttribLocation(shader_program_handle(p), name); if (attr == -1) { error("Shader has no attribute called '%s'", name); return -1; } else { return attr; } }
void shader_program_enable_attribute(shader_program* p, char* name, int count, int stride, void* ptr) { GLint attr = glGetAttribLocation(shader_program_handle(p), name); if (attr == -1) { warning("Shader has no attribute called '%s'", name); } else { glEnableVertexAttribArray(attr); glVertexAttribPointer(attr, count, GL_FLOAT, GL_FALSE, sizeof(float) * stride, ptr); } }
void deferred_renderer_render_static(static_object* so) { matrix_4x4 r_world_matrix = m44_world( so->position, so->scale, so->rotation ); m44_to_array(r_world_matrix, WORLD_MATRIX); renderable* r = so->renderable; for(int i=0; i < r->num_surfaces; i++) { renderable_surface* s = r->surfaces[i]; if(s->is_rigged) { error("Renderable for static object is rigged!"); } GLuint program_handle = shader_program_handle(PROGRAM_STATIC); glUseProgram(program_handle); deferred_renderer_use_material(s->base, PROGRAM_STATIC); GLsizei stride = sizeof(float) * 18; glBindBuffer(GL_ARRAY_BUFFER, s->vertex_vbo); glVertexPointer(3, GL_FLOAT, stride, (void*)0); glEnableClientState(GL_VERTEX_ARRAY); glVertexAttribPointer(NORMAL, 3, GL_FLOAT, GL_FALSE, stride, (void*)(sizeof(float) * 3)); glEnableVertexAttribArray(NORMAL); glVertexAttribPointer(TANGENT, 3, GL_FLOAT, GL_FALSE, stride, (void*)(sizeof(float) * 6)); glEnableVertexAttribArray(TANGENT); glVertexAttribPointer(BINORMAL, 3, GL_FLOAT, GL_FALSE, stride, (void*)(sizeof(float) * 9)); glEnableVertexAttribArray(BINORMAL); glTexCoordPointer(2, GL_FLOAT, stride, (void*)(sizeof(float) * 12)); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->triangle_vbo); glDrawElements(GL_TRIANGLES, s->num_triangles * 3, GL_UNSIGNED_INT, (void*)0); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableVertexAttribArray(NORMAL); glDisableVertexAttribArray(TANGENT); glDisableVertexAttribArray(BINORMAL); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); glUseProgram(0); } }
void shader_program_attach_shader(shader_program* program, shader* shader) { if (shader_program_has_shader(program, shader)) { error("Shader already attached!"); } glAttachShader(shader_program_handle(program), shader_handle(shader)); shader_program_print_log(program); SDL_GL_CheckError(); }
void shader_program_set_texture_id(shader_program* p, char* name, int index, GLint t) { GLint location = glGetUniformLocation(shader_program_handle(p), name); if ( location == -1) { warning("Shader has no uniform called '%s'", name); } else { glActiveTexture(GL_TEXTURE0 + index); glBindTexture(GL_TEXTURE_2D, t); glUniform1i(location, index); } }
bool shader_program_has_shader(shader_program* p, shader* s) { GLuint shaders[128]; int num_shaders = 0; glGetAttachedShaders(shader_program_handle(p), 128, &num_shaders, shaders); for(int i = 0; i < num_shaders; i++) { if (shaders[i] == shader_handle(s)) return true; } return false; }
void shader_program_set_texture(shader_program* p, char* name, int index, asset_hndl t) { GLint location = glGetUniformLocation(shader_program_handle(p), name); if ( location == -1) { warning("Shader has no uniform called '%s'", name); } else { glActiveTexture(GL_TEXTURE0 + index); glBindTexture(texture_type(asset_hndl_ptr(&t)), texture_handle(asset_hndl_ptr(&t))); glUniform1i(location, index); } }
void shader_program_print_log(shader_program* program) { char log[2048]; int i; glGetProgramInfoLog(shader_program_handle(program), 2048, &i, log); log[i] = '\0'; if (strcmp(log, "") != 0) { debug("%s", log); } }
static void noise_render() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(-1.0, 1.0, -1.0, 1.0, -1, 1); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); material* noise_mat = asset_get(P("./noise.mat")); GLuint handle = shader_program_handle(material_get_entry(noise_mat, 0)->program); GLuint random_tex = texture_handle(asset_get(P("$CORANGE/textures/random.dds"))); glUseProgram(handle); glActiveTexture(GL_TEXTURE0 + 0 ); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, random_tex); glUniform1i(glGetUniformLocation(handle, "noise_texture"), 0); glUniform1f(glGetUniformLocation(handle, "time"), shader_time); glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0, -1.0, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0, -1.0, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0, 1.0, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0, 1.0, 0.0f); glEnd(); glActiveTexture(GL_TEXTURE0 + 0 ); glDisable(GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glUseProgram(0); }
void shader_program_disable_attribute_matrix(shader_program* p, char* name) { GLint attr = glGetAttribLocation(shader_program_handle(p), name); if (attr == -1) { warning("Shader has no attribute called '%s'", name); } else { glVertexAttribDivisor(attr+0, 0); glVertexAttribDivisor(attr+1, 0); glVertexAttribDivisor(attr+2, 0); glVertexAttribDivisor(attr+3, 0); glDisableVertexAttribArray(attr+0); glDisableVertexAttribArray(attr+1); glDisableVertexAttribArray(attr+2); glDisableVertexAttribArray(attr+3); } }
void shader_program_enable_attribute_instance_matrix(shader_program* p, char* name, void* ptr) { GLint attr = glGetAttribLocation(shader_program_handle(p), name); if (attr == -1) { warning("Shader has no attribute called '%s'", name); } else { glEnableVertexAttribArray(attr+0); glEnableVertexAttribArray(attr+1); glEnableVertexAttribArray(attr+2); glEnableVertexAttribArray(attr+3); glVertexAttribPointer(attr+0, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 4 * 4, ptr); glVertexAttribPointer(attr+1, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 4 * 4, ptr + sizeof(float) * 4); glVertexAttribPointer(attr+2, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 4 * 4, ptr + sizeof(float) * 8); glVertexAttribPointer(attr+3, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 4 * 4, ptr + sizeof(float) * 12); glVertexAttribDivisor(attr+0, 1); glVertexAttribDivisor(attr+1, 1); glVertexAttribDivisor(attr+2, 1); glVertexAttribDivisor(attr+3, 1); } }
void deferred_renderer_end() { glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); /* Render out ssao */ glBindFramebuffer(GL_FRAMEBUFFER, ssao_fbo); glViewport(0, 0, graphics_viewport_width() / 2, graphics_viewport_height() / 2); GLuint ssao_handle = shader_program_handle(PROGRAM_SSAO); glUseProgram(ssao_handle); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(-1.0, 1.0, -1.0, 1.0, -1, 1); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glActiveTexture(GL_TEXTURE0 + 0 ); glBindTexture(GL_TEXTURE_2D, depth_texture); glEnable(GL_TEXTURE_2D); glUniform1i(glGetUniformLocation(ssao_handle, "depth_texture"), 0); glActiveTexture(GL_TEXTURE0 + 1 ); glBindTexture(GL_TEXTURE_2D, texture_handle(RANDOM)); glEnable(GL_TEXTURE_2D); glUniform1i(glGetUniformLocation(ssao_handle, "random_texture"), 1); float seed = CAMERA->position.x + CAMERA->position.y + CAMERA->position.z; glUniform1f(glGetUniformLocation(ssao_handle, "seed"), seed); glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0, -1.0, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0, -1.0, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0, 1.0, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0, 1.0, 0.0f); glEnd(); glActiveTexture(GL_TEXTURE0 + 1 ); glDisable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0 + 0 ); glDisable(GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); /* End */ /* Render full screen quad to hdr fbo */ glBindFramebuffer(GL_FRAMEBUFFER, hdr_fbo); glViewport(0, 0, graphics_viewport_width(), graphics_viewport_height()); GLuint screen_handle = shader_program_handle(PROGRAM_COMPOSE); glUseProgram(screen_handle); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(-1.0, 1.0, -1.0, 1.0, -1, 1); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glActiveTexture(GL_TEXTURE0 + 0 ); glBindTexture(GL_TEXTURE_2D, diffuse_texture); glEnable(GL_TEXTURE_2D); glUniform1i(glGetUniformLocation(screen_handle, "diffuse_texture"), 0); glActiveTexture(GL_TEXTURE0 + 1 ); glBindTexture(GL_TEXTURE_2D, positions_texture); glEnable(GL_TEXTURE_2D); glUniform1i(glGetUniformLocation(screen_handle, "positions_texture"), 1); glActiveTexture(GL_TEXTURE0 + 2 ); glBindTexture(GL_TEXTURE_2D, normals_texture); glEnable(GL_TEXTURE_2D); glUniform1i(glGetUniformLocation(screen_handle, "normals_texture"), 2); glActiveTexture(GL_TEXTURE0 + 3 ); glBindTexture(GL_TEXTURE_2D, depth_texture); glEnable(GL_TEXTURE_2D); glUniform1i(glGetUniformLocation(screen_handle, "depth_texture"), 3); glActiveTexture(GL_TEXTURE0 + 4 ); glBindTexture(GL_TEXTURE_2D, texture_handle(SHADOW_TEX)); glEnable(GL_TEXTURE_2D); glUniform1i(glGetUniformLocation(screen_handle, "shadows_texture"), 4); glActiveTexture(GL_TEXTURE0 + 5 ); glBindTexture(GL_TEXTURE_2D, ssao_texture); glEnable(GL_TEXTURE_2D); glGenerateMipmap(GL_TEXTURE_2D); glUniform1i(glGetUniformLocation(screen_handle, "ssao_texture"), 5); glActiveTexture(GL_TEXTURE0 + 6 ); glBindTexture(GL_TEXTURE_2D, texture_handle(ENVIRONMENT)); glEnable(GL_TEXTURE_2D); glUniform1i(glGetUniformLocation(screen_handle, "env_texture"), 6); GLint cam_position = glGetUniformLocation(screen_handle, "camera_position"); glUniform3f(cam_position, CAMERA->position.x, CAMERA->position.y, CAMERA->position.z); GLint lproj_matrix_u = glGetUniformLocation(screen_handle, "light_proj"); glUniformMatrix4fv(lproj_matrix_u, 1, 0, LIGHT_PROJ_MATRIX); GLint lview_matrix_u = glGetUniformLocation(screen_handle, "light_view"); glUniformMatrix4fv(lview_matrix_u, 1, 0, LIGHT_VIEW_MATRIX); for(int i = 0; i < num_lights; i++) { light_power[i] = lights[i]->power; light_falloff[i] = lights[i]->falloff; light_position[i] = lights[i]->position; light_target[i] = lights[i]->target; light_diffuse[i] = lights[i]->diffuse_color; light_ambient[i] = lights[i]->ambient_color; light_specular[i] = lights[i]->specular_color; } glUniform1i(glGetUniformLocation(screen_handle, "num_lights"), num_lights); GLint light_power_u = glGetUniformLocation(screen_handle, "light_power"); GLint light_falloff_u = glGetUniformLocation(screen_handle, "light_falloff"); GLint light_position_u = glGetUniformLocation(screen_handle, "light_position"); GLint light_target_u = glGetUniformLocation(screen_handle, "light_target"); GLint light_diffuse_u = glGetUniformLocation(screen_handle, "light_diffuse"); GLint light_ambient_u = glGetUniformLocation(screen_handle, "light_ambient"); GLint light_specular_u = glGetUniformLocation(screen_handle, "light_specular"); glUniform1fv(light_power_u, num_lights, (const GLfloat*)light_power); glUniform1fv(light_falloff_u, num_lights, (const GLfloat*)light_falloff); glUniform3fv(light_position_u, num_lights, (const GLfloat*)light_position); glUniform3fv(light_target_u, num_lights, (const GLfloat*)light_target); glUniform3fv(light_diffuse_u, num_lights, (const GLfloat*)light_diffuse); glUniform3fv(light_ambient_u, num_lights, (const GLfloat*)light_ambient); glUniform3fv(light_specular_u, num_lights, (const GLfloat*)light_specular); glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0, -1.0, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0, -1.0, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0, 1.0, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0, 1.0, 0.0f); glEnd(); glActiveTexture(GL_TEXTURE0 + 6 ); glDisable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0 + 5 ); glDisable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0 + 4 ); glDisable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0 + 3 ); glDisable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0 + 2 ); glDisable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0 + 1 ); glDisable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0 + 0 ); glDisable(GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glUseProgram(0); /* Render HDR to LDR buffer */ glBindFramebuffer(GL_FRAMEBUFFER, ldr_fbo); GLuint screen_tonemap_handle = shader_program_handle(PROGRAM_TONEMAP); glUseProgram(screen_tonemap_handle); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(-1.0, 1.0, -1.0, 1.0, -1, 1); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glActiveTexture(GL_TEXTURE0 + 0 ); glBindTexture(GL_TEXTURE_2D, hdr_texture); glEnable(GL_TEXTURE_2D); glUniform1i(glGetUniformLocation(screen_tonemap_handle, "hdr_texture"), 0); glUniform1f(glGetUniformLocation(screen_tonemap_handle, "exposure"), EXPOSURE); glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0, -1.0, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0, -1.0, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0, 1.0, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0, 1.0, 0.0f); glEnd(); glActiveTexture(GL_TEXTURE0 + 0 ); glDisable(GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glUseProgram(0); /* Generate Mipmaps, adjust exposure */ unsigned char color[4] = {0,0,0,0}; int level = -1; int width = 0; int height = 0; glActiveTexture(GL_TEXTURE0 + 0 ); glBindTexture(GL_TEXTURE_2D, ldr_texture); glEnable(GL_TEXTURE_2D); glGenerateMipmap(GL_TEXTURE_2D); do { level++; glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width); glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &height); if (level > 50) { error("Unable to find lowest mip level. Perhaps mipmaps were not generated"); } } while ((width > 1) || (height > 1)); glGetTexImage(GL_TEXTURE_2D, level, GL_RGBA, GL_UNSIGNED_BYTE, color); glActiveTexture(GL_TEXTURE0 + 0 ); glDisable(GL_TEXTURE_2D); float average = (float)(color[0] + color[1] + color[2]) / (3.0 * 255.0); EXPOSURE += (EXPOSURE_TARGET - average) * EXPOSURE_SPEED; /* Render final frame */ glBindFramebuffer(GL_FRAMEBUFFER, 0); GLuint screen_post_handle = shader_program_handle(PROGRAM_POST); glUseProgram(screen_post_handle); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(-1.0, 1.0, -1.0, 1.0, -1, 1); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glActiveTexture(GL_TEXTURE0 + 0 ); glBindTexture(GL_TEXTURE_2D, ldr_texture); glEnable(GL_TEXTURE_2D); glUniform1i(glGetUniformLocation(screen_post_handle, "diffuse_texture"), 0); glActiveTexture(GL_TEXTURE0 + 1 ); glBindTexture(GL_TEXTURE_2D, texture_handle(VIGNETTING)); glEnable(GL_TEXTURE_2D); glUniform1i(glGetUniformLocation(screen_post_handle, "vignetting_texture"), 1); glActiveTexture(GL_TEXTURE0 + 2 ); glBindTexture(GL_TEXTURE_3D, texture_handle(COLOR_CORRECTION)); glEnable(GL_TEXTURE_3D); glUniform1i(glGetUniformLocation(screen_post_handle, "lut"), 2); glUniform1i(glGetUniformLocation(screen_post_handle, "width"), graphics_viewport_width()); glUniform1i(glGetUniformLocation(screen_post_handle, "height"), graphics_viewport_height()); glUniform1i(glGetUniformLocation(screen_post_handle, "aa_type"), 1); glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0, -1.0, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0, -1.0, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0, 1.0, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0, 1.0, 0.0f); glEnd(); glActiveTexture(GL_TEXTURE0 + 2 ); glDisable(GL_TEXTURE_3D); glActiveTexture(GL_TEXTURE0 + 1 ); glDisable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0 + 0 ); glDisable(GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glUseProgram(0); }
void deferred_renderer_render_animated(animated_object* ao) { if (ao->skeleton->num_bones > MAX_BONES) { error("animated object skeleton has too many bones (over %i)", MAX_BONES); } matrix_4x4 r_world_matrix = m44_world( ao->position, ao->scale, ao->rotation ); m44_to_array(r_world_matrix, WORLD_MATRIX); skeleton_gen_transforms(ao->pose); for(int i = 0; i < ao->skeleton->num_bones; i++) { matrix_4x4 base, ani; base = ao->skeleton->inv_transforms[i]; ani = ao->pose->transforms[i]; bone_matrices[i] = m44_mul_m44(ani, base); m44_to_array(bone_matrices[i], bone_matrix_data + (i * 4 * 4)); } renderable* r = ao->renderable; for(int i = 0; i < r->num_surfaces; i++) { renderable_surface* s = r->surfaces[i]; if(s->is_rigged) { GLuint program_animated_handle = shader_program_handle(PROGRAM_ANIMATED); glUseProgram(program_animated_handle); deferred_renderer_use_material(s->base, PROGRAM_ANIMATED); GLint bone_world_matrices_u = glGetUniformLocation(program_animated_handle, "bone_world_matrices"); glUniformMatrix4fv(bone_world_matrices_u, ao->skeleton->num_bones, GL_FALSE, bone_matrix_data); GLint bone_count_u = glGetUniformLocation(program_animated_handle, "bone_count"); glUniform1i(bone_count_u, ao->skeleton->num_bones); GLsizei stride = sizeof(float) * 24; glBindBuffer(GL_ARRAY_BUFFER, s->vertex_vbo); glVertexPointer(3, GL_FLOAT, stride, (void*)0); glEnableClientState(GL_VERTEX_ARRAY); glVertexAttribPointer(NORMAL, 3, GL_FLOAT, GL_FALSE, stride, (void*)(sizeof(float) * 3)); glEnableVertexAttribArray(NORMAL); glVertexAttribPointer(TANGENT, 3, GL_FLOAT, GL_FALSE, stride, (void*)(sizeof(float) * 6)); glEnableVertexAttribArray(TANGENT); glVertexAttribPointer(BINORMAL, 3, GL_FLOAT, GL_FALSE, stride, (void*)(sizeof(float) * 9)); glEnableVertexAttribArray(BINORMAL); glTexCoordPointer(2, GL_FLOAT, stride, (void*)(sizeof(float) * 12)); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexAttribPointer(BONE_INDICIES, 3, GL_FLOAT, GL_FALSE, stride, (void*)(sizeof(float) * 18)); glEnableVertexAttribArray(BONE_INDICIES); glVertexAttribPointer(BONE_WEIGHTS, 3, GL_FLOAT, GL_FALSE, stride, (void*)(sizeof(float) * 21)); glEnableVertexAttribArray(BONE_WEIGHTS); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->triangle_vbo); glDrawElements(GL_TRIANGLES, s->num_triangles * 3, GL_UNSIGNED_INT, (void*)0); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableVertexAttribArray(NORMAL); glDisableVertexAttribArray(TANGENT); glDisableVertexAttribArray(BINORMAL); glDisableVertexAttribArray(BONE_INDICIES); glDisableVertexAttribArray(BONE_WEIGHTS); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); glUseProgram(0); } else { error("Animated object is not rigged!"); } } }
void deferred_renderer_init() { num_lights = 0; EXPOSURE = 0.0; EXPOSURE_SPEED = 1.0; EXPOSURE_TARGET = 0.4; COLOR_CORRECTION = asset_load_get("$CORANGE/resources/identity.lut"); RANDOM = asset_load_get("$CORANGE/resources/random.dds"); ENVIRONMENT = asset_load_get("$CORANGE/resources/envmap.dds"); VIGNETTING = asset_load_get("$CORANGE/resources/vignetting.dds"); load_folder("$CORANGE/shaders/deferred/"); PROGRAM_STATIC = asset_get("$CORANGE/shaders/deferred/static.prog"); PROGRAM_ANIMATED = asset_get("$CORANGE/shaders/deferred/animated.prog"); PROGRAM_CLEAR = asset_get("$CORANGE/shaders/deferred/clear.prog"); PROGRAM_SSAO = asset_get("$CORANGE/shaders/deferred/ssao.prog"); PROGRAM_TONEMAP = asset_get("$CORANGE/shaders/deferred/tonemap.prog"); PROGRAM_COMPOSE = asset_get("$CORANGE/shaders/deferred/compose.prog"); PROGRAM_POST = asset_get("$CORANGE/shaders/deferred/post.prog"); PROGRAM_UI = asset_get("$CORANGE/shaders/deferred/ui.prog"); NORMAL = glGetAttribLocation(shader_program_handle(PROGRAM_STATIC), "normal"); TANGENT = glGetAttribLocation(shader_program_handle(PROGRAM_STATIC), "tangent"); BINORMAL = glGetAttribLocation(shader_program_handle(PROGRAM_STATIC), "binormal"); NORMAL_ANIMATED = glGetAttribLocation(shader_program_handle(PROGRAM_ANIMATED), "normal"); TANGENT_ANIMATED = glGetAttribLocation(shader_program_handle(PROGRAM_ANIMATED), "tangent"); BINORMAL_ANIMATED = glGetAttribLocation(shader_program_handle(PROGRAM_ANIMATED), "binormal"); BONE_INDICIES = glGetAttribLocation(shader_program_handle(PROGRAM_ANIMATED), "bone_indicies"); BONE_WEIGHTS = glGetAttribLocation(shader_program_handle(PROGRAM_ANIMATED), "bone_weights"); int viewport_width = graphics_viewport_width(); int viewport_height = graphics_viewport_height(); glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); glGenRenderbuffers(1, &diffuse_buffer); glBindRenderbuffer(GL_RENDERBUFFER, diffuse_buffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, viewport_width, viewport_height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, diffuse_buffer); glGenRenderbuffers(1, &positions_buffer); glBindRenderbuffer(GL_RENDERBUFFER, positions_buffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, viewport_width, viewport_height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, positions_buffer); glGenRenderbuffers(1, &normals_buffer); glBindRenderbuffer(GL_RENDERBUFFER, normals_buffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA16F, viewport_width, viewport_height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_RENDERBUFFER, normals_buffer); glGenRenderbuffers(1, &depth_buffer); glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, viewport_width, viewport_height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_buffer); glGenTextures(1, &diffuse_texture); glBindTexture(GL_TEXTURE_2D, diffuse_texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, viewport_width, viewport_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, diffuse_texture, 0); glGenTextures(1, &positions_texture); glBindTexture(GL_TEXTURE_2D, positions_texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, viewport_width, viewport_height, 0, GL_RGBA, GL_FLOAT, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, positions_texture, 0); glGenTextures(1, &normals_texture); glBindTexture(GL_TEXTURE_2D, normals_texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, viewport_width, viewport_height, 0, GL_RGBA, GL_FLOAT, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, normals_texture, 0); glGenTextures(1, &depth_texture); glBindTexture(GL_TEXTURE_2D, depth_texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, viewport_width, viewport_height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_texture, 0); glGenFramebuffers(1, &ssao_fbo); glBindFramebuffer(GL_FRAMEBUFFER, ssao_fbo); glGenRenderbuffers(1, &ssao_buffer); glBindRenderbuffer(GL_RENDERBUFFER, ssao_buffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, viewport_width / 2, viewport_height / 2); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, ssao_buffer); glGenTextures(1, &ssao_texture); glBindTexture(GL_TEXTURE_2D, ssao_texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, viewport_width / 2, viewport_height / 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ssao_texture, 0); glGenFramebuffers(1, &hdr_fbo); glBindFramebuffer(GL_FRAMEBUFFER, hdr_fbo); glGenRenderbuffers(1, &hdr_buffer); glBindRenderbuffer(GL_RENDERBUFFER, hdr_buffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA16F, viewport_width, viewport_height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, ldr_buffer); glGenTextures(1, &hdr_texture); glBindTexture(GL_TEXTURE_2D, hdr_texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, viewport_width, viewport_height, 0, GL_RGBA, GL_FLOAT, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, hdr_texture, 0); glGenFramebuffers(1, &ldr_fbo); glBindFramebuffer(GL_FRAMEBUFFER, ldr_fbo); glGenRenderbuffers(1, &ldr_buffer); glBindRenderbuffer(GL_RENDERBUFFER, ldr_buffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, viewport_width, viewport_height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, ldr_buffer); glGenTextures(1, &ldr_texture); glBindTexture(GL_TEXTURE_2D, ldr_texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, viewport_width, viewport_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ldr_texture, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0); }
void shader_program_enable(shader_program* p) { glUseProgram(shader_program_handle(p)); }
void shader_program_delete(shader_program* program) { glDeleteProgram(shader_program_handle(program)); free(program); }