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);

}
Exemple #3
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);
  
}
Exemple #5
0
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);
    }
}
Exemple #6
0
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);
    }
}
Exemple #7
0
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);
    }
}
Exemple #8
0
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);
    }
}
Exemple #9
0
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);
    }
}
Exemple #10
0
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);
    }
}
Exemple #11
0
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!");
  }
    
}
Exemple #12
0
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;
    }
}
Exemple #13
0
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);

  }
  
}
Exemple #15
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();
}
Exemple #16
0
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);
    }

}
Exemple #17
0
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;
}
Exemple #18
0
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);
    }

}
Exemple #19
0
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);
    }

}
Exemple #20
0
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);

}
Exemple #21
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);
    }
}
Exemple #22
0
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);
  
}
Exemple #26
0
void shader_program_enable(shader_program* p) {
    glUseProgram(shader_program_handle(p));
}
Exemple #27
0
void shader_program_delete(shader_program* program) {
    glDeleteProgram(shader_program_handle(program));
    free(program);
}