medfall

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit c83c3a49c983adc0b9b23dc35b4aa3852e0a642d
parent 7324b4cf8dc151438e0602aca35b83b7f279955b
Author: Michael Savage <mikejsavage@gmail.com>
Date:   Mon Aug 17 21:49:05 +0200

First attempt at porting BSP renderer to OpenGL 3.2

Diffstat:
Makefile | 4++--
bsp.cc | 170++++++++++++++++++++++++++++++++++++-------------------------------------------
bsp.h | 7+++----
bsp_renderer.cc | 215++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
bsp_renderer.h | 18++++++++++++------
game.h | 8++++++++
6 files changed, 255 insertions(+), 167 deletions(-)
diff --git a/Makefile b/Makefile @@ -1,7 +1,7 @@ -all: medfall hm.so pp +all: medfall bsp.so hm.so pp OBJS = main.o gl.o -BSPOBJS = bsp.o bsp_renderer.o gl.o +BSPOBJS = bsp.o bsp_renderer.o gl.o memory_arena.o HMOBJS = hm.o heightmap.o terrain_manager.o work_queue.o stb_image.o stb_perlin.o immediate.o PPOBJS = pp.o stb_image.o stb_image_write.o diff --git a/bsp.cc b/bsp.cc @@ -2,45 +2,43 @@ #include <fstream> #include <math.h> -#include <GL/glu.h> #include <GLFW/glfw3.h> #include <glm/glm.hpp> +#include <glm/gtc/matrix_transform.hpp> +#include <glm/gtc/type_ptr.hpp> -#include "int.h" +#include "game.h" +#include "intrinsics.h" #include "gl.h" #include "bsp.h" #include "bsp_renderer.h" -#include "stb_easy_font.h" - -const float EPSILON = 1.0 / 32.0; - -#define TEXT( x, y, form, ... ) \ - do { \ - static char buffer[ 99999 ]; \ - static char text[ 2048 ]; \ - sprintf( text, form, __VA_ARGS__ ); \ - const int num_quads = stb_easy_font_print( x, y, text, NULL, buffer, sizeof( buffer ) ); \ - glColor3f(1,1,1); \ - glVertexPointer(2, GL_FLOAT, 16, buffer); \ - glDrawArrays(GL_QUADS, 0, num_quads*4); \ - } while( 0 ) - -void glterrible() { - printf( "glterrible\n" ); - GLenum err = glGetError(); - const char * error; - - switch(err) { - case GL_INVALID_OPERATION: error="INVALID_OPERATION"; break; - case GL_INVALID_ENUM: error="INVALID_ENUM"; break; - case GL_INVALID_VALUE: error="INVALID_VALUE"; break; - case GL_OUT_OF_MEMORY: error="OUT_OF_MEMORY"; break; - case GL_INVALID_FRAMEBUFFER_OPERATION: error="INVALID_FRAMEBUFFER_OPERATION"; break; - default: error = "shit bro"; break; +#include "shitty_glsl.h" + +static const GLchar * const vert_src = GLSL( + in vec3 position; + in vec3 colour; + + out vec3 frag_colour; + + uniform mat4 VP; + + void main() { + gl_Position = VP * vec4( position, 1.0 ); + frag_colour = colour; } +); - printf( "GL error: %s\n", error ); -} +static const GLchar * frag_src = GLSL( + in vec3 frag_colour; + + out vec4 screen_colour; + + void main() { + screen_colour = vec4( frag_colour, 1.0 ); + } +); + +static const float EPSILON = 1.0 / 32.0; // TODO: bit twiddling? bool same_sign( const float a, const float b ) { @@ -85,7 +83,6 @@ BSP::~BSP() { delete contents; } - template< typename T > void BSP::load_lump( u32 & num_ts, T *& ts, const BSP_Lump lump ) { const BSP_Header * const header = reinterpret_cast< BSP_Header * >( contents ); @@ -255,72 +252,61 @@ glm::vec3 angles_to_vector( const glm::vec3 & angles ) { ); } -int main() { - BSP bsp( "acidwdm2.bsp" ); - GLFWwindow * const window = GL::init(); - - glm::vec3 pos( 0, -100, 450 ); - glm::vec3 angles = d2r( glm::vec3( -90, 135, 0 ) ); - const glm::vec3 end = pos + angles_to_vector( angles ) * 1000.0f; - - Intersection tt; - bool hit = bsp.trace_seg( pos, end, tt ); - - printf( "%.3f: %s %.1f %.1f %.1f\n", tt.t, hit ? "yes" : "no", tt.pos.x, tt.pos.y, tt.pos.z ); - - float lastFrame = glfwGetTime(); +static const glm::mat4 P( glm::perspective( glm::radians( 120.0f ), 640.0f / 480.0f, 0.1f, 10000.0f ) ); - gluPerspective( 120.0f, 800.0f / 600.0f, 0.1f, 10000.0f ); +extern "C" GAME_INIT( game_init ) { + state->bsp = BSP( "acidwdm2.bsp" ); - while( !glfwWindowShouldClose( window ) ) { - const float now = glfwGetTime(); - const float dt = now - lastFrame; + u8 * memory = reserve_persistent( mem, megabytes( 10 ) ); + MemoryArena arena; + memarena_init( &arena, memory, megabytes( 10 ) ); - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + bspr_init( &state->bspr, &arena, &state->bsp ); - const int fb = glfwGetKey( window, 'W' ) - glfwGetKey( window, 'S' ); - const int lr = glfwGetKey( window, 'A' ) - glfwGetKey( window, 'D' ); + state->pos = glm::vec3( 0, -100, 450 ); + state->angles = glm::radians( ( glm::vec3( -90, 135, 0 ) ) ); - if( fb ) { - pos += angles_to_vector( angles ) * 320.0f * dt * ( float ) fb; - } - - if( lr ) { - const glm::vec3 sideways = glm::vec3( -cosf( angles.y ), sinf( angles.y ), 0 ); - pos += sideways * 320.0f * dt * ( float ) lr; - } - - // TODO: do matrices like a big boy - glPushMatrix(); - - glRotatef( angles.x * 180 / M_PI, 1.0, 0.0, 0.0 ); - glRotatef( angles.y * 180 / M_PI, 0.0, 0.0, 1.0 ); - glTranslatef( -pos.x, -pos.y, -pos.z ); - - BSP_Renderer::render( bsp, pos ); - - glLoadIdentity(); - - glBegin( GL_TRIANGLE_STRIP ); - glColor3f( 0.2, 0.2, 0.2 ); - glVertex2f( -1, 1 ); - glVertex2f( 1, 1 ); - glVertex2f( -1, 0.95 ); - glVertex2f( 1, 0.95 ); - glEnd(); - - glOrtho( 0, 640, 480, 0, -1, 1 ); - TEXT( 2, 2, "%d", ( int ) ( 1 / dt ) ); - - glPopMatrix(); - - glfwSwapBuffers( window ); - glfwPollEvents(); + state->test_shader = compile_shader( vert_src, frag_src, "screen_colour" ); + state->test_at_position = glGetAttribLocation( state->test_shader, "position" ); + state->test_at_colour = glGetAttribLocation( state->test_shader, "colour" ); + state->test_un_VP = glGetUniformLocation( state->test_shader, "VP" ); +} - lastFrame = now; - } +extern "C" GAME_FRAME( game_frame ) { + GameState * state = ( GameState * ) mem.persistent; + + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + const int fb = glfwGetKey( window, 'W' ) - glfwGetKey( window, 'S' ); + const int lr = glfwGetKey( window, 'A' ) - glfwGetKey( window, 'D' ); + const int dz = glfwGetKey( window, GLFW_KEY_SPACE ) - glfwGetKey( window, GLFW_KEY_LEFT_SHIFT ); + + const int pitch = glfwGetKey( window, GLFW_KEY_UP ) - glfwGetKey( window, GLFW_KEY_DOWN ); + const int yaw = glfwGetKey( window, GLFW_KEY_RIGHT ) - glfwGetKey( window, GLFW_KEY_LEFT ); + + state->angles.x += pitch * dt * 2; + state->angles.y += yaw * dt * 2; + + state->pos += angles_to_vector( state->angles ) * 100.0f * dt * ( float ) fb; + const glm::vec3 sideways = glm::vec3( -cosf( state->angles.y ), sinf( state->angles.y ), 0 ); + state->pos += sideways * 100.0f * dt * ( float ) lr; + state->pos.z += ( float ) dz * 100.0f * dt; + + const glm::mat4 VP = glm::translate( + glm::rotate( + glm::rotate( + P, + state->angles.x, + glm::vec3( 1, 0, 0 ) + ), + state->angles.y, + glm::vec3( 0, 0, 1 ) + ), + -state->pos + ); - GL::term(); + glUseProgram( state->test_shader ); + glUniformMatrix4fv( state->test_un_VP, 1, GL_FALSE, glm::value_ptr( VP ) ); - return 0; + bspr_render( &state->bspr, state->pos, state->test_at_position, state->test_at_colour ); } diff --git a/bsp.h b/bsp.h @@ -2,7 +2,7 @@ #define _BSP_H_ #include <string> -#include "int.h" +#include "intrinsics.h" enum BSP_Lump { LUMP_ENTITIES = 0, @@ -43,7 +43,7 @@ struct BSP_Texture { i32 surface_flags; i32 content_flags; }; - + struct BSP_Plane { glm::vec3 n; float d; @@ -149,9 +149,8 @@ struct BSP_Intersection { }; class BSP { - friend class BSP_Renderer; - private: +public: // TODO char * contents; u32 num_textures; diff --git a/bsp_renderer.cc b/bsp_renderer.cc @@ -1,92 +1,181 @@ #include <string.h> -#include <GL/gl.h> +#include "platform_opengl.h" #include <glm/glm.hpp> +#include <glm/gtc/matrix_transform.hpp> +#include <glm/gtc/type_ptr.hpp> +#include "intrinsics.h" #include "bsp.h" #include "bsp_renderer.h" +#include "memory_arena.h" -void BSP_Renderer::pick_color( const BSP & bsp, const BSP_Face & face ) { - if(strcmp(bsp.textures[face.texture].name, "textures/acidwdm2/wall_olive033") == 0) { - glColor3f(0, 0.33, 0); - } else if(strcmp(bsp.textures[face.texture].name, "textures/acidwdm2/wall_olive066") == 0) { - glColor3f(0, 0.66, 0); - } else if(strcmp(bsp.textures[face.texture].name, "textures/acidwdm2/wall_olive100") == 0) { - glColor3f(0, 1, 0); - } else if(strcmp(bsp.textures[face.texture].name, "textures/acidwdm2/wall_olive100_fade") == 0) { - glColor3f(0.25, 1, 0.25); - } else if(strcmp(bsp.textures[face.texture].name, "textures/acidwdm2/wall_red100_fade") == 0) { - glColor3f(1, 0.25, 0.25); - } else if(strcmp(bsp.textures[face.texture].name, "textures/acidwdm2/wall_red100") == 0) { - glColor3f(1, 0, 0); - } else if(strcmp(bsp.textures[face.texture].name, "textures/acidwdm2/wall_red066") == 0) { - glColor3f(0.66, 0, 0); - } else if(strcmp(bsp.textures[face.texture].name, "textures/acidwdm2/wall_red033") == 0) { - glColor3f(0.33, 0, 0); - } else if(strcmp(bsp.textures[face.texture].name, "textures/acidwdm2/wall_purple033") == 0) { - glColor3f(0.33, 0, 0.33); - } else if(strcmp(bsp.textures[face.texture].name, "textures/acidwdm2/wall_purple066") == 0) { - glColor3f(0.66, 0, 0.66); - } else if(strcmp(bsp.textures[face.texture].name, "textures/acidwdm2/wall_purple100") == 0) { - glColor3f(1, 0, 1); - } else if(strcmp(bsp.textures[face.texture].name, "textures/acidwdm2/wall_purple100_fade") == 0) { - glColor3f(1, 0.25, 1); - } else if(strcmp(bsp.textures[face.texture].name, "textures/acidwdm2/wall_cyan033") == 0) { - glColor3f(0, 0.33, 0.33); - } else if(strcmp(bsp.textures[face.texture].name, "textures/acidwdm2/wall_cyan066") == 0) { - glColor3f(0, 0.66, 0.66); - } else if(strcmp(bsp.textures[face.texture].name, "textures/acidwdm2/wall_cyan100") == 0) { - glColor3f(0, 1, 1); - } else if(strcmp(bsp.textures[face.texture].name, "textures/acidwdm2/wall_cyan100_fade") == 0) { - glColor3f(0.25, 1, 1); - } else if(strcmp(bsp.textures[face.texture].name, "textures/acidwdm2/struc_lightgrey") == 0) { - //glColor3f(0.85, 0.85, 0.85); - glColor3f(0.15, 0.15, 0.15); - } else if(strcmp(bsp.textures[face.texture].name, "textures/acidwdm2/struc_darkgrey") == 0) { - glColor3f(0.5, 0.5, 0.5); - } else if(strcmp(bsp.textures[face.texture].name, "textures/acidwdm2/sky_black") == 0) { - glColor3f(0, 0, 0); - } else if(strcmp(bsp.textures[face.texture].name, "textures/acidwdm2/ink") == 0) { - //glColor3f(0, 0, 0); - glColor3f( 0, 0, 0 ); +glm::vec3 bspr_face_colour( const BSP * const bsp, const BSP_Face & face ) { + if(strcmp(bsp->textures[face.texture].name, "textures/acidwdm2/wall_olive033") == 0) { + return glm::vec3(0, 0.33, 0); + } else if(strcmp(bsp->textures[face.texture].name, "textures/acidwdm2/wall_olive066") == 0) { + return glm::vec3(0, 0.66, 0); + } else if(strcmp(bsp->textures[face.texture].name, "textures/acidwdm2/wall_olive100") == 0) { + return glm::vec3(0, 1, 0); + } else if(strcmp(bsp->textures[face.texture].name, "textures/acidwdm2/wall_olive100_fade") == 0) { + return glm::vec3(0.25, 1, 0.25); + } else if(strcmp(bsp->textures[face.texture].name, "textures/acidwdm2/wall_red100_fade") == 0) { + return glm::vec3(1, 0.25, 0.25); + } else if(strcmp(bsp->textures[face.texture].name, "textures/acidwdm2/wall_red100") == 0) { + return glm::vec3(1, 0, 0); + } else if(strcmp(bsp->textures[face.texture].name, "textures/acidwdm2/wall_red066") == 0) { + return glm::vec3(0.66, 0, 0); + } else if(strcmp(bsp->textures[face.texture].name, "textures/acidwdm2/wall_red033") == 0) { + return glm::vec3(0.33, 0, 0); + } else if(strcmp(bsp->textures[face.texture].name, "textures/acidwdm2/wall_purple033") == 0) { + return glm::vec3(0.33, 0, 0.33); + } else if(strcmp(bsp->textures[face.texture].name, "textures/acidwdm2/wall_purple066") == 0) { + return glm::vec3(0.66, 0, 0.66); + } else if(strcmp(bsp->textures[face.texture].name, "textures/acidwdm2/wall_purple100") == 0) { + return glm::vec3(1, 0, 1); + } else if(strcmp(bsp->textures[face.texture].name, "textures/acidwdm2/wall_purple100_fade") == 0) { + return glm::vec3(1, 0.25, 1); + } else if(strcmp(bsp->textures[face.texture].name, "textures/acidwdm2/wall_cyan033") == 0) { + return glm::vec3(0, 0.33, 0.33); + } else if(strcmp(bsp->textures[face.texture].name, "textures/acidwdm2/wall_cyan066") == 0) { + return glm::vec3(0, 0.66, 0.66); + } else if(strcmp(bsp->textures[face.texture].name, "textures/acidwdm2/wall_cyan100") == 0) { + return glm::vec3(0, 1, 1); + } else if(strcmp(bsp->textures[face.texture].name, "textures/acidwdm2/wall_cyan100_fade") == 0) { + return glm::vec3(0.25, 1, 1); + } else if(strcmp(bsp->textures[face.texture].name, "textures/acidwdm2/struc_lightgrey") == 0) { + //return glm::vec3(0.85, 0.85, 0.85); + return glm::vec3(0.15, 0.15, 0.15); + } else if(strcmp(bsp->textures[face.texture].name, "textures/acidwdm2/struc_darkgrey") == 0) { + return glm::vec3(0.5, 0.5, 0.5); + } else if(strcmp(bsp->textures[face.texture].name, "textures/acidwdm2/sky_black") == 0) { + return glm::vec3(0, 0, 0); + } else if(strcmp(bsp->textures[face.texture].name, "textures/acidwdm2/ink") == 0) { + //return glm::vec3(0, 0, 0); + return glm::vec3( 0, 0, 0 ); } else { - //glColor3f( 1, 1, 1 ); - glColor3f( 0, 0, 0 ); + //return glm::vec3( 1, 1, 1 ); + return glm::vec3( 0, 0, 0 ); } } -void BSP_Renderer::render_leaf( const BSP & bsp, const BSP_Leaf & leaf ) { - for( u32 i = 0; i < leaf.num_faces; i++ ) { - const BSP_LeafFace & leaf_face = bsp.leaf_faces[ i + leaf.init_face ]; - const BSP_Face & face = bsp.faces[ leaf_face ]; +void bspr_init( BSPRenderer * const bspr, MemoryArena * const arena, const BSP * const bsp ) { + bspr->arena = arena; + bspr->bsp = bsp; - pick_color( bsp, face ); + bspr->vaos = memarena_push_many( arena, GLuint, bsp->num_leaves ); + bspr->vbos = memarena_push_many( arena, GLuint, bsp->num_leaves * 2 ); + bspr->ebos = memarena_push_many( arena, GLuint, bsp->num_leaves ); + bspr->vertex_counts = memarena_push_many( arena, u32, bsp->num_leaves ); - glVertexPointer( 3, GL_FLOAT, sizeof( BSP_Vertex ), &bsp.vertices[ face.init_vert ].pos ); - glDrawElements( GL_TRIANGLES, face.num_mesh_verts, GL_UNSIGNED_INT, &bsp.mesh_verts[ face.init_mesh_vert ] ); + glGenVertexArrays( bsp->num_leaves, bspr->vaos ); + glGenBuffers( bsp->num_leaves * 2, bspr->vbos ); + glGenBuffers( bsp->num_leaves, bspr->ebos ); + + GLfloat * pos_scratch = memarena_push_many( arena, GLfloat, 4096 ); + u32 pos_scratch_used = 0; + + GLfloat * colour_scratch = memarena_push_many( arena, GLfloat, 4096 ); + u32 colour_scratch_used = 0; + + GLuint * ebo_scratch = memarena_push_many( arena, GLuint, 4096 ); + u32 ebo_scratch_used = 0; + + for( u32 l = 0; l < bspr->bsp->num_leaves; l++ ) { + const BSP_Leaf & leaf = bspr->bsp->leaves[ l ]; + + for( u32 f = 0; f < leaf.num_faces; f++ ) { + const BSP_LeafFace & leaf_face = bspr->bsp->leaf_faces[ f + leaf.init_face ]; + const BSP_Face & face = bspr->bsp->faces[ leaf_face ]; + const glm::vec3 colour = bspr_face_colour( bspr->bsp, face ); + + for( i32 v = 0; v < face.num_verts; v++ ) { + const BSP_Vertex & vert = bspr->bsp->vertices[ face.init_vert + v ]; + const glm::vec3 pos = vert.pos; + + pos_scratch[ pos_scratch_used++ ] = pos.x; + pos_scratch[ pos_scratch_used++ ] = pos.y; + pos_scratch[ pos_scratch_used++ ] = pos.z; + colour_scratch[ colour_scratch_used++ ] = colour.x; + colour_scratch[ colour_scratch_used++ ] = colour.y; + colour_scratch[ colour_scratch_used++ ] = colour.z; + + assert( pos_scratch_used < 4096 && colour_scratch_used < 4096 ); + } + + for( i32 m = 0; m < face.num_mesh_verts; m++ ) { + const u32 idx = bsp->mesh_verts[ face.init_mesh_vert + m ]; + const glm::vec3 pos = bspr->bsp->vertices[ face.init_vert + idx ].pos; + + ebo_scratch[ ebo_scratch_used++ ] = idx; + + assert( ebo_scratch_used < 4096 ); + } + } + + glBindVertexArray( bspr->vaos[ l ] ); + + glBindBuffer( GL_ARRAY_BUFFER, bspr->vbos[ l * 2 ] ); + glBufferData( GL_ARRAY_BUFFER, pos_scratch_used * sizeof( GLfloat ), pos_scratch, GL_STATIC_DRAW ); + + glBindBuffer( GL_ARRAY_BUFFER, bspr->vbos[ l * 2 + 1 ] ); + glBufferData( GL_ARRAY_BUFFER, colour_scratch_used * sizeof( GLfloat ), colour_scratch, GL_STATIC_DRAW ); + + glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, bspr->ebos[ l ] ); + glBufferData( GL_ELEMENT_ARRAY_BUFFER, ebo_scratch_used * sizeof( GLuint ), ebo_scratch, GL_STATIC_DRAW ); + + bspr->vertex_counts[ l ] = ebo_scratch_used; + + pos_scratch_used = 0; + colour_scratch_used = 0; + ebo_scratch_used = 0; } } -void BSP_Renderer::render( const BSP & bsp, const glm::vec3 & camera ) { - const i32 cluster = bsp.position_to_leaf( camera ).cluster; +static void bspr_render_leaf( const BSPRenderer * const bspr, const u32 leaf, const GLuint at_position, const GLuint at_colour ) { + glBindVertexArray( bspr->vaos[ leaf ] ); + + glBindBuffer( GL_ARRAY_BUFFER, bspr->vbos[ leaf * 2 ] ); + glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, bspr->ebos[ leaf ] ); + glEnableVertexAttribArray( at_position ); + glVertexAttribPointer( at_position, 3, GL_FLOAT, GL_FALSE, 0, 0 ); + + glBindBuffer( GL_ARRAY_BUFFER, bspr->vbos[ leaf * 2 + 1 ] ); + glEnableVertexAttribArray( at_colour ); + glVertexAttribPointer( at_colour, 3, GL_FLOAT, GL_FALSE, 0, 0 ); + + glDrawElements( GL_TRIANGLES, bspr->vertex_counts[ leaf ], GL_UNSIGNED_INT, 0 ); +} + +static const glm::mat4 P( glm::perspective( glm::radians( 120.0f ), 640.0f / 480.0f, 0.1f, 10000.0f ) ); + +void bspr_render( const BSPRenderer * const bspr, const glm::vec3 & pos, const GLuint at_position, const GLuint at_colour ) { + const i32 cluster = bspr->bsp->position_to_leaf( pos ).cluster; if( cluster == -1 ) { - for( u32 i = 0; i < bsp.num_leaves; i++ ) { - const BSP_Leaf & leaf = bsp.leaves[ i ]; - render_leaf( bsp, leaf ); + for( u32 i = 0; i < bspr->bsp->num_leaves; i++ ) { + bspr_render_leaf( bspr, i, at_position, at_colour ); } return; } - for( u32 i = 0; i < bsp.num_leaves; i++ ) { - const BSP_Leaf & leaf = bsp.leaves[ i ]; + for( u32 i = 0; i < bspr->bsp->num_leaves; i++ ) { + const BSP_Leaf & leaf = bspr->bsp->leaves[ i ]; const i32 other_cluster = leaf.cluster; - const i32 pvs_idx = cluster * bsp.vis->cluster_size + other_cluster / 8; + const i32 pvs_idx = cluster * bspr->bsp->vis->cluster_size + other_cluster / 8; - if( bsp.vis->pvs[ pvs_idx ] & ( 1 << other_cluster % 8 ) ) { - render_leaf( bsp, leaf ); + if( bspr->bsp->vis->pvs[ pvs_idx ] & ( 1 << other_cluster % 8 ) ) { + bspr_render_leaf( bspr, i, at_position, at_colour ); } } } + +void bspr_destroy( BSPRenderer * const bspr ) { + memarena_clear( bspr->arena ); + + glDeleteBuffers( bspr->bsp->num_leaves, bspr->ebos ); + glDeleteBuffers( bspr->bsp->num_leaves * 2, bspr->vbos ); + glDeleteVertexArrays( bspr->bsp->num_leaves, bspr->vaos ); +} diff --git a/bsp_renderer.h b/bsp_renderer.h @@ -4,14 +4,20 @@ #include <glm/glm.hpp> #include "bsp.h" +#include "memory_arena.h" -class BSP_Renderer { -private: - static void pick_color( const BSP & bsp, const BSP_Face & face ); - static void render_leaf( const BSP & bsp, const BSP_Leaf & leaf ); +struct BSPRenderer { + MemoryArena * arena; + const BSP * bsp; -public: - static void render( const BSP & bsp, const glm::vec3 & camera ); + GLuint * vaos; + GLuint * vbos; + GLuint * ebos; + u32 * vertex_counts; }; +void bspr_init( BSPRenderer * const bspr, MemoryArena * const arena, const BSP * const bsp ); +void bspr_render( const BSPRenderer * const bspr, const glm::vec3 & pos, const GLuint at_position, const GLuint at_colour ); +void bspr_destroy( BSPRenderer * const bspr ); + #endif // _BSP_RENDERER_H_ diff --git a/game.h b/game.h @@ -6,6 +6,8 @@ #include "intrinsics.h" #include "terrain_manager.h" +#include "bsp.h" +#include "bsp_renderer.h" #include "immediate.h" #include "work_queue.h" @@ -14,10 +16,16 @@ struct GameState { glm::vec3 angles; TerrainManager tm; + BSP bsp; + BSPRenderer bspr; + WorkQueue background_tasks; GLuint test_shader; GLuint test_at_position; + GLuint test_at_colour; + GLuint test_un_VP; + ImmediateContext test_immediate; };