polyadvent

A game engine from scratch in C
git clone git://jb55.com/polyadvent
Log | Files | Refs | README

commit 87f1a071c0ec3bfd2d4ed2e0ca84b78638017276
parent 609d293368a567b13ccf7569fde7cd6ec73be461
Author: William Casarin <bill@casarin.me>
Date:   Fri, 19 Jun 2015 00:12:44 -0700

VBOs

Diffstat:
Metc/shaders/test.f.glsl | 4++--
Metc/shaders/test.v.glsl | 4+---
Msrc/buffer.c | 41+++++++++++++++++++++++++++++++++++++++--
Msrc/buffer.h | 25++++++++++++++++++++++++-
Msrc/common.h | 6++++++
Msrc/game.h | 16+++++++++-------
Msrc/main.c | 2+-
Msrc/render.c | 104+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Msrc/render.h | 7+++++--
Msrc/shader.c | 4++--
Msrc/update.c | 8++++++--
Msrc/update.h | 2+-
12 files changed, 158 insertions(+), 65 deletions(-)

diff --git a/etc/shaders/test.f.glsl b/etc/shaders/test.f.glsl @@ -1,5 +1,5 @@ -#version 110 +uniform float fade_factor; void main() { - gl_FragColor = vec4(0.4,0.4,0.8,1.0); + gl_FragColor = vec4(0.4, 0.4, 0.8, 1.0) * fade_factor; } \ No newline at end of file diff --git a/etc/shaders/test.v.glsl b/etc/shaders/test.v.glsl @@ -2,9 +2,7 @@ attribute vec2 position; -varying vec2 texcoord; - void main() { - gl_Position = vec4(position, 0.0, 1.0); + gl_Position = vec4(position * 0.5, 0.0, 1.0); } \ No newline at end of file diff --git a/src/buffer.c b/src/buffer.c @@ -4,11 +4,48 @@ /* * Functions for creating OpenGL objects: */ -GLuint + +gpu_addr make_buffer(GLenum target, const void *buffer_data, GLsizei buffer_size) { - GLuint buffer; + gpu_addr buffer; glGenBuffers(1, &buffer); glBindBuffer(target, buffer); glBufferData(target, buffer_size, buffer_data, GL_STATIC_DRAW); return buffer; } + + +struct vbo* +make_index_buffer(GLenum target, const void *data, GLsizei buffer_size, + struct vbo *vbo) { + vbo->components = 2; + vbo->handle = make_buffer(target, data, buffer_size); + vbo->type = GL_ELEMENT_ARRAY_BUFFER; + return vbo; +} + + +struct vbo* +make_vertex_buffer(GLenum target, const void *data, + GLsizei buffer_size, struct vbo *vbo) { + vbo->components = 2; + vbo->handle = make_buffer(target, data, buffer_size); + vbo->type = GL_ARRAY_BUFFER; + return vbo; +} + +void bind_ibo(struct vbo *vbo) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo->handle); +} + +void bind_vbo(struct vbo *vbo, gpu_addr slot) { + glEnableVertexAttribArray(slot); + glBindBuffer(vbo->type, vbo->handle); + glVertexAttribPointer(slot, // attribute + vbo->components, // size + GL_FLOAT, // type + GL_FALSE, // normalized? + sizeof(GLfloat)*2, // stride + (void*)0 // array buffer offset + ); +} diff --git a/src/buffer.h b/src/buffer.h @@ -2,7 +2,30 @@ #define POLYADVENT_BUFFER_H #include "gl.h" +#include "common.h" -GLuint make_buffer(GLenum target, const void *buffer_data, GLsizei buffer_size); +typedef GLuint gpu_addr; + +struct vbo { + u32 type; + int components; + gpu_addr handle; +}; + +#define NUM_VBO_SLOTS 1 + +gpu_addr make_buffer(GLenum target, const void *buffer_data, + GLsizei buffer_size); + +struct vbo * +make_vertex_buffer(GLenum target, const void *buffer_data, + GLsizei buffer_size, struct vbo *vbo); + +struct vbo * +make_index_buffer(GLenum target, const void *buffer_data, + GLsizei buffer_size, struct vbo *vbo); + +void bind_vbo(struct vbo *vbo, gpu_addr slot); +void bind_ibo(struct vbo *vbo); #endif /* POLYADVENT_BUFFER_H */ diff --git a/src/common.h b/src/common.h @@ -2,4 +2,10 @@ #ifndef POLYADVENT_COMMON_H #define POLYADVENT_COMMON_H +typedef unsigned short u16; +typedef signed short s16; + +typedef unsigned int u32; +typedef signed int s32; + #endif /* POLYADVENT_COMMON_H */ diff --git a/src/game.h b/src/game.h @@ -2,11 +2,13 @@ #ifndef PA_GAME_H #define PA_GAME_H +#include "buffer.h" + /* * Global data used by our render callback: */ -typedef struct TestResources { - GLuint vertex_buffer, element_buffer; +struct test_resources { + struct vbo vertex_buffer, element_buffer; GLuint vertex_shader, fragment_shader, program; struct { @@ -14,17 +16,17 @@ typedef struct TestResources { } uniforms; struct { - GLint position; + gpu_addr position; } attributes; GLfloat fade_factor; -} TestResources; +}; -typedef struct GameState { +struct game_state { int counter; - TestResources test_resources; -} GameState; + struct test_resources test_resources; +}; #endif /* PA_GAME_H */ diff --git a/src/main.c b/src/main.c @@ -8,7 +8,7 @@ int main(void) { - GameState game; + struct game_state game; SDL_Window *window = SDL_CreateWindow( "SDL2/OpenGL Demo", 0, 0, 640, 480, diff --git a/src/render.c b/src/render.c @@ -9,37 +9,68 @@ #include "shader.h" #include "debug.h" #include "render.h" +#include "util.h" + + + +// v6----- v5 +// /| /| +// v1------v0| +// | | | | +// | |v7---|-|v4 +// |/ |/ +// v2------v3 -/* - * Global data used by our render callback: - */ static const GLfloat g_vertex_buffer_data[] = { - -0.5f, -0.5f, - 0.5f, -0.5f, - -0.5f, 0.6f, - 0.5f, 0.5f + 1, 1, 1, -1, 1, 1, -1,-1, 1, 1,-1, 1, // v0-v1-v2-v3 front + 1, 1,-1, 1, 1, 1, 1,-1, 1, 1,-1,-1, // v5-v0-v3-v4 right + -1, 1, 1, 1, 1, 1, 1, 1,-1, -1, 1,-1, // v1-v0-v5-v6 top + -1, 1, 1, -1, 1,-1, -1,-1,-1, -1,-1, 1, // v1-v6-v7-v2 left + 1,-1, 1, -1,-1, 1, -1,-1,-1, 1,-1,-1, // v3-v2-v7-v4 bottom + -1, 1,-1, 1, 1,-1, 1,-1,-1, -1,-1,-1 // v4-v7-v6-v5 back }; -static const GLushort g_element_buffer_data[] = { 0, 1, 2, 3 }; +/* static const GLfloat g_element_buffer_normals[] = { */ +/* 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // front */ +/* 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // right */ +/* 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, // top */ +/* -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, // left */ +/* 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1, 0, // bottom */ +/* 0, 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1 // back */ +/* }; */ + +static const GLushort g_element_buffer_data[] = { + 0, 1, 2, 0, 2, 3, // front + 4, 5, 6, 4, 6, 7, // right + 8, 9,10, 8,10,11, // top + 12,13,14, 12,14,15, // left + 16,17,18, 16,18,19, // bottom + 20,21,22, 20,22,23 +}; void -init_gl(TestResources * resources) { +init_gl(struct test_resources * resources) { //glEnable(GL_DEPTH_TEST); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + /* wireframe_mode_on(); */ + // VBOs - resources->vertex_buffer = make_buffer( - GL_ARRAY_BUFFER, - g_vertex_buffer_data, - sizeof(g_vertex_buffer_data) + make_vertex_buffer( + GL_ARRAY_BUFFER, + g_vertex_buffer_data, + sizeof(g_vertex_buffer_data), + &resources->vertex_buffer ); - resources->element_buffer = make_buffer( - GL_ELEMENT_ARRAY_BUFFER, - g_element_buffer_data, - sizeof(g_element_buffer_data) + + make_index_buffer( + GL_ELEMENT_ARRAY_BUFFER, + g_element_buffer_data, + sizeof(g_element_buffer_data), + &resources->element_buffer ); // Shaders @@ -47,6 +78,7 @@ init_gl(TestResources * resources) { GL_VERTEX_SHADER, SHADER("test.v.glsl") ); + assert(resources->vertex_shader != 0); resources->fragment_shader = make_shader( GL_FRAGMENT_SHADER, @@ -57,23 +89,24 @@ init_gl(TestResources * resources) { // Shader program resources->program = make_program(resources->vertex_shader, - resources->fragment_shader); + resources->fragment_shader); assert(resources->program != 0); // Program variables resources->uniforms.fade_factor - = glGetUniformLocation(resources->program, "fade_factor"); + = glGetUniformLocation(resources->program, "fade_factor"); resources->attributes.position - = glGetAttribLocation(resources->program, "position"); + = (gpu_addr)glGetAttribLocation(resources->program, "position"); assert(resources->program != 0); } + void -render (TestResources * resources) { +render (struct test_resources * resources) { glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); //clear background screen to black glClear( GL_COLOR_BUFFER_BIT ); @@ -82,32 +115,19 @@ render (TestResources * resources) { glUseProgram(resources->program); - /* glUniform1f(resources->uniforms.fade_factor, */ - /* resources->fade_factor) */; - - glBindBuffer(GL_ARRAY_BUFFER, - resources->vertex_buffer); - - glVertexAttribPointer( - (GLuint)resources->attributes.position, /* attribute */ - 2, /* size */ - GL_FLOAT, /* type */ - GL_FALSE, /* normalized? */ - sizeof(GLfloat)*2, /* stride */ - (void*)0 /* array buffer offset */ - ); - - glEnableVertexAttribArray((GLuint)resources->attributes.position); + glUniform1f(resources->uniforms.fade_factor, + resources->fade_factor); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, - resources->element_buffer); + bind_vbo(&resources->vertex_buffer, resources->attributes.position); + bind_ibo(&resources->element_buffer); glDrawElements( - GL_TRIANGLE_STRIP, /* mode */ - 4, /* count */ + GL_TRIANGLE_STRIP, + 36, /* count */ GL_UNSIGNED_SHORT, /* type */ (void*)0 /* element array buffer offset */ ); - glDisableVertexAttribArray((GLuint)resources->attributes.position); + //glDisableVertexAttribArray(resources->attributes.position); } + diff --git a/src/render.h b/src/render.h @@ -1,7 +1,10 @@ #ifndef POLYADVENT_RENDER_H #define POLYADVENT_RENDER_H -void init_gl(TestResources * resources); -void render(TestResources * resources); +void init_gl(struct test_resources * resources); +void render(struct test_resources * resources); + +void wireframe_mode_on(); +void wireframe_mode_off(); #endif /* POLYADVENT_RENDER_H */ diff --git a/src/shader.c b/src/shader.c @@ -18,11 +18,11 @@ make_shader(GLenum type, const char *filename) { return 0; shader = glCreateShader(type); - glShaderSource(shader, 1, (const GLchar**)&source, (GLint*)&length); + glShaderSource(shader, 1, (const GLchar*const*)&source, (GLint*)&length); free(source); glCompileShader(shader); - glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_ok); + glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_ok); if (!shader_ok) { fprintf(stderr, "Failed to compile %s:\n", filename); diff --git a/src/update.c b/src/update.c @@ -2,9 +2,13 @@ #include "gl.h" #include "update.h" -void update (GameState * game) { +void update (struct game_state * game) { unsigned int ms = SDL_GetTicks(); + struct test_resources * res; + + res = &game->test_resources; // Update fade effect in shader - game->test_resources.fade_factor = sinf((float)ms * 0.001f) * 0.5f + 0.5f; + res->fade_factor = sinf((float)ms * 0.001f) * 0.5f + 0.5f; + } diff --git a/src/update.h b/src/update.h @@ -4,6 +4,6 @@ #include "game.h" -void update(GameState * game); +void update(struct game_state * game); #endif /* PA_UPDATE_H */