Added render to texture support

dev
Shariq Shah 10 years ago
parent 3f4e84d6d3
commit 568d03f155
  1. 35
      src/array.c
  2. 3
      src/array.h
  3. 18
      src/framebuffer.c
  4. 4
      src/game.c
  5. 87
      src/geometry.c
  6. 6
      src/geometry.h
  7. 2
      src/model.c
  8. 107
      src/renderer.c
  9. 12
      src/texture.c
  10. 2
      src/texture.h
  11. 5
      src/window_system.c
  12. 1
      src/window_system.h

@ -17,7 +17,6 @@ struct Array
static struct Array* array_get_ptr(void* array_data);
static struct Array* array_reallocate(struct Array* array);
static void* array_top(struct Array* array);
static void* array_get(struct Array* array, unsigned int index);
static struct Array* array_get_ptr(void* array_data)
{
@ -26,7 +25,7 @@ static struct Array* array_get_ptr(void* array_data)
void* array_new_(size_t object_size, int capacity)
{
capacity = capacity == 0 ? ARRAY_MIN_CAPACITY : capacity;
if(capacity == 0) capacity = ARRAY_MIN_CAPACITY;
struct Array* new_array = malloc(sizeof(*new_array) + (object_size * capacity));
new_array->object_size = object_size;
new_array->length = 0;
@ -41,11 +40,6 @@ void array_free(void* array)
free(array_ptr);
}
void* array_get(struct Array* array, unsigned int index)
{
return array->data + (array->object_size * index);
}
void* array_top(struct Array* array)
{
return array->data + (array->object_size * (array->length - 1));
@ -81,6 +75,7 @@ int array_reset_(void** array, int length)
size_t object_size = array_ptr->object_size;
int new_capacity = length < ARRAY_MIN_CAPACITY ? ARRAY_MIN_CAPACITY : length;
int new_length = new_capacity;
array_free(*array);
array_ptr = calloc(1, sizeof(*array_ptr) + (new_capacity * object_size));
if(array_ptr)
{
@ -187,7 +182,8 @@ void array_inc_cap_by_(void** array, int cap)
if(cap > 0)
{
array_ptr->capacity += cap;
char* new_data = realloc(array_ptr, sizeof(*array_ptr) + (array_ptr->object_size * array_ptr->capacity));
char* new_data = realloc(array_ptr,
sizeof(*array_ptr) + (array_ptr->object_size * array_ptr->capacity));
if(new_data)
{
array_ptr = (struct Array*)new_data;
@ -195,8 +191,29 @@ void array_inc_cap_by_(void** array, int cap)
}
else
{
array_ptr->capacity = array_ptr->capacity -= cap;
array_ptr->capacity -= cap;
/* TODO: Error handling here! */
}
}
}
int array_copy_(void* array_src, void** array_dest)
{
int success = 0;
struct Array* src = array_get_ptr(array_src);
struct Array* dest = array_get_ptr(*array_dest);
/* determine if copy is possible */
if(src->object_size != dest->object_size)
return success;
if((src->length > dest->length) && (dest->capacity < src->length))
{
array_free(*array_dest);
*array_dest = array_new_(src->object_size, src->capacity);
dest = *array_dest;
}
memcpy(dest->data, src->data, src->object_size * src->length);
dest->length = src->length;
return success;
}

@ -11,6 +11,7 @@ int array_pop_(void** array); // Remove object with highest index
int array_remove_at_(void** array, int index);
void array_match_len_cap_(void** array);
void array_inc_cap_by_(void** array, int cap);
int array_copy_(void* arr_src, void** arr_dest);
/* Public Api */
#define array_new(type) (type*) array_new_(sizeof(type), 0); // Use this for array creation
@ -27,9 +28,11 @@ void array_inc_cap_by_(void** array, int cap);
#define array_reset(array, length) array_reset_((void**)&array, length);
#define array_match_len_cap(array) array_match_len_cap_((void**)&array);
#define array_inc_cap_by(array, cap) array_inc_cap_by_((void**)&array, cap);
#define array_copy(src, dest) array_copy_(src, (void**)&dest);
int array_len(void* array);
int array_capacity(void* array);
void array_free(void* array);
/* TODO function to increase capacity of array by certain number similar to reserve in stl vector? */
#endif

@ -144,15 +144,15 @@ void framebuffer_set_texture(int index, int texture, int attachment)
GL_TEXTURE_2D,
texture_get_texture_handle(texture),
0);
if(!renderer_check_glerror("framebuffer:set_texture:glFramebuffertexture"))
{
int current_fbo_tex = fbo_list[index].texture;
if(current_fbo_tex > -1)
texture_remove(current_fbo_tex);
fbo_list[index].texture = texture;
texture_inc_refcount(texture);
}
/* if(!renderer_check_glerror("framebuffer:set_texture:glFramebuffertexture")) */
/* { */
/* int current_fbo_tex = fbo_list[index].texture; */
/* if(current_fbo_tex > -1) */
/* texture_remove(current_fbo_tex); */
/* fbo_list[index].texture = texture; */
/* texture_inc_refcount(texture); */
/* } */
glBindFramebuffer(GL_FRAMEBUFFER, current_fbo);
}

@ -37,14 +37,14 @@ void game_init(void)
GLFWwindow* window = window_get_active();
/* Init systems */
input_init(window);
renderer_init(window);
io_file_init("/mnt/Dev/Projects/Symmetry/assets/");/* TODO: Implement proper way of getting binary directory */
shader_init();
texture_init();
framebuffer_init();
geom_init();
renderer_init(window);
transform_init();
camera_init();
geom_init();
material_init();
model_init();
entity_init();

@ -1,7 +1,5 @@
#include "geometry.h"
#include "array.h"
#include "num_types.h"
#include "linmath.h"
#include "string_utils.h"
#include "file_io.h"
#include "log.h"
@ -40,9 +38,9 @@ struct Geometry
static struct Geometry* geometry_list;
static int* empty_indices;
/* Function definitions */
int load_from_file(struct Geometry* geometry, const char* filename);
void create_vao(struct Geometry* geometry);
static int load_from_file(struct Geometry* geometry, const char* filename);
static void create_vao(struct Geometry* geometry);
static struct Geometry* generate_new_index(int* out_new_index);
void geom_init(void)
{
@ -65,26 +63,35 @@ int geom_find(const char* filename)
return index;
}
int geom_create(const char* name)
static struct Geometry* generate_new_index(int* out_new_index)
{
assert(out_new_index);
int empty_len = array_len(empty_indices);
struct Geometry* new_geo = NULL;
if(empty_len > 0)
{
*out_new_index = empty_indices[empty_len - 1];
array_pop(empty_indices);
new_geo = &geometry_list[*out_new_index];
}
else
{
new_geo = array_grow(geometry_list, struct Geometry);
*out_new_index = array_len(geometry_list) - 1;
}
return new_geo;
}
int geom_create_from_file(const char* name)
{
assert(name);
// check if exists
int index = geom_find(name);
if(index == -1)
{
/* add new geometry object or overwrite existing one */
struct Geometry* new_geo = NULL;
int empty_len = array_len(empty_indices);
if(empty_len > 0)
{
index = empty_indices[empty_len - 1];
array_pop(empty_indices);
new_geo = &geometry_list[index];
}
else
{
new_geo = array_grow(geometry_list, struct Geometry);
index = array_len(geometry_list) - 1;
}
new_geo = generate_new_index(&index);
assert(new_geo);
if(load_from_file(new_geo, name))
@ -106,6 +113,38 @@ int geom_create(const char* name)
return index;
}
int geom_create(const char* name, vec3* vertices, vec2* uvs, vec3* normals, uint* indices, vec3* vertex_colors)
{
assert(name && vertices && uvs && normals && indices);
int index = -1;
/* add new geometry object or overwrite existing one */
struct Geometry* new_geo = NULL;
new_geo = generate_new_index(&index);
assert(new_geo);
new_geo->filename = str_new(name);
new_geo->vertices = array_new_cap(vec3, array_len(vertices));
array_copy(vertices, new_geo->vertices);
new_geo->normals = array_new_cap(vec3, array_len(normals));
array_copy(normals, new_geo->normals);
new_geo->uvs = array_new_cap(vec2, array_len(uvs));
array_copy(uvs, new_geo->uvs);
new_geo->indices = array_new_cap(uint, array_len(indices));
array_copy(indices, new_geo->indices);
if(vertex_colors)
{
new_geo->vertex_colors = array_new_cap(vec3, array_len(vertex_colors));
array_copy(vertex_colors, new_geo->vertex_colors);
}
else
{
new_geo->vertex_colors = array_new(vec3);
}
create_vao(new_geo);
//generateBoundingBox(index);
return index;
}
void geom_remove(int index)
{
if(index >= 0 && index < array_len(geometry_list))
@ -122,6 +161,12 @@ void geom_remove(int index)
if(geometry->normals) array_free(geometry->normals);
if(geometry->vertex_colors) array_free(geometry->vertex_colors);
if(geometry->filename) free(geometry->filename);
geometry->indices = NULL;
geometry->vertices = NULL;
geometry->uvs = NULL;
geometry->normals = NULL;
geometry->vertex_colors = NULL;
geometry->filename = NULL;
array_push(empty_indices, index, int);
}
}
@ -137,7 +182,7 @@ void geom_cleanup(void)
array_free(empty_indices);
}
int load_from_file(struct Geometry* geometry, const char* filename)
static int load_from_file(struct Geometry* geometry, const char* filename)
{
assert(filename);
int success = 1;
@ -195,9 +240,9 @@ int load_from_file(struct Geometry* geometry, const char* filename)
return success;
}
void create_vao(struct Geometry* geometry)
static void create_vao(struct Geometry* geometry)
{
// TODO : Add support for different model formats and interleaving VBO
// TODO: Add support for different model formats and interleaving VBO
assert(geometry);
glGenVertexArrays(1, &geometry->vao);
glBindVertexArray(geometry->vao);

@ -1,8 +1,12 @@
#ifndef geometry_H
#define geometry_H
#include "num_types.h"
#include "linmath.h"
void geom_init(void);
int geom_create(const char* name);
int geom_create_from_file(const char* name);
int geom_create(const char* name, vec3* vertices, vec2* uvs, vec3* normals, uint* indices, vec3* vertex_colors);
int geom_find(const char* filename);
void geom_remove(int index);
void geom_cleanup(void);

@ -38,7 +38,7 @@ void model_init(void)
int model_create(int node, const char* geo_name)
{
assert(geo_name);
int geo_index = geom_create(geo_name);
int geo_index = geom_create_from_file(geo_name);
int index = -1;
struct Model* new_model = NULL;
if(geo_index > -1)

@ -4,8 +4,19 @@
#include "log.h"
#include "camera.h"
#include "model.h"
#include "texture.h"
#include "framebuffer.h"
#include "array.h"
#include "geometry.h"
#include "shader.h"
#include "num_types.h"
#include "window_system.h"
static int default_fbo = -1;
static int def_fbo = -1;
static int def_render_tex = -1;
static int def_depth_tex = -1;
static int quad_geo = -1;
static int fbo_shader = -1;
void on_framebuffer_size_change(GLFWwindow* window, int width, int height);
@ -15,19 +26,105 @@ void renderer_init(GLFWwindow* window)
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glfwSetFramebufferSizeCallback(window, on_framebuffer_size_change);
/* Quad geometry for final render */
vec3* vertices = array_new(vec3);
vec2* uvs = array_new(vec2);
vec3* normals = array_new(vec3);
uint* indices = array_new(uint);
vec3 temp_v3;
vec2 temp_v2;
/* Vertices */
temp_v3.x = -1; temp_v3.y = -1; temp_v3.z = 0; array_push(vertices, temp_v3, vec3);
temp_v3.x = 1; temp_v3.y = -1; temp_v3.z = 0; array_push(vertices, temp_v3, vec3);
temp_v3.x = 1; temp_v3.y = 1; temp_v3.z = 0; array_push(vertices, temp_v3, vec3);
temp_v3.x = -1; temp_v3.y = 1; temp_v3.z = 0; array_push(vertices, temp_v3, vec3);
/* Normals */
temp_v3.x = 0; temp_v3.y = 1; temp_v3.z = 0; array_push(normals, temp_v3, vec3);
temp_v3.x = 0; temp_v3.y = 1; temp_v3.z = 0; array_push(normals, temp_v3, vec3);
/* Uvs */
temp_v2.x = 0; temp_v2.y = 0; array_push(uvs, temp_v2, vec2);
temp_v2.x = 1; temp_v2.y = 0; array_push(uvs, temp_v2, vec2);
temp_v2.x = 1; temp_v2.y = 1; array_push(uvs, temp_v2, vec2);
temp_v2.x = 0; temp_v2.y = 1; array_push(uvs, temp_v2, vec2);
/* Indices */
array_push(indices, 0, uint); array_push(indices, 1, uint); array_push(indices, 2, uint);
array_push(indices, 2, uint); array_push(indices, 3, uint); array_push(indices, 0, uint);
quad_geo = geom_create("Quad", vertices, uvs, normals, indices, NULL);
array_free(vertices);
array_free(uvs);
array_free(normals);
array_free(indices);
/* Textues for default fbo */
int width = -1, height = -1;
window_get_size(&width, &height);
def_render_tex = texture_create("def_render_texture",
TU_DIFFUSE,
width, height,
GL_RGBA,
GL_RGBA8,
GL_UNSIGNED_BYTE,
NULL);
texture_set_param(def_render_tex, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
texture_set_param(def_render_tex, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
texture_set_param(def_render_tex, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
texture_set_param(def_render_tex, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
def_depth_tex = texture_create("def_depth_texture",
TU_SHADOWMAP1,
width, height,
GL_DEPTH_COMPONENT,
GL_DEPTH_COMPONENT,
GL_UNSIGNED_BYTE,
NULL);
texture_set_param(def_depth_tex, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
texture_set_param(def_depth_tex, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
texture_set_param(def_depth_tex, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
texture_set_param(def_depth_tex, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
texture_set_param(def_depth_tex, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
texture_set_param(def_depth_tex, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
def_fbo = framebuffer_create(width, height, 0, 1);
framebuffer_set_texture(def_fbo, def_render_tex, GL_COLOR_ATTACHMENT0);
framebuffer_set_texture(def_fbo, def_depth_tex, GL_DEPTH_ATTACHMENT);
fbo_shader = shader_create("fbo.vert", "fbo.frag");
}
void renderer_draw(void)
{
framebuffer_bind(def_fbo);
{
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);
}
framebuffer_unbind();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* Hard coded version */
struct Camera* camera = camera_get(0);
model_render_all(camera);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
shader_bind(fbo_shader);
texture_bind(def_render_tex);
geom_render(quad_geo);
texture_unbind(def_render_tex);
shader_unbind();
}
void renderer_cleanup(void)
{
shader_remove(fbo_shader);
geom_remove(quad_geo);
framebuffer_remove(def_fbo);
texture_remove(def_render_tex);
texture_remove(def_depth_tex);
}
void on_framebuffer_size_change(GLFWwindow* window, int width, int height)

@ -81,10 +81,10 @@ int texture_create_from_file(const char* filename, int texture_unit)
index = texture_create(filename, texture_unit, width, height, fmt, int_fmt, GL_UNSIGNED_BYTE, img_data);
if(index > -1)
{
texture_param_set(index, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
texture_param_set(index, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
texture_param_set(index,GL_TEXTURE_WRAP_S,GL_REPEAT);
texture_param_set(index,GL_TEXTURE_WRAP_T,GL_REPEAT);
texture_set_param(index, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
texture_set_param(index, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
texture_set_param(index,GL_TEXTURE_WRAP_S,GL_REPEAT);
texture_set_param(index,GL_TEXTURE_WRAP_T,GL_REPEAT);
}
else
{
@ -291,7 +291,7 @@ int load_img(FILE* file, GLubyte** image_data, int* width, int* height, int* fmt
return success;
}
void texture_param_set(int index, int parameter, int value)
void texture_set_param(int index, int parameter, int value)
{
struct Texture* texture = NULL;
if(index > -1 && index < array_len(texture_list))
@ -303,7 +303,7 @@ void texture_param_set(int index, int parameter, int value)
glGetIntegerv(GL_TEXTURE_2D, &curr_texture);
glBindTexture(GL_TEXTURE_2D, texture->handle);
glTexParameteri(GL_TEXTURE_2D, parameter, value);
renderer_check_glerror("texture:param_set");
renderer_check_glerror("texture:set_param");
if(curr_texture != 0)
glBindTexture(GL_TEXTURE_2D, curr_texture);
}

@ -17,7 +17,7 @@ int texture_find(const char* name);
void texture_cleanup(void);
void texture_bind(int index);
void texture_unbind(int index);
void texture_param_set(int index, int parameter, int value);
void texture_set_param(int index, int parameter, int value);
int texture_get_textureunit(int index);
int texture_get_texture_handle(int index);
void texture_inc_refcount(int index);

@ -101,3 +101,8 @@ void window_set_should_close(int should_close)
{
glfwSetWindowShouldClose(active_window, should_close ? GL_TRUE : GL_FALSE);
}
void window_get_size(int* width, int* height)
{
glfwGetWindowSize(active_window, width, height);
}

@ -12,6 +12,7 @@ typedef void (*on_mouse_pos) (double, double); // Callback for mouse position
int window_init(const char* title, int width, int height);
void window_cleanup(void);
void window_set_size(int width, int height);
void window_get_size(int* width, int* height);
void window_poll_events(void);
void window_swap_buffers(void);
int window_should_close(void);

Loading…
Cancel
Save