Implemented immediate mode renderer for debug drawing and drawing arbitrary points, lines and triangles

dev
Shariq Shah 8 years ago
parent 6728ac5f8c
commit 8782bf27ac
  1. 2
      README.md
  2. 10
      assets/shaders/im_geom.frag
  3. 14
      assets/shaders/im_geom.vert
  4. 71
      src/libsymmetry/game.c
  5. 25
      src/libsymmetry/gl_load.c
  6. 9
      src/libsymmetry/gl_load.h
  7. 157
      src/libsymmetry/im_render.c
  8. 32
      src/libsymmetry/im_render.h
  9. 24
      src/libsymmetry/renderer.c
  10. 2
      src/libsymmetry/renderer.h

@ -156,6 +156,7 @@
- ## TODO - ## TODO
- Physics forces/torque etc - Physics forces/torque etc
- Replace all renderer_check_gl calls with GL_CHECK macro
- Fix lights type not being correctly saved/loaded from file - Fix lights type not being correctly saved/loaded from file
- Physics Trimesh support - Physics Trimesh support
- Debug physics mesh drawing - Debug physics mesh drawing
@ -365,3 +366,4 @@
* Implemented Getting/Modifying primitive physics shapes' values like length, radius etc * Implemented Getting/Modifying primitive physics shapes' values like length, radius etc
* Update physics if entity position/rotation/scale etc are changed * Update physics if entity position/rotation/scale etc are changed
* Implemented Physics raycasting * Implemented Physics raycasting
* Implemented immediate mode renderer that can draw arbitrary points, lines and triangles

@ -0,0 +1,10 @@
//include version.glsl
in vec4 color;
out vec4 frag_color;
void main()
{
frag_color = color;
}

@ -0,0 +1,14 @@
//include version.glsl
uniform mat4 mvp;
in vec3 vPosition;
in vec4 vColor;
out vec4 color;
void main()
{
gl_Position = mvp * vec4(vPosition, 1.0);
color = vColor;
}

@ -30,6 +30,7 @@
#include "../common/hashmap.h" #include "../common/hashmap.h"
#include "../common/variant.h" #include "../common/variant.h"
#include "../common/common.h" #include "../common/common.h"
#include "im_render.h"
#define UNUSED(a) (void)a #define UNUSED(a) (void)a
#ifndef _MSC_VER #ifndef _MSC_VER
@ -450,6 +451,76 @@ void debug(float dt)
} }
platform->physics.cs_remove(ray); platform->physics.cs_remove(ray);
} }
// Immediate geometry test
vec3 im_position = { 0.f, 20.f, 0.f };
vec3 im_scale = { 1.f, 1.f, 1.f };
quat im_rot = { 0.f, 0.f, 0.f, 1.f };
quat_identity(&im_rot);
im_begin(im_position, im_rot, im_scale, GL_LINES);
im_color(0.f, 1.f, 0.f, 1.f);
im_pos(0.f, 0.f, 0.f);
im_pos(100.f, 100.f, 10.f);
im_end();
im_position.x = -10;
im_begin(im_position, im_rot, im_scale, GL_TRIANGLES);
//Front
im_pos(0.f, 0.f, 0.f);
im_pos(0.f, 20.f, 0.f);
im_pos(20.f, 20.f, 0.f);
im_pos(20.f, 20.f, 0.f);
im_pos(20.f, 0.f, 0.f);
im_pos( 0.f, 0.f, 0.f);
//Back
im_pos(0.f, 0.f, 20.f);
im_pos(0.f, 20.f, 20.f);
im_pos(20.f, 20.f, 20.f);
im_pos(20.f, 20.f, 20.f);
im_pos(20.f, 0.f, 20.f);
im_pos( 0.f, 0.f, 20.f);
//Left
im_pos(0.f, 0.f, 0.f);
im_pos(0.f, 0.f, 20.f);
im_pos(0.f, 20.f, 20.f);
im_pos(0.f, 20.f, 20.f);
im_pos(0.f, 20.f, 0.f);
im_pos(0.f, 0.f, 20.f);
//Right
im_pos(20.f, 0.f, 0.f);
im_pos(20.f, 0.f, 20.f);
im_pos(20.f, 20.f, 20.f);
im_pos(20.f, 20.f, 20.f);
im_pos(20.f, 20.f, 0.f);
im_pos(20.f, 0.f, 20.f);
im_end();
im_position.x = -30.f;
im_begin(im_position, im_rot, im_scale, GL_LINES);
im_color(1.f, 1.f, 0.f, 1.f);
im_pos(0.f, 0.f, 0.f);
im_pos(0.f, 0.f, 10.f);
im_pos(0.f, 0.f, 10.f);
im_pos(0.f, 10.f, 10.f);
im_pos(0.f, 10.f, 10.f);
im_pos(0.f, 10.f, 0.f);
im_pos(0.f, 10.f, 0.f);
im_pos(0.f, 0.f, 0.f);
im_end();
} }
bool run(void) bool run(void)

@ -44,4 +44,27 @@ bool gl_load_extentions(void)
#undef GLE #undef GLE
#endif #endif
return success; return success;
} }
void gl_check_error(const char * expression, unsigned int line, const char * file)
{
int error = 1;
GLenum error_code = glGetError();
const char* error_string = "No Error";
switch(error_code)
{
case GL_INVALID_OPERATION: error_string = "Invalid Operation"; break;
case GL_NO_ERROR: error_string = "No Error"; break;
case GL_INVALID_ENUM: error_string = "Invalid ENUM"; break;
case GL_INVALID_VALUE: error_string = "Invalid Value"; break;
case GL_INVALID_FRAMEBUFFER_OPERATION: error_string = "Invalid FrameBuffer Operation"; break;
case GL_OUT_OF_MEMORY: error_string = "Out of Memory"; break;
}
if(error_code != GL_NO_ERROR)
log_error("GL", "(%s:%d:%s) : %s", file, line, expression, error_string);
else
error = 0;
return error;
}

@ -61,8 +61,17 @@ SYMMETRY_GL_LIST
#endif #endif
#ifdef GL_DEBUG
#define GL_CHECK(expression) do { gl_check(#expression, __LINE__, __FILE__)} while(false)
#else
#define GL_CHECK(expression) (expression)
#endif
int gl_load_library(void); int gl_load_library(void);
bool gl_load_extentions(void); bool gl_load_extentions(void);
void gl_check_error(const char* expression, unsigned int line, const char* file);
void gl_cleanup(void); void gl_cleanup(void);
#endif #endif

@ -0,0 +1,157 @@
#include "im_render.h"
#include "entity.h"
#include "camera.h"
#include "gl_load.h"
#include "../common/array.h"
#include "../common/num_types.h"
#include "shader.h"
#include "../common/log.h"
#define MAX_IM_VERTICES 4096
#define MAX_IM_GEOMETRIES (MAX_IM_VERTICES / 2)
static struct
{
struct IM_Vertex vertices[MAX_IM_VERTICES];
struct IM_Geom geometries[MAX_IM_GEOMETRIES];
uint vao;
uint vbo;
int im_shader;
int curr_geom;
int curr_vertex;
vec4 default_color;
}
IM_State;
static struct IM_Geom* active_geom = NULL;
static vec4 active_vertex_color = { 0.f, 0.f, 0.f, 0.f };
void im_init(void)
{
glGenVertexArrays(1, &IM_State.vao);
glBindVertexArray(IM_State.vao);
glGenBuffers(1, &IM_State.vbo);
glBindBuffer(GL_ARRAY_BUFFER, IM_State.vbo);
GL_CHECK(glBufferData(GL_ARRAY_BUFFER, sizeof(struct IM_Vertex) * MAX_IM_VERTICES, NULL, GL_STREAM_DRAW));
//Position
GL_CHECK(glVertexAttribPointer(ATTRIB_LOC_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(struct IM_Vertex), 0));
GL_CHECK(glEnableVertexAttribArray(ATTRIB_LOC_POSITION));
//Color
GL_CHECK(glVertexAttribPointer(ATTRIB_LOC_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(struct IM_Vertex), sizeof(vec3)));
GL_CHECK(glEnableVertexAttribArray(ATTRIB_LOC_COLOR));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
memset(&IM_State.geometries[0], 0, sizeof(struct IM_Geom) * MAX_IM_GEOMETRIES);
memset(&IM_State.vertices[0], 0, sizeof(struct IM_Vertex) * MAX_IM_VERTICES);
IM_State.curr_geom = -1;
IM_State.curr_vertex = 0;
vec4_fill(&IM_State.default_color, 1.f, 0.f, 1.f, 1.f);
vec4_assign(&active_vertex_color, &IM_State.default_color);
IM_State.im_shader = shader_create("im_geom.vert", "im_geom.frag");
}
void im_cleanup(void)
{
shader_remove(IM_State.im_shader);
glDeleteBuffers(1, &IM_State.vbo);
glDeleteVertexArrays(1, &IM_State.vao);
memset(&IM_State.geometries[0], 0, sizeof(struct IM_Geom) * MAX_IM_GEOMETRIES);
memset(&IM_State.vertices[0], 0, sizeof(struct IM_Vertex) * MAX_IM_VERTICES);
IM_State.vao = 0;
IM_State.vbo = 0;
IM_State.curr_geom = -1;
IM_State.curr_vertex = 0;
IM_State.im_shader = -1;
}
void im_begin(vec3 position, quat rotation, vec3 scale, int draw_mode)
{
if(active_geom)
{
log_error("im_begin", "im_begin called before im_end");
return;
}
IM_State.curr_geom++;
active_geom = &IM_State.geometries[IM_State.curr_geom];
active_geom->start_index = IM_State.curr_vertex;
active_geom->draw_mode = draw_mode;
vec3_assign(&active_geom->position, &position);
vec3_assign(&active_geom->scale, &scale);
quat_assign(&active_geom->rotation, &rotation);
}
void im_pos(float x, float y, float z)
{
vec3_fill(&IM_State.vertices[IM_State.curr_vertex].position, x, y, z);
vec4_assign(&IM_State.vertices[IM_State.curr_vertex].color, &active_vertex_color);
IM_State.curr_vertex++;
}
void im_color(float r, float g, float b, float a)
{
vec4_fill(&active_vertex_color, r, g, b, a);
}
void im_end(void)
{
active_geom->num_vertices = IM_State.curr_vertex - active_geom->start_index;
glBindBuffer(GL_ARRAY_BUFFER, IM_State.vbo);
glBufferSubData(GL_ARRAY_BUFFER,
sizeof(struct IM_Vertex) * active_geom->start_index,
sizeof(struct IM_Vertex) * active_geom->num_vertices,
&IM_State.vertices[active_geom->start_index]);
renderer_check_glerror("sprite_batch_end:glBufferSubData");
glBindBuffer(GL_ARRAY_BUFFER, 0);
active_geom = NULL;
vec4_assign(&active_vertex_color, &IM_State.default_color);
}
void im_render(struct Entity* active_viewer)
{
if(IM_State.curr_geom == -1)
return;
shader_bind(IM_State.im_shader);
{
static mat4 mvp, translation, rotation, scale;
glBindVertexArray(IM_State.vao);
for(int i = 0; i <= IM_State.curr_geom; i++)
{
struct IM_Geom* geom = &IM_State.geometries[i];
mat4_identity(&mvp);
mat4_identity(&scale);
mat4_identity(&translation);
mat4_identity(&rotation);
mat4_scale(&scale, geom->scale.x, geom->scale.y, geom->scale.z);
mat4_translate(&translation, geom->position.x, geom->position.y, geom->position.z);
mat4_from_quat(&rotation, &geom->rotation);
mat4_mul(&mvp, &mvp, &translation);
mat4_mul(&mvp, &mvp, &rotation);
mat4_mul(&mvp, &mvp, &scale);
mat4_mul(&mvp, &active_viewer->camera.view_proj_mat, &mvp);
shader_set_uniform_mat4(IM_State.im_shader, "mvp", &mvp);
glDrawArrays(geom->draw_mode, geom->start_index, geom->num_vertices);
}
glBindVertexArray(0);
}
shader_unbind();
IM_State.curr_geom = -1;
IM_State.curr_vertex = 0;
}

@ -0,0 +1,32 @@
#ifndef IM_RENDER_H
#define IM_RENDER_H
#include "../common/linmath.h"
struct IM_Vertex
{
vec3 position;
vec4 color;
};
struct IM_Geom
{
vec3 position;
quat rotation;
vec3 scale;
int start_index;
int num_vertices;
int draw_mode;
};
struct Entity;
void im_init(void);
void im_cleanup(void);
void im_begin(vec3 position, quat rotation, vec3 scale, int draw_mode);
void im_pos(float x, float y, float z);
void im_color(float r, float g, float b, float a); // set active color
void im_end(void);
void im_render(struct Entity* active_viewer);
#endif

@ -19,6 +19,7 @@
#include "material.h" #include "material.h"
#include "editor.h" #include "editor.h"
#include "sprite.h" #include "sprite.h"
#include "im_render.h"
#include "../common/variant.h" #include "../common/variant.h"
#include "../common/common.h" #include "../common/common.h"
@ -131,6 +132,8 @@ void renderer_init(void)
{ {
sprite_batch_create(sprite_batch, "sprite_map.tga", "sprite.vert", "sprite.frag", GL_TRIANGLES); sprite_batch_create(sprite_batch, "sprite_map.tga", "sprite.vert", "sprite.frag", GL_TRIANGLES);
} }
im_init();
} }
void renderer_draw(struct Entity* active_viewer) void renderer_draw(struct Entity* active_viewer)
@ -405,7 +408,9 @@ void renderer_draw(struct Entity* active_viewer)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
} }
shader_unbind(); //Immediate mode geometry render
im_render(active_viewer);
/* Render 2D stuff */ /* Render 2D stuff */
shader_bind(sprite_batch->shader); shader_bind(sprite_batch->shader);
@ -416,7 +421,7 @@ void renderer_draw(struct Entity* active_viewer)
struct Game_State* game_state = game_state_get(); struct Game_State* game_state = game_state_get();
platform->window.get_size(game_state->window, &width, &height); platform->window.get_size(game_state->window, &width, &height);
mat4_ortho(&ortho_mat, 0, width, height, 0, -10.f, 10.f); mat4_ortho(&ortho_mat, 0.f, (float)width, (float)height, 0.f, -10.f, 10.f);
shader_set_uniform_mat4(sprite_batch->shader, "mvp", &ortho_mat); shader_set_uniform_mat4(sprite_batch->shader, "mvp", &ortho_mat);
sprite_batch_render(sprite_batch); sprite_batch_render(sprite_batch);
@ -429,6 +434,7 @@ void renderer_draw(struct Entity* active_viewer)
void renderer_cleanup(void) void renderer_cleanup(void)
{ {
im_cleanup();
sprite_batch_remove(sprite_batch); sprite_batch_remove(sprite_batch);
free(sprite_batch); free(sprite_batch);
gui_cleanup(); gui_cleanup();
@ -480,15 +486,11 @@ int renderer_check_glerror(const char* context)
error = 0; error = 0;
return error; return error;
} }
void im_render_box(float position, float length, float width, float height) struct Sprite_Batch * get_batch(void)
{ {
} return sprite_batch;
struct Sprite_Batch * get_batch(void)
{
return sprite_batch;
} }
void renderer_debug_draw_enabled(bool enabled) void renderer_debug_draw_enabled(bool enabled)

@ -43,8 +43,6 @@ void renderer_clearcolor_set(float r, float g, float b, float a);
void renderer_debug_draw_enabled(bool enabled); void renderer_debug_draw_enabled(bool enabled);
int renderer_check_glerror(const char* context); int renderer_check_glerror(const char* context);
void im_render_box(float position, float length, float width, float height);
struct Sprite_Batch* get_batch(void); struct Sprite_Batch* get_batch(void);
#endif #endif

Loading…
Cancel
Save