summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoraura <nw@moneybot.cc>2026-03-10 02:08:32 +0100
committeraura <nw@moneybot.cc>2026-03-10 02:08:32 +0100
commit31b77ed2e0c037e5718b9ecd06d3941600cc8815 (patch)
treeb15e8a098b772de1be54a1bb90a31992f2a78975 /src
parent8329d42d3e592f4cd42cdfa586e2325ddc76c898 (diff)
wip on 2d batching
Diffstat (limited to 'src')
-rw-r--r--src/editor/view2d.cpp4
-rw-r--r--src/game/raycast.cpp4
-rw-r--r--src/render/gl.cpp2
-rw-r--r--src/render/gl_2d.cpp271
-rw-r--r--src/render/gl_2d.h39
-rw-r--r--src/render/gl_batch.h7
6 files changed, 250 insertions, 77 deletions
diff --git a/src/editor/view2d.cpp b/src/editor/view2d.cpp
index c1ef5ea..7b97687 100644
--- a/src/editor/view2d.cpp
+++ b/src/editor/view2d.cpp
@@ -530,9 +530,9 @@ void gui_editor_2dview_draw_polygons( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) {
} );
if( props->tex )
- gl_textured_polygon( _gui.gl2d_font, vertices.data, vertices.size, props->tex );
+ gl_2d_textured_polygon( _gui.gl2d_font, vertices.data, vertices.size, props->tex );
else
- gl_polygon( _gui.gl2d, vertices.data, vertices.size );
+ gl_2d_polygon( _gui.gl2d, vertices.data, vertices.size );
}
else {
for( U32 i = 0; i < p->vertices.size; ++i ) {
diff --git a/src/game/raycast.cpp b/src/game/raycast.cpp
index 0d2dbe3..ec66b48 100644
--- a/src/game/raycast.cpp
+++ b/src/game/raycast.cpp
@@ -147,9 +147,9 @@ void ray_draw_world2d( GAME_DATA* game, WORLD* world ) {
} );
if( props->tex )
- gl_textured_polygon( game->shaders.gl2d, verts.data, verts.size, props->tex );
+ gl_2d_textured_polygon( game->shaders.gl2d, verts.data, verts.size, props->tex );
else
- gl_polygon( game->shaders.gl2d, verts.data, verts.size );
+ gl_2d_polygon( game->shaders.gl2d, verts.data, verts.size );
}
for( U32 i = 0; i < world->map->walls.size; ++i ) {
diff --git a/src/render/gl.cpp b/src/render/gl.cpp
index c1b6d19..9aef44c 100644
--- a/src/render/gl.cpp
+++ b/src/render/gl.cpp
@@ -484,7 +484,7 @@ STAT gl_endframe( GL_DATA* gl ) {
SDL_GL_SwapWindow( gl->window );
// 1000 fps max be real
- while( true ) {
+ while( 1 ) {
U64 diff = u_tick() - gl->last_tick;
if( diff < TICK_RESOLUTION / 1000 )
usleep( 10 );
diff --git a/src/render/gl_2d.cpp b/src/render/gl_2d.cpp
index b5203b2..506d0da 100644
--- a/src/render/gl_2d.cpp
+++ b/src/render/gl_2d.cpp
@@ -27,6 +27,26 @@ GL_SHADER_PROGRAM* gl_2d_init( GL_DATA* gl, VEC2 screensize, const char* shadern
return program;
}
+void gl_2d_batch_setup( GL_BATCH2D* batch ) {
+ glUseProgram( batch->shader->id );
+ glBindBuffer( GL_ARRAY_BUFFER, batch->vbuffer );
+
+ I32 position = glGetAttribLocation( batch->shader->id, "in_pos" );
+ I32 color = glGetAttribLocation( batch->shader->id, "in_clr" );
+ I32 texcoord = glGetAttribLocation( batch->shader->id, "in_texcoord" );
+ I32 sampler = glGetAttribLocation( batch->shader->id, "in_sampler" );
+
+ glEnableVertexAttribArray( position );
+ glVertexAttribPointer( position, 2, GL_FLOAT, 0, sizeof(VERTEX), 0 );
+ glEnableVertexAttribArray( color );
+ glVertexAttribPointer( color, 4, GL_FLOAT, 0, sizeof(VERTEX), &( (VERTEX*)nullptr)->clr );
+ glEnableVertexAttribArray( texcoord );
+ glVertexAttribPointer( texcoord, 2, GL_FLOAT, 0, sizeof(VERTEX), &( (VERTEX*)nullptr)->uv );
+ glEnableVertexAttribArray( sampler );
+ glVertexAttribPointer( sampler, 1, GL_UNSIGNED_BYTE, 1, sizeof(VERTEX), &( (VERTEX*)nullptr)->sampler );
+ glBindBuffer( GL_ARRAY_BUFFER, 0 );
+}
+
void gl_2d_line( GL_SHADER_PROGRAM* gl2d, VEC2 start, VEC2 end, CLR col ) {
static const U16 order[] = { 0, 1 };
@@ -84,66 +104,6 @@ void gl_2d_rect( GL_SHADER_PROGRAM* gl2d, VEC2 origin, VEC2 dim, CLR col ) {
glDrawElements( GL_LINE_STRIP, 5, GL_UNSIGNED_SHORT, order );
}
-void gl_2d_textured_frect( GL_SHADER_PROGRAM* gl2d, VEC2 origin, VEC2 dim, GL_TEX2D* texture, CLR col, VEC2* uv, F32 rotation ) {
- static const U16 order[] = { 0, 1, 2, 3 };
-
- glUseProgram( gl2d->id );
-
- VERTEX vertices[] = {
- { { origin.x, origin.y }, uv? uv[0] : VEC2{ 0.f, 0.f }, col, 0 },
- { { origin.x + dim.x, origin.y }, uv? uv[1] : VEC2{ 1.f, 0.f }, col, 0 },
- { { origin.x, origin.y + dim.y }, uv? uv[2] : VEC2{ 0.f, 1.f }, col, 0 },
- { { origin.x + dim.x, origin.y + dim.y }, uv? uv[3] : VEC2{ 1.f, 1.f }, col, 0 }
- };
-
- rotation = remainderf( rotation, 360.f );
- if( rotation != 0.f ) {
- F32 rad2dg = rotation * (M_PI / 180.f);
-
- // rotate texture coordinates
- for( U32 i = 0; i < 4; ++i ) {
- F32 x = vertices[i].uv.x - 0.5f;
- F32 y = vertices[i].uv.y - 0.5f;
- vertices[i].uv.x = x * cosf( rad2dg ) - y * sinf( rad2dg ) + 0.5f;
- vertices[i].uv.y = x * sinf( rad2dg ) + y * cosf( rad2dg ) + 0.5f;
- if( vertices[i].uv.x < 0.f ) vertices[i].uv.x = 0.f;
- if( vertices[i].uv.x > 1.f ) vertices[i].uv.x = 1.f;
- }
- }
-
- glBindBuffer( GL_ARRAY_BUFFER, gl2d->gl->vbuffer );
- glBufferData( GL_ARRAY_BUFFER, sizeof(vertices), &vertices[0], GL_DYNAMIC_DRAW );
-
- I32 position = glGetAttribLocation( gl2d->id, "in_pos" );
- I32 color = glGetAttribLocation( gl2d->id, "in_clr" );
- I32 texcoord = glGetAttribLocation( gl2d->id, "in_texcoord" );
- I32 sampler = glGetAttribLocation( gl2d->id, "in_sampler" );
-
- glEnableVertexAttribArray( position );
- glVertexAttribPointer( position, 2, GL_FLOAT, 0, sizeof(VERTEX), 0 );
-
- glEnableVertexAttribArray( color );
- glVertexAttribPointer( color, 4, GL_FLOAT, 0, sizeof(VERTEX), &( (VERTEX*)nullptr)->clr );
-
- glEnableVertexAttribArray( texcoord );
- glVertexAttribPointer( texcoord, 2, GL_FLOAT, 0, sizeof(VERTEX), &( (VERTEX*)nullptr)->uv );
-
- glEnableVertexAttribArray( sampler );
- glVertexAttribPointer( sampler, 1, GL_UNSIGNED_BYTE, 1, sizeof(VERTEX), &( (VERTEX*)nullptr)->sampler );
-
- glActiveTexture( GL_TEXTURE0 );
- glBindTexture( GL_TEXTURE_2D, texture->id );
-
- glBindBuffer( GL_ARRAY_BUFFER, 0 );
-
- glActiveTexture( GL_TEXTURE0 );
- glBindTexture( GL_TEXTURE_2D, texture->id );
-
- // glUniform1f( glGetUniformLocation( gl2d->id, "in_time" ), u_time() );
-
- glDrawElements( GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, order );
- glBindTexture( GL_TEXTURE_2D, 0 );
-}
void gl_2d_frect( GL_SHADER_PROGRAM* gl2d, VEC2 origin, VEC2 dim, CLR col ) {
static const U16 order[] = { 0, 1, 2, 3 };
@@ -281,7 +241,7 @@ void gl_2d_fcircle( GL_SHADER_PROGRAM* gl2d, VEC2 origin, F32 radius, CLR col, U
free( vertices );
}
-void gl_polygon( GL_SHADER_PROGRAM* gl2d, VERTEX* vertices, U32 vertices_count ) {
+void gl_2d_polygon( GL_SHADER_PROGRAM* gl2d, VERTEX* vertices, U32 vertices_count ) {
glUseProgram( gl2d->id );
glBindBuffer( GL_ARRAY_BUFFER, gl2d->gl->vbuffer );
@@ -309,7 +269,7 @@ void gl_polygon( GL_SHADER_PROGRAM* gl2d, VERTEX* vertices, U32 vertices_count )
glDrawElements( GL_TRIANGLE_FAN, vertices_count, GL_UNSIGNED_SHORT, order );
}
-void gl_textured_polygon(
+void gl_2d_textured_polygon(
GL_SHADER_PROGRAM *gl2d,
VERTEX *vertices,
U32 vertices_count,
@@ -340,11 +300,194 @@ void gl_textured_polygon(
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, tex->id );
- glUniform1f( glGetUniformLocation( gl2d->id, "in_time" ), u_time() );
-
U16* order = (U16*)alloca( sizeof(U16) * vertices_count );
for( U32 i = 0; i < vertices_count; i++ )
order[i] = i;
glDrawElements( GL_TRIANGLE_FAN, vertices_count, GL_UNSIGNED_SHORT, order );
}
+
+void gl_2d_textured_frect( GL_SHADER_PROGRAM* gl2d, VEC2 origin, VEC2 dim, GL_TEX2D* texture, CLR col, VEC2* uv, F32 rotation ) {
+ static const U16 order[] = { 0, 1, 2, 3 };
+
+ glUseProgram( gl2d->id );
+
+ VERTEX vertices[] = {
+ { { origin.x, origin.y }, uv? uv[0] : VEC2{ 0.f, 0.f }, col, 0 },
+ { { origin.x + dim.x, origin.y }, uv? uv[1] : VEC2{ 1.f, 0.f }, col, 0 },
+ { { origin.x, origin.y + dim.y }, uv? uv[2] : VEC2{ 0.f, 1.f }, col, 0 },
+ { { origin.x + dim.x, origin.y + dim.y }, uv? uv[3] : VEC2{ 1.f, 1.f }, col, 0 }
+ };
+
+ rotation = remainderf( rotation, 360.f );
+ if( rotation != 0.f ) {
+ F32 rad2dg = rotation * (M_PI / 180.f);
+
+ // rotate texture coordinates
+ for( U32 i = 0; i < 4; ++i ) {
+ F32 x = vertices[i].uv.x - 0.5f;
+ F32 y = vertices[i].uv.y - 0.5f;
+ vertices[i].uv.x = x * cosf( rad2dg ) - y * sinf( rad2dg ) + 0.5f;
+ vertices[i].uv.y = x * sinf( rad2dg ) + y * cosf( rad2dg ) + 0.5f;
+ if( vertices[i].uv.x < 0.f ) vertices[i].uv.x = 0.f;
+ if( vertices[i].uv.x > 1.f ) vertices[i].uv.x = 1.f;
+ }
+ }
+
+ glBindBuffer( GL_ARRAY_BUFFER, gl2d->gl->vbuffer );
+ glBufferData( GL_ARRAY_BUFFER, sizeof(vertices), &vertices[0], GL_DYNAMIC_DRAW );
+
+ I32 position = glGetAttribLocation( gl2d->id, "in_pos" );
+ I32 color = glGetAttribLocation( gl2d->id, "in_clr" );
+ I32 texcoord = glGetAttribLocation( gl2d->id, "in_texcoord" );
+ I32 sampler = glGetAttribLocation( gl2d->id, "in_sampler" );
+
+ glEnableVertexAttribArray( position );
+ glVertexAttribPointer( position, 2, GL_FLOAT, 0, sizeof(VERTEX), 0 );
+
+ glEnableVertexAttribArray( color );
+ glVertexAttribPointer( color, 4, GL_FLOAT, 0, sizeof(VERTEX), &( (VERTEX*)nullptr)->clr );
+
+ glEnableVertexAttribArray( texcoord );
+ glVertexAttribPointer( texcoord, 2, GL_FLOAT, 0, sizeof(VERTEX), &( (VERTEX*)nullptr)->uv );
+
+ glEnableVertexAttribArray( sampler );
+ glVertexAttribPointer( sampler, 1, GL_UNSIGNED_BYTE, 1, sizeof(VERTEX), &( (VERTEX*)nullptr)->sampler );
+
+ glActiveTexture( GL_TEXTURE0 );
+ glBindTexture( GL_TEXTURE_2D, texture->id );
+
+ glBindBuffer( GL_ARRAY_BUFFER, 0 );
+
+ glActiveTexture( GL_TEXTURE0 );
+ glBindTexture( GL_TEXTURE_2D, texture->id );
+
+ // glUniform1f( glGetUniformLocation( gl2d->id, "in_time" ), u_time() );
+
+ glDrawElements( GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, order );
+ glBindTexture( GL_TEXTURE_2D, 0 );
+}
+
+void gl_2d_line( GL_BATCH2D* batch, VEC2 start, VEC2 end, CLR col ) {
+ VERTEX vertices[] = {
+ { .pos = { start.x, start.y }, .clr = col },
+ { .pos = { end.x, end.y }, .clr = col },
+ };
+
+ gl_batch_insert( batch, vertices, 2, 0, GL_LINES );
+}
+
+
+void gl_2d_rect( GL_BATCH2D* batch, VEC2 origin, VEC2 dim, CLR col ) {
+ VERTEX vertices[] = {
+ { .pos = { origin.x , origin.y }, .clr = col },
+ { .pos = { origin.x + dim.x, origin.y }, .clr = col },
+ { .pos = { origin.x + dim.x, origin.y + dim.y }, .clr = col },
+ { .pos = { origin.x , origin.y + dim.y }, .clr = col },
+ { .pos = { origin.x , origin.y }, .clr = col },
+ };
+
+ gl_batch_insert( batch, vertices, 5, 0, GL_LINE_STRIP );
+}
+
+void gl_2d_frect( GL_BATCH2D* batch, VEC2 origin, VEC2 dim, CLR col ) {
+ VERTEX vertices[] = {
+ { .pos = { origin.x, origin.y }, .uv = { 0.f, 0.f }, .clr = col },
+ { .pos = { origin.x + dim.x, origin.y }, .uv = { 1.f, 0.f }, .clr = col },
+ { .pos = { origin.x, origin.y + dim.y }, .uv = { 0.f, 1.f }, .clr = col },
+ { .pos = { origin.x + dim.x, origin.y + dim.y }, .uv = { 1.f, 1.f }, .clr = col }
+ };
+
+ gl_batch_insert( batch, vertices, 4, 0, GL_TRIANGLE_STRIP );
+}
+
+void gl_2d_circle( GL_BATCH2D* batch, VEC2 origin, F32 radius, CLR col, U32 res ) {
+ const F32 step = 360.f / (F32)res;
+ VERTEX* vertices = (VERTEX*)malloc( sizeof( VERTEX ) * (res + 1) );
+ for( U32 i = 0; i < res + 1; ++i ) {
+ VEC2 offset = m_radial_offset( step * ( i == res? 0 : i ), radius );
+
+ vertices[i] = (VERTEX){
+ .pos = {
+ origin.x + offset.x,
+ origin.y + offset.y,
+ },
+ .uv = {},
+ .clr = col
+ };
+ }
+
+ gl_batch_insert( batch, vertices, res + 1, 0, GL_LINE_STRIP );
+}
+
+void gl_2d_fcircle( GL_BATCH2D* batch, VEC2 origin, F32 radius, CLR col, U32 res ) {
+ const F32 step = 360.f / (F32)res;
+
+ VERTEX* vertices = (VERTEX*)malloc( sizeof(VERTEX) * (res * 2) );
+ for( U32 i = 0; i < res * 2; i += 2 ) {
+ VEC2 offset = m_radial_offset( step * i, radius );
+ vertices[i].pos = (VEC2){
+ origin.x,
+ origin.y,
+ };
+
+ vertices[i + 1].pos = (VEC2){
+ origin.x + offset.x,
+ origin.y + offset.y,
+ };
+
+ vertices[i].uv = (VEC2){ 0.5f, 0.5f };
+ vertices[i + 1].uv = (VEC2){
+ 0.5f + ( offset.x * 0.5f ) / radius,
+ 0.5f + ( offset.y * 0.5f ) / radius
+ };
+
+ vertices[i].clr = col;
+ vertices[i + 1].clr = col;
+ };
+
+ gl_batch_insert( batch, vertices, res * 2, 0, GL_TRIANGLE_STRIP );
+}
+
+
+extern void gl_2d_textured_frect(
+ GL_BATCH2D* batch,
+ VEC2 origin,
+ VEC2 dim,
+ GL_TEX2D* texture,
+ CLR col,
+ VEC2* uv,
+ F32 rotation
+) {
+ VERTEX vertices[] = {
+ { { origin.x, origin.y }, uv? uv[0] : VEC2{ 0.f, 0.f }, col, 0 },
+ { { origin.x + dim.x, origin.y }, uv? uv[1] : VEC2{ 1.f, 0.f }, col, 0 },
+ { { origin.x, origin.y + dim.y }, uv? uv[2] : VEC2{ 0.f, 1.f }, col, 0 },
+ { { origin.x + dim.x, origin.y + dim.y }, uv? uv[3] : VEC2{ 1.f, 1.f }, col, 0 }
+ };
+
+ rotation = remainderf( rotation, 360.f );
+ if( rotation != 0.f ) {
+ F32 rad2dg = rotation * (M_PI / 180.f);
+
+ // rotate texture coordinates
+ for( U32 i = 0; i < 4; ++i ) {
+ F32 x = vertices[i].uv.x - 0.5f;
+ F32 y = vertices[i].uv.y - 0.5f;
+ vertices[i].uv.x = x * cosf( rad2dg ) - y * sinf( rad2dg ) + 0.5f;
+ vertices[i].uv.y = x * sinf( rad2dg ) + y * cosf( rad2dg ) + 0.5f;
+ if( vertices[i].uv.x < 0.f ) vertices[i].uv.x = 0.f;
+ if( vertices[i].uv.x > 1.f ) vertices[i].uv.x = 1.f;
+ }
+ }
+
+ gl_batch_insert( batch, vertices, 4, texture, GL_TRIANGLE_FAN );
+}
+
+void gl_2d_polygon( GL_BATCH2D* batch, VERTEX* vertices, U32 vertices_count ) {
+ gl_batch_insert( batch, vertices, vertices_count, 0, GL_TRIANGLE_FAN );
+}
+
+void gl_2d_textured_polygon( GL_BATCH2D* batch, VERTEX* vertices, U32 vertices_count, GL_TEX2D* tex ) {
+ gl_batch_insert( batch, vertices, vertices_count, tex, GL_TRIANGLE_FAN );
+}
diff --git a/src/render/gl_2d.h b/src/render/gl_2d.h
index 9830516..25dbd4d 100644
--- a/src/render/gl_2d.h
+++ b/src/render/gl_2d.h
@@ -1,21 +1,24 @@
#pragma once
#include "gl.h"
+#include "gl_batch.h"
+using GL_BATCH2D = GL_BATCH<VERTEX>;
extern GL_SHADER_PROGRAM* gl_2d_init( GL_DATA* gl, VEC2 screensize, const char* shadername );
-void gl_polygon( GL_SHADER_PROGRAM* gl2d, VERTEX* vertices, U32 vertices_count );
-void gl_textured_polygon(
- GL_SHADER_PROGRAM* gl2d,
- VERTEX* vertices,
- U32 vertices_count,
- GL_TEX2D* tex
-);
+extern void gl_2d_batch_setup( GL_BATCH2D* batch );
extern void gl_2d_line( GL_SHADER_PROGRAM* gl2d, VEC2 start, VEC2 end, CLR col );
extern void gl_2d_rect( GL_SHADER_PROGRAM* gl2d, VEC2 origin, VEC2 dimensions, CLR col );
extern void gl_2d_frect( GL_SHADER_PROGRAM* gl2d, VEC2 origin, VEC2 dimensions, CLR col );
extern void gl_2d_circle( GL_SHADER_PROGRAM* gl2d, VEC2 origin, F32 radius, CLR col, U32 res = 48 );
extern void gl_2d_fcircle( GL_SHADER_PROGRAM* gl2d, VEC2 origin, F32 radius, CLR col, U32 res = 48 );
+extern void gl_2d_polygon( GL_SHADER_PROGRAM* gl2d, VERTEX* vertices, U32 vertices_count );
+extern void gl_2d_textured_polygon(
+ GL_SHADER_PROGRAM* gl2d,
+ VERTEX* vertices,
+ U32 vertices_count,
+ GL_TEX2D* tex
+);
extern void gl_2d_textured_frect(
GL_SHADER_PROGRAM* gl2d,
VEC2 origin,
@@ -25,3 +28,25 @@ extern void gl_2d_textured_frect(
VEC2* uv = 0,
F32 rotation = 0.F
);
+
+extern void gl_2d_line( GL_BATCH2D* batch, VEC2 start, VEC2 end, CLR col );
+extern void gl_2d_rect( GL_BATCH2D* batch, VEC2 origin, VEC2 dimensions, CLR col );
+extern void gl_2d_frect( GL_BATCH2D* batch, VEC2 origin, VEC2 dimensions, CLR col );
+extern void gl_2d_circle( GL_BATCH2D* batch, VEC2 origin, F32 radius, CLR col, U32 res = 48 );
+extern void gl_2d_fcircle( GL_BATCH2D* batch, VEC2 origin, F32 radius, CLR col, U32 res = 48 );
+extern void gl_2d_polygon( GL_BATCH2D* batch, VERTEX* vertices, U32 vertices_count );
+extern void gl_2d_textured_polygon(
+ GL_BATCH2D* batch,
+ VERTEX* vertices,
+ U32 vertices_count,
+ GL_TEX2D* tex
+);
+extern void gl_2d_textured_frect(
+ GL_BATCH2D* batch,
+ VEC2 origin,
+ VEC2 dim,
+ GL_TEX2D* texture,
+ CLR col = { 1.f, 1.f, 1.f, 1.f },
+ VEC2* uv = 0,
+ F32 rotation = 0.F
+);
diff --git a/src/render/gl_batch.h b/src/render/gl_batch.h
index 944521f..12b512f 100644
--- a/src/render/gl_batch.h
+++ b/src/render/gl_batch.h
@@ -133,6 +133,11 @@ inline GL_BATCH_CALL<VERTEX>* gl_batch_get_call( GL_BATCH<VERTEX>* batch, GL_TEX
&& vp_start == last->clip_start && vp_dim == last->viewport_dim
&& clip_start == last->clip_start && clip_dim == last->clip_dim
) {
+ if( !tex ) {
+ *texid = SAMPLER_ID_NONE;
+ return last;
+ }
+
I32 idx = last->textures.idx_of( tex );
if( idx != -1 ) {
*texid = idx;
@@ -187,7 +192,7 @@ inline void gl_batch_insert(
call = gl_batch_get_call( batch, tex, primitive, &texid );
for( U32 i = 0; i < count; ++i ) {
- vertices[i].sampler = (!!tex)? texid : SAMPLER_ID_NONE;
+ vertices[i].sampler = texid;
call->vertices.push( vertices[i] );
}
}