Implemented resolution independent rendering and RTT

dev
Shariq Shah 10 years ago
parent c1ea63f571
commit ed1edf44ce
  1. 100
      src/camera.c
  2. 8
      src/camera.h
  3. 7
      src/game.c
  4. 35
      src/renderer.c

@ -1,13 +1,21 @@
#include "GLFW/glfw3.h"
#include "camera.h"
#include "entity.h"
#include "transform.h"
#include "array.h"
#include "framebuffer.h"
#include "texture.h"
#include "utils.h"
#include "log.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
static struct Camera* camera_list;
static int* empty_indices;
static int primary_camera_index;
struct Camera* camera_get(int index)
{
@ -22,6 +30,7 @@ void camera_init(void)
{
camera_list = array_new(struct Camera);
empty_indices = array_new(int);
primary_camera_index = -1;
}
void camera_remove(int index)
@ -54,7 +63,9 @@ int camera_create(int node, int width, int height)
new_camera = array_grow(camera_list, struct Camera);
index = array_len(camera_list) - 1;
}
new_camera->fbo = -1;
new_camera->render_tex = -1;
new_camera->depth_tex = -1;
new_camera->node = node;
new_camera->farz = 1000.f;
new_camera->nearz = 0.1f;
@ -106,3 +117,90 @@ void camera_update_proj(struct Camera* camera)
}
camera_update_view_proj(camera);
}
void camera_attach_fbo(struct Camera* camera, int width, int height, int has_depth, int has_color)
{
assert(width > 0 && height > 0 && camera);
if(camera->fbo != -1)
{
log_error("camera:attach_fbo", "Camera already has fbo attached!");
return;
}
camera->fbo = framebuffer_create(width, height, has_depth, has_color);
if(camera->fbo > -1)
{
char tex_name[128];
snprintf(tex_name, 128, "cam_render_tex_%d", camera->node);
camera->render_tex = texture_create(tex_name,
TU_DIFFUSE,
width, height,
GL_RGBA,
GL_RGBA8,
GL_UNSIGNED_BYTE,
NULL);
texture_set_param(camera->render_tex, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
texture_set_param(camera->render_tex, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
texture_set_param(camera->render_tex, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
texture_set_param(camera->render_tex, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
memset(tex_name, '\0', 128);
snprintf(tex_name, 128, "cam_depth_tex_%d", camera->node);
camera->depth_tex = texture_create(tex_name,
TU_SHADOWMAP1,
width, height,
GL_DEPTH_COMPONENT,
GL_DEPTH_COMPONENT,
GL_UNSIGNED_BYTE,
NULL);
texture_set_param(camera->depth_tex, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
texture_set_param(camera->depth_tex, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
texture_set_param(camera->depth_tex, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
texture_set_param(camera->depth_tex, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
texture_set_param(camera->depth_tex, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
texture_set_param(camera->depth_tex, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
camera->fbo = framebuffer_create(width, height, 0, 1);
framebuffer_set_texture(camera->fbo, camera->render_tex, GL_COLOR_ATTACHMENT0);
framebuffer_set_texture(camera->fbo, camera->depth_tex, GL_DEPTH_ATTACHMENT);
}
else
{
log_error("camera:attach_fbo", "Framebuffer not attached to camera!");
}
}
struct Camera* camera_get_all(void)
{
return camera_list;
}
void camera_set_primary_viewer(struct Camera* camera)
{
assert(camera);
if(camera->node == -1)
{
log_error("camera:set_primary_viewer", "Invalid camera!");
}
else
{
/* locate the index of this camera */
for(int i = 0; i < array_len(camera_list); i++)
{
if(camera_list[i].node == camera->node)
{
primary_camera_index = i;
log_message("Camera at index %d set as primary viewer", primary_camera_index);
break;
}
}
}
}
struct Camera* camera_get_primary(void)
{
struct Camera* primary_camera = NULL;
if(primary_camera_index != -1)
primary_camera = &camera_list[primary_camera_index];
return primary_camera;
}

@ -14,9 +14,14 @@ struct Camera
float nearz;
float farz;
int ortho;
int fbo;
int render_tex;
int depth_tex;
};
struct Camera* camera_get(int index);
struct Camera* camera_get_all(void);
struct Camera* camera_get_primary(void);
void camera_init(void);
void camera_cleanup(void);
void camera_remove(int index);
@ -24,6 +29,7 @@ int camera_create(int node, int width, int height);
void camera_update_view_proj(struct Camera* camera);
void camera_update_view(struct Camera* camera);
void camera_update_proj(struct Camera* camera);
void camera_attach_fbo(struct Camera* camera, int width, int height, int has_depth, int has_color);
void camera_set_primary_viewer(struct Camera* camera);
#endif

@ -84,7 +84,12 @@ void scene_setup(void)
vec3 viewer_pos = {0, 0, 10};
struct Transform* viewer_tran = entity_component_get(player, C_TRANSFORM);
transform_set_position(viewer_tran, &viewer_pos);
entity_component_add(player, C_CAMERA, 800, 600);
int render_width, render_height;
render_width = 800;
render_height = 600;
struct Camera* camera = entity_component_add(player, C_CAMERA, render_width, render_height);
camera_attach_fbo(camera, render_width, render_height, 1, 1);
camera_set_primary_viewer(camera);
struct Entity* new_ent = scene_add_new("Model_Entity", NULL);
struct Transform* tran = entity_component_get(new_ent, C_TRANSFORM);

@ -95,24 +95,37 @@ void renderer_init(GLFWwindow* window)
void renderer_draw(void)
{
framebuffer_bind(def_fbo);
struct Camera* camera_list = camera_get_all();
for(int i = 0; i < array_len(camera_list); i++)
{
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glDepthFunc(GL_LEQUAL);
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
struct Camera* camera = camera_get(0);
model_render_all(camera);
glDisable(GL_BLEND);
struct Camera* camera = &camera_list[i];
if(camera->node < 0)
continue;
int fbo = camera->fbo == -1 ? def_fbo : camera->fbo;
framebuffer_bind(fbo);
{
glViewport(0, 0, framebuffer_get_width(fbo), framebuffer_get_height(fbo));
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glDepthFunc(GL_LEQUAL);
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
model_render_all(camera);
glDisable(GL_BLEND);
}
framebuffer_unbind();
}
framebuffer_unbind();
int width, height;
window_get_size(&width, &height);
glViewport(0, 0, width, height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
shader_bind(fbo_shader);
texture_bind(def_render_tex);
struct Camera* primary_camera = camera_get_primary();
texture_bind(primary_camera->render_tex);
geom_render(quad_geo);
texture_unbind(def_render_tex);
shader_unbind();

Loading…
Cancel
Save