commit 93e95d2192c17cb01df62bf8d3ba7e6893569803 parent daedcbe98bcbb6ac210d089a5b7aa3cdb1973beb Author: Michael Savage <mikejsavage@gmail.com> Date: Tue Sep 15 22:57:15 +0100 Push BTTs to the GPU. Don't do anything with them yet Diffstat:
Makefile | | | 2 | +- |
btt.cc | | | 3 | +++ |
game.h | | | 2 | ++ |
gpubtt.cc | | | 85 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
gpubtt.h | | | 23 | +++++++++++++++++++++++ |
heightmap.h | | | 5 | +++++ |
diff --git a/Makefile b/Makefile @@ -32,7 +32,7 @@ bsp.so: $(BSPOBJS) pp: $(PPOBJS) $(CXX) $^ $(LDFLAGS) -o $@ -btt.so: btt.o heightmap.o memory_arena.o work_queue.o stb_image.o immediate.o +btt.so: btt.o heightmap.o memory_arena.o work_queue.o stb_image.o immediate.o gpubtt.o $(CXX) $^ $(LDFLAGS) -o $@ -shared clean: diff --git a/btt.cc b/btt.cc @@ -230,6 +230,9 @@ extern "C" GAME_INIT( game_init ) { state->test_at_normal, state->test_at_lit ); state->btt = btt_from_heightmap( &state->hm, &mem->persistent_arena ); + const OffsetHeightmap ohm = { state->hm, 0, 0 }; + gpubtt_init( &mem->persistent_arena, &state->gpubtt, &ohm, state->btt, state->test_at_position ); + glClearColor( 0, 0.5, 0.7, 1 ); } diff --git a/game.h b/game.h @@ -67,6 +67,7 @@ #include "assets.h" #include "terrain_manager.h" #include "btt.h" +#include "gpubtt.h" #include "heightmap.h" #include "bsp.h" #include "bsp_renderer.h" @@ -107,6 +108,7 @@ struct GameState { GLint test_outline_un_vp; BTTs btt; + GPUBTT gpubtt; Heightmap hm; ImmediateContext test_immediate; diff --git a/gpubtt.cc b/gpubtt.cc @@ -0,0 +1,85 @@ +#include "platform_opengl.h" +#include <glm/glm.hpp> +#include <glm/gtc/matrix_transform.hpp> +#include <glm/gtc/type_ptr.hpp> + +#include "intrinsics.h" +#include "memory_arena.h" +#include "btt.h" +#include "heightmap.h" +#include "gpubtt.h" + +static u32 btt_count_leaves( const BTT * const btt ) { + if( btt->left ) { + return btt_count_leaves( btt->left ) + btt_count_leaves( btt->right ); + } + + return 1; +} + +static void gpubtt_build( + glm::vec3 * const verts, u32 * i, + const OffsetHeightmap * ohm, const BTT * btt, + const glm::ivec2 iv0, const glm::ivec2 iv1, const glm::ivec2 iv2 +) { + const glm::vec3 offset( ohm->x_offset, ohm->y_offset, 0.0f ); + + const glm::vec3 v0( ohm->hm.point( v0.x, v0.y ) + offset ); + const glm::vec3 v1( ohm->hm.point( v1.x, v1.y ) + offset ); + const glm::vec3 v2( ohm->hm.point( v2.x, v2.y ) + offset ); + + if( btt->left ) { + const glm::ivec2 mid = ( iv0 + iv2 ) / 2; + + gpubtt_build( verts, i, ohm, btt->left, iv1, mid, iv0 ); + gpubtt_build( verts, i, ohm, btt->right, iv2, mid, iv1 ); + } + else { + verts[ *i++ ] = v0; + verts[ *i++ ] = v1; + verts[ *i++ ] = v2; + } +} + +void gpubtt_init( + MemoryArena * const mem, GPUBTT * const gpubtt, + const OffsetHeightmap * const ohm, const BTTs btts, + const GLuint at_position +) { + MemoryArenaCheckpoint cp = memarena_checkpoint( mem ); + + const u32 num_leaves = btt_count_leaves( btts.left_root ) + + btt_count_leaves( btts.right_root ); + + glm::vec3 * const verts = memarena_push_many( mem, glm::vec3, num_leaves * 3 ); + u32 i = 0; + + gpubtt_build( verts, &i, ohm, btts.left_root, glm::ivec2( 0, 0 ), glm::ivec2( 0, ohm->hm.h - 1 ), glm::ivec2( ohm->hm.w - 1, ohm->hm.h - 1 ) ); + gpubtt_build( verts, &i, ohm, btts.right_root, glm::ivec2( ohm->hm.w - 1, ohm->hm.h - 1 ), glm::ivec2( ohm->hm.w - 1, 0 ), glm::ivec2( 0, 0 ) ); + + glGenVertexArrays( 1, &gpubtt->vao ); + glBindVertexArray( gpubtt->vao ); + + glGenBuffers( 1, &gpubtt->vbo_verts ); + glBindBuffer( GL_ARRAY_BUFFER, gpubtt->vbo_verts ); + glBufferData( GL_ARRAY_BUFFER, num_leaves * sizeof( GLfloat ) * 3, verts, GL_STATIC_DRAW ); + glEnableVertexAttribArray( at_position ); + glVertexAttribPointer( at_position, 3, GL_FLOAT, GL_FALSE, 0, 0 ); + + glBindVertexArray( 0 ); + + gpubtt->num_verts = i; + + memarena_restore( mem, &cp ); +} + +void gpubtt_destroy( GPUBTT * const gpubtt ) { + glDeleteBuffers( 1, &gpubtt->vbo_verts ); + glDeleteVertexArrays( 1, &gpubtt->vao ); +} + +void gpubtt_render( const GPUBTT * const gpubtt ) { + glBindVertexArray( gpubtt->vao ); + glDrawElements( GL_TRIANGLES, gpubtt->num_verts, GL_UNSIGNED_INT, 0 ); + glBindVertexArray( 0 ); +} diff --git a/gpubtt.h b/gpubtt.h @@ -0,0 +1,23 @@ +#ifndef _GPUBTT_H_ +#define _GPUBTT_H_ + +#include "platform_opengl.h" + +#include "heightmap.h" +#include "btt.h" + +struct GPUBTT { + GLuint vao; + GLuint vbo_verts; + u32 num_verts; +}; + +void gpubtt_init( MemoryArena * const mem, GPUBTT * const gpubtt, + const OffsetHeightmap * const ohm, const BTTs btts, + const GLuint at_position ); + +void gpubtt_destroy( GPUBTT * const gpubtt ); + +void gpubtt_render( const GPUBTT * const gpubtt ); + +#endif // _GPUBTT_H_ diff --git a/heightmap.h b/heightmap.h @@ -31,4 +31,9 @@ public: void render() const; }; +struct OffsetHeightmap { + Heightmap hm; + float x_offset, y_offset; +}; + #endif // _HEIGHTMAP_H_