void texture3d_write_to_file(texture* t, char* filename) { int t_width; int t_height; int t_depth; glBindTexture(t->type, texture_handle(t)); glGetTexLevelParameteriv(t->type, 0, GL_TEXTURE_WIDTH, &t_width); glGetTexLevelParameteriv(t->type, 0, GL_TEXTURE_HEIGHT, &t_height); glGetTexLevelParameteriv(t->type, 0, GL_TEXTURE_DEPTH, &t_depth); int width = t_width; int height = t_height * t_depth; unsigned char* data = malloc(width * height * 4); glGetTexImage(t->type, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); int xa= width % 256; int xb= (width-xa)/256; int ya= height % 256; int yb= (height-ya)/256; unsigned char header[18]={0,0,2,0,0,0,0,0,0,0,0,0,(char)xa,(char)xb,(char)ya,(char)yb,32,0}; SDL_RWops* file = SDL_RWFromFile(filename, "wb"); SDL_RWwrite(file, header, sizeof(header), 1); SDL_RWwrite(file, data, width * height * 4, 1 ); SDL_RWclose(file); free(data); }
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 texture_set_filtering_linear(texture* t) { glBindTexture(t->type, texture_handle(t)); glTexParameteri(t->type, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(t->type, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(t->type, GL_TEXTURE_MAX_ANISOTROPY_EXT, 0); }
void level_render_tiles(level* l, vec2 camera_position) { glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(camera_position.x - graphics_viewport_width() / 2, camera_position.x + graphics_viewport_width() / 2, -camera_position.y + graphics_viewport_height() / 2, -camera_position.y - graphics_viewport_height() / 2 , -1, 1); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* Start from 1, 0 is no tiles! */ for(int i = 1; i < l->num_tile_sets; i++) { texture* tile_tex = tile_get_texture(i); glBindTexture(GL_TEXTURE_2D, texture_handle(tile_tex)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, l->tile_sets[i].positions_buffer); glVertexPointer(3, GL_FLOAT, 0, (void*)0); glBindBuffer(GL_ARRAY_BUFFER, l->tile_sets[i].texcoords_buffer); glTexCoordPointer(2, GL_FLOAT, 0, (void*)0); glDrawArrays(GL_QUADS, 0, l->tile_sets[i].num_tiles * 4); glBindBuffer(GL_ARRAY_BUFFER, 0); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); } glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); }
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 texture_set_filtering_anisotropic(texture* t) { float max = 0; glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max); glBindTexture(t->type, texture_handle(t)); glTexParameteri(t->type, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(t->type, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(t->type, GL_TEXTURE_MAX_ANISOTROPY_EXT, max); }
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); } }
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); }
texture* bmp_load_file( char* filename ) { image* i = image_bmp_load_file(filename); texture* t = texture_new(); glBindTexture(GL_TEXTURE_2D, texture_handle(t)); glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0 ); texture_set_image(t, i); texture_set_filtering_anisotropic(t); image_delete(i); return t; }
void coin_render(coin* c, vec2 camera_position) { glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(camera_position.x - graphics_viewport_width() / 2, camera_position.x + graphics_viewport_width() / 2, -camera_position.y + graphics_viewport_height() / 2, -camera_position.y - graphics_viewport_height() / 2 , 0, 1); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_TEXTURE_2D); texture* coin_tex = asset_get(P("./tiles/coin.dds")); glBindTexture(GL_TEXTURE_2D, texture_handle(coin_tex)); glBegin(GL_QUADS); glTexCoord2f(0, 1); glVertex3f(c->position.x, c->position.y + 32, 0); glTexCoord2f(1, 1); glVertex3f(c->position.x + 32, c->position.y + 32, 0); glTexCoord2f(1, 0); glVertex3f(c->position.x + 32, c->position.y, 0); glTexCoord2f(0, 0); glVertex3f(c->position.x, c->position.y, 0); glEnd(); glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); }
void level_render_background(level* l) { glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0, graphics_viewport_width(), 0, graphics_viewport_height(), -1, 1); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glEnable(GL_TEXTURE_2D); texture* background = asset_get_load(P("./backgrounds/bluesky.dds")); glBindTexture(GL_TEXTURE_2D, texture_handle(background)); glBegin(GL_QUADS); glVertex3f(0, graphics_viewport_height(), 0.0); glTexCoord2f(1, 0); glVertex3f(graphics_viewport_width(), graphics_viewport_height(), 0.0); glTexCoord2f(1, 1); glVertex3f(graphics_viewport_width(), 0, 0.0); glTexCoord2f(0, 1); glVertex3f(0, 0, 0.0); glTexCoord2f(0, 0); glEnd(); glDisable(GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); }
texture* lut_load_file( char* filename ) { SDL_RWops* file = SDL_RWFromFile(filename, "r"); if(file == NULL) { error("Cannot load file %s", filename); } long size = SDL_RWseek(file,0,SEEK_END); unsigned char* contents = malloc(size+1); contents[size] = '\0'; SDL_RWseek(file, 0, SEEK_SET); SDL_RWread(file, contents, size, 1); SDL_RWclose(file); int head = sizeof("CORANGE-LUT")-1; int lut_size = (unsigned char)contents[head] | (unsigned char)contents[head + 1]; int offset = head + 3; texture* t = texture_new(); t->type = GL_TEXTURE_3D; glBindTexture(t->type, texture_handle(t)); glTexImage3D(t->type, 0, GL_RGB, lut_size, lut_size, lut_size, 0, GL_RGB, GL_UNSIGNED_BYTE, contents + offset); glTexParameteri(t->type, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(t->type, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(t->type, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); glTexParameteri(t->type, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); glTexParameteri(t->type, GL_TEXTURE_WRAP_R, GL_MIRRORED_REPEAT); free(contents); return t; }
image* texture_get_image(texture* t) { int width = 0; int height = 0; int format = 0; glBindTexture(GL_TEXTURE_2D, texture_handle(t)); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format); if ((width == 0) || (height == 0)) { error("Texture has zero size width/height: (%i, %i)", width, height); } unsigned char* data = malloc(width * height * 4); float* data_flt; unsigned int* data_int; switch (format) { case GL_RGBA: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); break; case GL_ALPHA16: data_flt = malloc(sizeof(float) * width * height); glGetTexImage(GL_TEXTURE_2D, 0, GL_ALPHA, GL_FLOAT, data_flt); for(int x = 0; x < width; x++) for(int y = 0; y < height; y++) { data[(y*4*width) + (x*4) + 0] = pow(data_flt[(y*width) + x], 256.0) * 255; data[(y*4*width) + (x*4) + 1] = pow(data_flt[(y*width) + x], 256.0) * 255; data[(y*4*width) + (x*4) + 2] = pow(data_flt[(y*width) + x], 256.0) * 255; data[(y*4*width) + (x*4) + 3] = pow(data_flt[(y*width) + x], 256.0) * 255; } free(data_flt); break; case GL_RGBA32F: case GL_RGBA16F: data_flt = malloc(4 * sizeof(float) * width * height); glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, data_flt); for(int x = 0; x < width; x++) for(int y = 0; y < height; y++) { data[(y*4*width) + (x*4) + 0] = clamp(data_flt[(y*4*width) + (x*4) + 0] * 127 + 127, 0, 255); data[(y*4*width) + (x*4) + 1] = clamp(data_flt[(y*4*width) + (x*4) + 1] * 127 + 127, 0, 255); data[(y*4*width) + (x*4) + 2] = clamp(data_flt[(y*4*width) + (x*4) + 2] * 127 + 127, 0, 255); data[(y*4*width) + (x*4) + 3] = clamp(data_flt[(y*4*width) + (x*4) + 3] * 127 + 127, 0, 255); } free(data_flt); break; case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT24: data_int = malloc(sizeof(unsigned int) * width * height); glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, data_int); for(int x = 0; x < width; x++) for(int y = 0; y < height; y++) { data[(y*4*width) + (x*4) + 0] = data_int[(y*width) + x]; data[(y*4*width) + (x*4) + 1] = data_int[(y*width) + x]; data[(y*4*width) + (x*4) + 2] = data_int[(y*width) + x]; data[(y*4*width) + (x*4) + 3] = data_int[(y*width) + x]; } free(data_int); break; default: error("Can't convert that particular texture format %i to an image.", format); } SDL_GL_CheckError(); image* i = image_new(width, height, data); free(data); return i; }
texture* dds_load_file( char* filename ) { DdsLoadInfo loadInfoDXT1 = { true, false, false, 4, 8, GL_COMPRESSED_RGBA_S3TC_DXT1 }; DdsLoadInfo loadInfoDXT3 = { true, false, false, 4, 16, GL_COMPRESSED_RGBA_S3TC_DXT3 }; DdsLoadInfo loadInfoDXT5 = { true, false, false, 4, 16, GL_COMPRESSED_RGBA_S3TC_DXT5 }; DdsLoadInfo loadInfoBGRA8 = { false, false, false, 1, 4, GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE }; DdsLoadInfo loadInfoBGR8 = { false, false, false, 1, 3, GL_RGB8, GL_BGR, GL_UNSIGNED_BYTE }; DdsLoadInfo loadInfoBGR5A1 = { false, true, false, 1, 2, GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV }; DdsLoadInfo loadInfoBGR565 = { false, true, false, 1, 2, GL_RGB5, GL_RGB, GL_UNSIGNED_SHORT_5_6_5 }; DdsLoadInfo loadInfoIndex8 = { false, false, true, 1, 1, GL_RGB8, GL_BGRA, GL_UNSIGNED_BYTE }; SDL_RWops* f = SDL_RWFromFile(filename, "rb"); if (f == NULL) { error("Cannot load file %s", filename); } DDS_header hdr; SDL_RWread(f, &hdr, 1, sizeof(DDS_header)); if( hdr.dwMagic != DDS_MAGIC || hdr.dwSize != 124 || !(hdr.dwFlags & DDSD_PIXELFORMAT) || !(hdr.dwFlags & DDSD_CAPS) ) { error("Cannot Load File %s: Does not appear to be a .dds file.\n", filename); } int x = hdr.dwWidth; int y = hdr.dwHeight; int mip_map_num = (hdr.dwFlags & DDSD_MIPMAPCOUNT) ? hdr.dwMipMapCount : 1; if (!is_power_of_two(x)) { error("Texture %s with is %i pixels which is not a power of two!", filename, x); } if (!is_power_of_two(y)) { error("Texture %s height is %i pixels which is not a power of two!", filename, y); } DdsLoadInfo* li = &loadInfoDXT1; if (PF_IS_DXT1(hdr.sPixelFormat )) { li = &loadInfoDXT1; } else if (PF_IS_DXT3(hdr.sPixelFormat )) { li = &loadInfoDXT3; } else if (PF_IS_DXT5(hdr.sPixelFormat )) { li = &loadInfoDXT5; } else if (PF_IS_BGRA8(hdr.sPixelFormat )) { li = &loadInfoBGRA8; } else if (PF_IS_BGR8(hdr.sPixelFormat )) { li = &loadInfoBGR8; } else if (PF_IS_BGR5A1(hdr.sPixelFormat)) { li = &loadInfoBGR5A1; } else if (PF_IS_BGR565(hdr.sPixelFormat)) { li = &loadInfoBGR565; } else if (PF_IS_INDEX8(hdr.sPixelFormat)) { li = &loadInfoIndex8; } else { error("Cannot Load File %s: Unknown DDS File format type.", filename); } texture* t = texture_new(); if (hdr.sCaps.dwCaps2 & DDSCAPS2_CUBEMAP) { t->type = GL_TEXTURE_CUBE_MAP; glBindTexture(GL_TEXTURE_CUBE_MAP, texture_handle(t)); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_FALSE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, mip_map_num-1); } else { t->type = GL_TEXTURE_2D; glBindTexture(GL_TEXTURE_2D, texture_handle(t)); glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mip_map_num-1); texture_set_filtering_anisotropic(t); } for (int i = 0; i < (t->type == GL_TEXTURE_CUBE_MAP ? 6 : 1); i++) { GLenum target = t->type; if (t->type == GL_TEXTURE_CUBE_MAP) { target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i; } int x = hdr.dwWidth; int y = hdr.dwHeight; int mip_map_num = (hdr.dwFlags & DDSD_MIPMAPCOUNT) ? hdr.dwMipMapCount : 1; if ( li->compressed ) { size_t size = max(li->div_size, x) / li->div_size * max(li->div_size, y) / li->div_size * li->block_bytes; char* data = malloc(size); for(int ix = 0; ix < mip_map_num; ix++) { SDL_RWread(f, data, 1, size); glCompressedTexImage2D(target, ix, li->internal_format, x, y, 0, size, data); x = (x+1)>>1; y = (y+1)>>1; size = max(li->div_size, x) / li->div_size * max(li->div_size, y) / li->div_size * li->block_bytes; } free(data); } else if ( li->palette ) {
void texture_set_image(texture* t, image* i) { glBindTexture(GL_TEXTURE_2D, texture_handle(t)); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, i->width, i->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, i->data ); }
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 texture_generate_mipmaps(texture* t) { glBindTexture(t->type, texture_handle(t)); glGenerateMipmap(t->type); }