summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraura <nw@moneybot.cc>2026-03-10 05:18:33 +0100
committeraura <nw@moneybot.cc>2026-03-10 05:18:33 +0100
commit30151d75dddd651faa1b27148a052ced7d0f190a (patch)
tree30b9374d59ecdd83296f7a2b7aa008340b95daf5
parent31b77ed2e0c037e5718b9ecd06d3941600cc8815 (diff)
2d batch rendering
-rw-r--r--src/editor/editor_infobox.cpp2
-rw-r--r--src/editor/texturepicker.cpp12
-rw-r--r--src/editor/view2d.cpp8
-rw-r--r--src/editor/view3d.cpp76
-rw-r--r--src/game.cpp3
-rw-r--r--src/game.h2
-rw-r--r--src/gui/base.cpp26
-rw-r--r--src/gui/base.h9
-rw-r--r--src/gui/window.cpp8
-rw-r--r--src/render/gl_2d.cpp63
-rw-r--r--src/render/gl_2d_font.cpp67
-rw-r--r--src/render/gl_2d_font.h3
-rw-r--r--src/render/gl_batch.h37
13 files changed, 168 insertions, 148 deletions
diff --git a/src/editor/editor_infobox.cpp b/src/editor/editor_infobox.cpp
index 931d9ea..9f9060d 100644
--- a/src/editor/editor_infobox.cpp
+++ b/src/editor/editor_infobox.cpp
@@ -92,7 +92,7 @@ static void gui_editor_infobox_draw_assets( GUI_EDITOR_INFOBOX* box, I32 panel_x
gui_draw_frect( tx + 1, ty + 1, EDITOR_ASSETS_THUMB - 2, EDITOR_ASSETS_THUMB - 2, ui_clr.bg_alt );
gui_draw_str( tx + EDITOR_ASSETS_THUMB / 2, ty + 4, ALIGN_C, FNT_JPN12, ui_clr.txt, "m" );
} else if( p->tex ) {
- gl_2d_textured_frect( _gui.gl2d_font, { (F32)(tx + 1), (F32)(ty + 1) }, { (F32)(EDITOR_ASSETS_THUMB - 2), (F32)(EDITOR_ASSETS_THUMB - 2) }, p->tex );
+ gl_2d_textured_frect( _gui.batch, { (F32)(tx + 1), (F32)(ty + 1) }, { (F32)(EDITOR_ASSETS_THUMB - 2), (F32)(EDITOR_ASSETS_THUMB - 2) }, p->tex );
} else {
gui_draw_frect( tx + 1, ty + 1, EDITOR_ASSETS_THUMB - 2, EDITOR_ASSETS_THUMB - 2, p->clr );
}
diff --git a/src/editor/texturepicker.cpp b/src/editor/texturepicker.cpp
index a24e955..621f0c2 100644
--- a/src/editor/texturepicker.cpp
+++ b/src/editor/texturepicker.cpp
@@ -90,7 +90,7 @@ void gui_editor_texturepicker_draw_files( GUI_EDITOR_TEXTUREPICKER* wnd ) {
gui_draw_frect( tx - 1, ty - 1, size + 2, size + 2, clr );
gui_draw_frect( tx, ty, size, size, clr );
gl_2d_textured_frect(
- _gui.gl2d_font,
+ _gui.batch,
{ (F32)tx, (F32)ty },
{ (F32)size, (F32)size },
tex,
@@ -144,7 +144,7 @@ void gui_editor_texturepicker_draw_fn( void* ptr ) {
void gui_editor_textureview_delete_textures( GUI_EDITOR_TEXTUREPICKER* wnd ) {
wnd->textures.each( fn( GL_TEX2D** ptr ) {
GL_TEX2D* tex = *ptr;
- gl_texture_destroy( _gui.gl2d->gl, tex );
+ gl_texture_destroy( _gui.batch->gl, tex );
} );
wnd->textures.clear();
@@ -155,7 +155,7 @@ void gui_editor_texturepicker_load_texture( void* ptr ) {
FILE_ENTRY* f = &wnd->files[wnd->curload];
const char* name = assets_abspath( f->name );
- GL_TEX2D* tex = gl_texture_from_file( _gui.gl2d->gl, name );
+ GL_TEX2D* tex = gl_texture_from_file( _gui.batch->gl, name );
if( !tex ) {
dlog( "gui_editor_textureview_create_textures() : error creating texture %s", name );
return;
@@ -170,7 +170,7 @@ void gui_editor_texturepicker_load_texture( void* ptr ) {
void gui_editor_textureview_create_textures( GUI_EDITOR_TEXTUREPICKER* wnd ) {
wnd->curload = 0;
- GL_TEX2D* emptytex = gl_texture_create( _gui.gl2d->gl, "" );
+ GL_TEX2D* emptytex = gl_texture_create( _gui.batch->gl, "" );
strcpy( emptytex->name, "none" );
emptytex->width = emptytex->height = 1;
@@ -189,7 +189,7 @@ void gui_editor_textureview_accept( GUI_EDITOR_TEXTUREPICKER* wnd ) {
if( !isnone && tex == wnd->curselect )
return;
- gl_texture_destroy( _gui.gl2d->gl, tex );
+ gl_texture_destroy( _gui.batch->gl, tex );
} );
if( !isnone ) {
@@ -198,7 +198,7 @@ void gui_editor_textureview_accept( GUI_EDITOR_TEXTUREPICKER* wnd ) {
GL_TEX2D* tex = map_find_texture( editor->map, name );
*wnd->target = tex;
- gl_texture_destroy( _gui.gl2d->gl, wnd->curselect );
+ gl_texture_destroy( _gui.batch->gl, wnd->curselect );
} else {
*wnd->target = wnd->curselect;
}
diff --git a/src/editor/view2d.cpp b/src/editor/view2d.cpp
index 7b97687..8dbe42c 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_2d_textured_polygon( _gui.gl2d_font, vertices.data, vertices.size, props->tex );
+ gl_2d_textured_polygon( _gui.batch, vertices.data, vertices.size, props->tex );
else
- gl_2d_polygon( _gui.gl2d, vertices.data, vertices.size );
+ gl_2d_polygon( _gui.batch, vertices.data, vertices.size );
}
else {
for( U32 i = 0; i < p->vertices.size; ++i ) {
@@ -632,7 +632,7 @@ void gui_editor_2dview_draw_sprites( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) {
else {
gl_2d_frect(
- _gui.gl2d,
+ _gui.batch,
{ (F32)((I32)pos.x - w/2), (F32)((I32)pos.y - h/2) },
{ (F32)w, (F32)h },
s->clr
@@ -640,7 +640,7 @@ void gui_editor_2dview_draw_sprites( GUI_EDITOR_2DVIEW* view, I32 x, I32 y ) {
}
if( s->tex ) {
gl_2d_textured_frect(
- _gui.gl2d_font,
+ _gui.batch,
{ (F32)((I32)pos.x - w/2), (F32)((I32)pos.y - h/2) },
{ (F32)w, (F32)h },
s->tex,
diff --git a/src/editor/view3d.cpp b/src/editor/view3d.cpp
index 292760a..cdec211 100644
--- a/src/editor/view3d.cpp
+++ b/src/editor/view3d.cpp
@@ -1,5 +1,7 @@
#include "editor.h"
+#include "../render/gl_2d_font.h"
+
#include "../game/objlist.h"
#include "../game/world/draw.h"
#include "../game/world/bsp_draw.h"
@@ -14,37 +16,43 @@ void gui_editor_3dview_draw_showpos( GUI_EDITOR_3DVIEW* view ) {
VEC3 pos = objl->pl->pos;
F32 speed = vec_len( objl->pl->velocity );
-
- gui_draw_str(
- x + view->w - 2, y + 2,
- ALIGN_R,
- FNT_JPN12,
- ui_clr.txt,
- "pos: %.02f %.02f %.02f (%.02f)",
- pos.x, pos.y, pos.z, speed
+ STR posstr = STR( "pos: %.02f %.02f %.02f (%.02f)", pos.x, pos.y, pos.z, speed );
+ STR rotstr = STR( "rot: %.02f %.02f", objl->pl->rot.y, objl->pl->rot.x );
+
+ VEC2 posdim = gl_font_dim( _gui.fonts.jpn12.glfnt, posstr );
+ VEC2 rotdim = gl_font_dim( _gui.fonts.jpn12.glfnt, rotstr );
+
+ gl_font_draw(
+ _gui.fonts.jpn12.glfnt,
+ _gui.batch->shader,
+ VEC2( x + view->w - 2 - posdim.x, y + 2 ),
+ posstr,
+ ui_clr.txt
);
-
- gui_draw_str(
- x + view->w - 2, y + 18,
- ALIGN_R,
- FNT_JPN12,
- ui_clr.txt,
- "rot: %.02f %.02f",
- objl->pl->rot.y,
- objl->pl->rot.x
+ gl_font_draw(
+ _gui.fonts.jpn12.glfnt,
+ _gui.batch->shader,
+ VEC2( x + view->w - 2 - rotdim.x, y + 18 ),
+ rotstr,
+ ui_clr.txt
);
-
if( input.mouselock ) {
- gui_draw_str(
- x + 2, y + 2,
- ALIGN_L,
- FNT_JPN12,
- ui_clr.txt,
- "[capturing mouse]"
+ gl_font_draw(
+ _gui.fonts.jpn12.glfnt,
+ _gui.batch->shader,
+ VEC2( x + 2, y + 2 ),
+ "[capturing mouse]",
+ ui_clr.txt
);
}
}
+struct WORLD_DRAW_CB_DATA {
+ VEC2 wnd;
+ VEC2 winsize;
+ GUI_EDITOR_3DVIEW* view;
+};
+
void gui_editor_3dview_draw_fn( void* ptr ) {
GUI_EDITOR_3DVIEW* view = (GUI_EDITOR_3DVIEW*)ptr;
@@ -59,14 +67,25 @@ void gui_editor_3dview_draw_fn( void* ptr ) {
VEC2 wnd = { (F32)x, (F32)y };
VEC2 winsize = { (F32)view->w, (F32)view->h };
+ static WORLD_DRAW_CB_DATA data;
+ data = { wnd, winsize, view };
CLR col = gui_is_fg_window( view )? ui_clr.border : ui_clr.border_inactive;
gui_draw_frect( x-1, y-1, view->w+2, view->h+2, col );
gui_draw_frect( x, y, view->w, view->h, CLR::BLACK() );
- if( editor->drawbsp && editor->map->bsp )
- bsp_draw( editor->map->bsp, editor->game, wnd, winsize );
- else
- world_draw( editor->game, objl->world, wnd, winsize );
+ if( editor->drawbsp && editor->map->bsp ) {
+ gui_push_callback( &data, fn( void* data ) {
+ WORLD_DRAW_CB_DATA* d = (WORLD_DRAW_CB_DATA*)data;
+ bsp_draw( editor->map->bsp, editor->game, d->wnd, d->winsize );
+ gui_editor_3dview_draw_showpos( d->view);
+ } );
+ } else {
+ gui_push_callback( &data, fn( void* data ) {
+ WORLD_DRAW_CB_DATA* d = (WORLD_DRAW_CB_DATA*)data;
+ world_draw( editor->game, objl->world, d->wnd, d->winsize );
+ gui_editor_3dview_draw_showpos( d->view );
+ } );
+ }
gui_draw_push_clip( x, y, view->w, view->h );
view->children.each( fn( GUI_BASE** childptr ) {
@@ -77,7 +96,6 @@ void gui_editor_3dview_draw_fn( void* ptr ) {
else dlog( "gui_view_draw_fn(): child %p no draw_fn\n", child );
} );
gui_draw_pop_clip();
- gui_editor_3dview_draw_showpos( view );
}
void gui_editor_3dview_input_fn( void* ptr ) {
diff --git a/src/game.cpp b/src/game.cpp
index a0452db..092da55 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -58,6 +58,7 @@ GAME_DATA* game_init( GL_DATA* gl ) {
}
void game_create_batches( GAME_DATA *game ) {
+ game->render.batch_2d = gl_batch_create( game->gl, game->shaders.gl2d, &gl_2d_batch_setup );
game->render.batch_3d = gl_batch_create( game->gl, game->shaders.gl3d, &gl_3d_batch_setup );
}
@@ -222,5 +223,7 @@ void game_on_tick( GAME_DATA* game ) { _profiled
}
void game_destroy( GAME_DATA *game ) {
+ gl_batch_destroy( game->render.batch_2d );
+ gl_batch_destroy( game->render.batch_3d );
free( game );
}
diff --git a/src/game.h b/src/game.h
index f0e1957..862234b 100644
--- a/src/game.h
+++ b/src/game.h
@@ -5,6 +5,7 @@
#include "game/assets.h"
#include "render/gl.h"
+#include "render/gl_2d.h"
#include "render/gl_3d.h"
#ifdef IS_EDITOR
@@ -27,6 +28,7 @@ typedef struct {
typedef struct {
GL_BATCH3D* batch_3d;
+ GL_BATCH2D* batch_2d;
} GAME_RENDER;
typedef struct {
diff --git a/src/gui/base.cpp b/src/gui/base.cpp
index 1e8a493..79299de 100644
--- a/src/gui/base.cpp
+++ b/src/gui/base.cpp
@@ -37,8 +37,8 @@ void gui_end() {
}
void gui_draw( GAME_DATA* game ) {
- _gui.gl2d = game->shaders.gl2d;
- _gui.gl2d_font = game->shaders.gl2d;
+ _gui.batch = game->render.batch_2d;
+ gl_batch_empty( _gui.batch );
_gui.windows.each( fn( GUI_WINDOW** w ) {
GUI_WINDOW* wnd = *w;
@@ -46,6 +46,8 @@ void gui_draw( GAME_DATA* game ) {
wnd->draw_fn( wnd );
} );
+
+ gl_batch_draw( _gui.batch );
}
void gui_input( GAME_DATA* game ) {
@@ -59,10 +61,10 @@ void gui_input( GAME_DATA* game ) {
}
void gui_onframe( GAME_DATA* game ) { _profiled
- gui_run_callbacks();
-
gui_input( game );
gui_draw( game );
+
+ gui_run_callbacks();
}
void gui_free( GUI_BASE* node ) {
@@ -254,15 +256,15 @@ void gui_base_input_fn( void* ptr ) {
}
void gui_draw_frect( I32 x, I32 y, I32 w, I32 h, CLR col ) {
- gl_2d_frect( _gui.gl2d, { (F32)x, (F32)y }, { (F32)w, (F32)h }, col );
+ gl_2d_frect( _gui.batch, { (F32)x, (F32)y }, { (F32)w, (F32)h }, col );
}
void gui_draw_rect( I32 x, I32 y, I32 w, I32 h, CLR col ) {
- gl_2d_rect( _gui.gl2d, { (F32)x, (F32)y }, { (F32)w, (F32)h }, col );
+ gl_2d_rect( _gui.batch, { (F32)x, (F32)y }, { (F32)w, (F32)h }, col );
}
void gui_draw_line( I32 x0, I32 y0, I32 x1, I32 y1, CLR col ) {
- gl_2d_line( _gui.gl2d, { (F32)x0, (F32)y0 }, { (F32)x1, (F32)y1 }, col );
+ gl_2d_line( _gui.batch, { (F32)x0, (F32)y0 }, { (F32)x1, (F32)y1 }, col );
}
GL_FONT* gui_font_from_idx( U32 fnt ) {
@@ -292,7 +294,7 @@ void gui_draw_str_internal( I32 x, I32 y, U8 align, U32 fnt, CLR col, const char
case ALIGN_C: x -= (I32)( w * 0.5f ); break;
}
- gl_font_draw( pfnt, _gui.gl2d_font, { (F32)x, (F32)y }, str, col );
+ gl_font_draw( pfnt, _gui.batch, { (F32)x, (F32)y }, str, col );
}
void gui_draw_str( I32 x, I32 y, U8 align, U32 fnt, CLR col, const char* fmt, ... ) {
@@ -326,7 +328,7 @@ void gui_draw_get_str_bounds( I32* w, I32* h, U32 fnt, const char *fmt, ... ) {
void gui_draw_get_clip( I32 *x, I32 *y, I32 *w, I32 *h ) {
VEC2 start, dim;
- gl_get_clip( _gui.gl2d->gl, &start, &dim );
+ gl_get_clip( _gui.batch->gl, &start, &dim );
if( x ) *x = (I32)start.x;
if( y ) *y = (I32)start.y;
@@ -341,11 +343,11 @@ void gui_draw_set_clip( I32 x, I32 y, I32 w, I32 h ) {
dim.x = (F32)w;
dim.y = (F32)h;
- gl_set_clip( _gui.gl2d->gl, start, dim );
+ gl_set_clip( _gui.batch->gl, start, dim );
}
void gui_draw_reset_clip() {
- gl_reset_clip( _gui.gl2d->gl );
+ gl_reset_clip( _gui.batch->gl );
}
void gui_draw_push_clip( I32 x, I32 y, I32 w, I32 h ) {
@@ -397,7 +399,7 @@ U8 gui_key_down( U8 key ) {
}
F32 gui_frametime() {
- return _gui.gl2d->gl->frametime;
+ return _gui.batch->gl->frametime;
}
F32 gui_time() {
diff --git a/src/gui/base.h b/src/gui/base.h
index 73816a7..e62c66a 100644
--- a/src/gui/base.h
+++ b/src/gui/base.h
@@ -1,6 +1,6 @@
#pragma once
-#include "../util/color.h"
-#include "../util/allocator.h"
+#include "../render/gl_2d.h"
+#include <functional>
// ======================================= [ colorscheme ] ========================================
@@ -46,7 +46,7 @@ extern U8 gui_is_fg_window( struct GUI_BASE* node ); // 1 if pa
// ======================================= [ components ] =========================================
-typedef void( *GUI_CALLBACK )( void* ptr );
+using GUI_CALLBACK = std::function<void( void* )>;
struct GUI_LIST_ENTRY {
I32 val;
char title[256];
@@ -320,8 +320,7 @@ struct __gui_internal {
} fonts;
// draw stuff below
- struct GL_SHADER_PROGRAM* gl2d;
- struct GL_SHADER_PROGRAM* gl2d_font;
+ GL_BATCH2D* batch;
};
void __gui_internal_vectorinput_init(
diff --git a/src/gui/window.cpp b/src/gui/window.cpp
index 0183d8c..500cb3d 100644
--- a/src/gui/window.cpp
+++ b/src/gui/window.cpp
@@ -83,12 +83,12 @@ void gui_title_input_fn( void* ptr ) {
w->x = mx - t->xoff;
w->y = my - t->yoff;
- if( w->x > _gui.gl2d->gl->canvas_size[0] - 5 )
- w->x = _gui.gl2d->gl->canvas_size[0] - 5;
+ if( w->x > _gui.batch->gl->canvas_size[0] - 5 )
+ w->x = _gui.batch->gl->canvas_size[0] - 5;
if( w->x + w->w < 5 )
w->x = 5 - w->w;
- if( w->y > _gui.gl2d->gl->canvas_size[1] - 5 )
- w->y = _gui.gl2d->gl->canvas_size[1] - 5;
+ if( w->y > _gui.batch->gl->canvas_size[1] - 5 )
+ w->y = _gui.batch->gl->canvas_size[1] - 5;
if( w->y + w->h < 5 )
w->y = 5 - w->h;
}
diff --git a/src/render/gl_2d.cpp b/src/render/gl_2d.cpp
index 506d0da..bc55cae 100644
--- a/src/render/gl_2d.cpp
+++ b/src/render/gl_2d.cpp
@@ -382,12 +382,15 @@ 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 }, .clr = col },
+ { .pos = { origin.x + dim.x, origin.y + dim.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 + dim.y }, .clr = col },
{ .pos = { origin.x , origin.y }, .clr = col },
};
- gl_batch_insert( batch, vertices, 5, 0, GL_LINE_STRIP );
+ gl_batch_insert( batch, vertices, 8, 0, GL_LINES );
}
void gl_2d_frect( GL_BATCH2D* batch, VEC2 origin, VEC2 dim, CLR col ) {
@@ -395,19 +398,24 @@ void gl_2d_frect( GL_BATCH2D* batch, VEC2 origin, VEC2 dim, CLR col ) {
{ .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 }
+ { .pos = { origin.x + dim.x, origin.y }, .uv = { 1.f, 0.f }, .clr = col },
+ { .pos = { origin.x + dim.x, origin.y + dim.y }, .uv = { 1.f, 1.f }, .clr = col },
+ { .pos = { origin.x , origin.y + dim.y }, .uv = { 0.f, 1.f }, .clr = col }
};
- gl_batch_insert( batch, vertices, 4, 0, GL_TRIANGLE_STRIP );
+ gl_batch_insert( batch, vertices, 6, 0, GL_TRIANGLES );
}
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 );
+ LIST<VERTEX> vertices;
+ vertices.reserve( res * 2 );
+ VEC2 prev;
+ for( U32 i = 0; i < res * 2; i += 2 ) {
+ VEC2 offset = m_radial_offset( step * i, radius );
+ VEC2 offset_next = m_radial_offset( step * ( i + 1 ), radius );
- vertices[i] = (VERTEX){
+ vertices.data[i] = (VERTEX){
.pos = {
origin.x + offset.x,
origin.y + offset.y,
@@ -415,17 +423,26 @@ void gl_2d_circle( GL_BATCH2D* batch, VEC2 origin, F32 radius, CLR col, U32 res
.uv = {},
.clr = col
};
+ vertices.data[i+1] = (VERTEX){
+ .pos = {
+ origin.x + offset_next.x,
+ origin.y + offset_next.y,
+ },
+ .uv = {},
+ .clr = col
+ };
}
- gl_batch_insert( batch, vertices, res + 1, 0, GL_LINE_STRIP );
+ gl_batch_insert( batch, vertices.data, vertices.size, 0, GL_LINES );
}
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 ) {
+ VERTEX* vertices = (VERTEX*)malloc( sizeof(VERTEX) * (res * 3) );
+ for( U32 i = 0; i < res * 3; i += 3 ) {
VEC2 offset = m_radial_offset( step * i, radius );
+ VEC2 offset_next = m_radial_offset( step * (i + 1), radius );
vertices[i].pos = (VEC2){
origin.x,
origin.y,
@@ -436,17 +453,27 @@ void gl_2d_fcircle( GL_BATCH2D* batch, VEC2 origin, F32 radius, CLR col, U32 res
origin.y + offset.y,
};
+ vertices[i + 2].pos = (VEC2){
+ origin.x + offset_next.x,
+ origin.y + offset_next.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 + 2].uv = (VEC2){
+ 0.5f + ( offset_next.x * 0.5f ) / radius,
+ 0.5f + ( offset_next.y * 0.5f ) / radius
+ };
vertices[i].clr = col;
vertices[i + 1].clr = col;
+ vertices[i + 2].clr = col;
};
- gl_batch_insert( batch, vertices, res * 2, 0, GL_TRIANGLE_STRIP );
+ gl_batch_insert( batch, vertices, res * 3, 0, GL_TRIANGLES );
}
@@ -460,10 +487,12 @@ extern void gl_2d_textured_frect(
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 }
+ { .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 }, .uv = { 1.f, 0.f }, .clr = col },
+ { .pos = { origin.x + dim.x, origin.y + dim.y }, .uv = { 1.f, 1.f }, .clr = col },
+ { .pos = { origin.x , origin.y + dim.y }, .uv = { 0.f, 1.f }, .clr = col }
};
rotation = remainderf( rotation, 360.f );
@@ -471,7 +500,7 @@ extern void gl_2d_textured_frect(
F32 rad2dg = rotation * (M_PI / 180.f);
// rotate texture coordinates
- for( U32 i = 0; i < 4; ++i ) {
+ for( U32 i = 0; i < 6; ++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;
@@ -481,7 +510,7 @@ extern void gl_2d_textured_frect(
}
}
- gl_batch_insert( batch, vertices, 4, texture, GL_TRIANGLE_FAN );
+ gl_batch_insert( batch, vertices, 6, texture, GL_TRIANGLES );
}
void gl_2d_polygon( GL_BATCH2D* batch, VERTEX* vertices, U32 vertices_count ) {
diff --git a/src/render/gl_2d_font.cpp b/src/render/gl_2d_font.cpp
index 10ae71a..6533dce 100644
--- a/src/render/gl_2d_font.cpp
+++ b/src/render/gl_2d_font.cpp
@@ -145,7 +145,6 @@ void gl_font_calc_vertices_uvs(
F32 _scale,
VERTEX* vertices,
U16* indices,
- VEC2* coords,
CLR clr
) {
U32 len = (U32)strlen( text );
@@ -199,13 +198,12 @@ void gl_font_calc_vertices_uvs(
}
}
-void gl_font_draw( GL_FONT* font, GL_SHADER_PROGRAM* shader, VEC2 origin, const char* text, CLR clr, F32 _scale ) {
+void gl_font_draw( GL_FONT* font, GL_SHADER_PROGRAM* shader, VEC2 pos, const char* text, CLR clr, F32 _scale ) {
U32 len = strlen( text );
VERTEX* vertices = (VERTEX*)malloc( sizeof(VERTEX) * 6 * len );
U16* indices = (U16*)malloc( sizeof(U16) * 6 * len );
- VEC2* coords = (VEC2*)malloc( sizeof(VEC2) * 6 * len );
- gl_font_calc_vertices_uvs( font, origin, text, _scale, vertices, indices, coords, clr );
+ gl_font_calc_vertices_uvs( font, pos, text, _scale, vertices, indices, clr );
glUseProgram( shader->id );
glBindBuffer( GL_ARRAY_BUFFER, shader->gl->vbuffer );
@@ -242,75 +240,20 @@ void gl_font_draw( GL_FONT* font, GL_SHADER_PROGRAM* shader, VEC2 origin, const
free( vertices );
free( indices );
- free( coords );
}
-void gl_font_textured(
- GL_FONT* font,
- GL_SHADER_PROGRAM* shader,
- VEC2 origin,
- const char* text,
- GL_TEX2D* tex,
- CLR clr,
- F32 _scale
-) {
+void gl_font_draw( GL_FONT* font, GL_BATCH2D* batch, VEC2 pos, const char* text, CLR clr, F32 _scale ) {
U32 len = strlen( text );
- struct FONT_CUSTOM_VERTEX {
- VERTEX v;
- VEC2 uv2;
- };
-
- FONT_CUSTOM_VERTEX* custom_vertices = (FONT_CUSTOM_VERTEX*)malloc( sizeof(FONT_CUSTOM_VERTEX) * 6 * len );
VERTEX* vertices = (VERTEX*)malloc( sizeof(VERTEX) * 6 * len );
U16* indices = (U16*)malloc( sizeof(U16) * 6 * len );
- VEC2* coords = (VEC2*)malloc( sizeof(VEC2) * 6 * len );
-
- gl_font_calc_vertices_uvs( font, origin, text, _scale, vertices, indices, coords, clr );
- VEC2 dim = gl_font_dim( font, text, _scale );
-
- for( U32 i = 0; i < len * 6; ++i ) {
- custom_vertices[i].v = vertices[i];
- custom_vertices[i].uv2 = {
- (vertices[i].pos.x - origin.x) / dim.x,
- (vertices[i].pos.y - origin.y - vertices[0].pos.y) / dim.y
- };
- }
- glUseProgram( shader->id );
-
- glBindBuffer( GL_ARRAY_BUFFER, shader->gl->vbuffer );
- glBufferData( GL_ARRAY_BUFFER, sizeof(FONT_CUSTOM_VERTEX) * 6 * len, custom_vertices, GL_STATIC_DRAW );
- I32 position = glGetAttribLocation( shader->id, "in_pos" );
- glEnableVertexAttribArray( position );
- glVertexAttribPointer( position, 2, GL_FLOAT, 0, sizeof(FONT_CUSTOM_VERTEX), 0 );
-
- I32 texcoord = glGetAttribLocation( shader->id, "in_texcoord" );
- glEnableVertexAttribArray( texcoord );
- glVertexAttribPointer( texcoord, 2, GL_FLOAT, 0, sizeof(FONT_CUSTOM_VERTEX), (void*)(sizeof(VEC2)) );
-
- I32 texcoord2 = glGetAttribLocation( shader->id, "in_texcoord2" );
- glEnableVertexAttribArray( texcoord2 );
- glVertexAttribPointer( texcoord2, 2, GL_FLOAT, 0, sizeof(FONT_CUSTOM_VERTEX), (void*)(sizeof(VERTEX)) );
-
- glBindBuffer( GL_ARRAY_BUFFER, 0 );
-
- I32 color = glGetUniformLocation( shader->id, "in_color" );
- glUniform4fv( color, 1, (F32*)&clr );
-
- glActiveTexture( GL_TEXTURE0 );
- glUniform1iv( glGetUniformLocation( shader->id, "in_sampler" ), 0, 0 );
- glBindTexture( GL_TEXTURE_2D, font->atlas->id );
-
- glDrawElements( GL_TRIANGLES, len * 6, GL_UNSIGNED_SHORT, indices );
- glBindTexture( GL_TEXTURE_2D, 0 );
+ gl_font_calc_vertices_uvs( font, pos, text, _scale, vertices, indices, clr );
+ gl_batch_insert( batch, vertices, len * 6, font->atlas, GL_TRIANGLES );
free( vertices );
free( indices );
- free( coords );
- free( custom_vertices );
}
-
VEC2 gl_font_dim( GL_FONT* font, const char* text, F32 _scale ) {
U32 len = strlen( text );
diff --git a/src/render/gl_2d_font.h b/src/render/gl_2d_font.h
index 71154c0..d0c9a71 100644
--- a/src/render/gl_2d_font.h
+++ b/src/render/gl_2d_font.h
@@ -2,7 +2,7 @@
#include <ft2build.h>
#include FT_FREETYPE_H
-#include "gl.h"
+#include "gl_2d.h"
#include "../util/thread.h"
extern THREAD_MUTEX font_mutex;
@@ -38,6 +38,7 @@ GL_FONT* gl_font_create( GL_DATA* gl, const char* path, I32 size );
void gl_font_destroy( GL_DATA* gl, GL_FONT* font );
void gl_font_draw( GL_FONT* font, GL_SHADER_PROGRAM* shader, VEC2 pos, const char* text, CLR color, F32 scale = 1.0f );
+void gl_font_draw( GL_FONT* font, GL_BATCH2D* batch, VEC2 pos, const char* text, CLR color, F32 scale = 1.0f );
void gl_font_textured(
GL_FONT* font,
GL_SHADER_PROGRAM* shader,
diff --git a/src/render/gl_batch.h b/src/render/gl_batch.h
index 12b512f..04f72a7 100644
--- a/src/render/gl_batch.h
+++ b/src/render/gl_batch.h
@@ -79,12 +79,16 @@ inline GL_BATCH<VERTEX>* gl_batch_create(
template <typename VERTEX>
inline void gl_batch_destroy( GL_BATCH<VERTEX>* batch ) {
- glDeleteBuffers( &batch->vbuffer );
+ glDeleteBuffers( 1, &batch->vbuffer );
+ for( auto& it : batch->calls )
+ it.textures.clear();
delete batch;
}
template <typename VERTEX>
inline void gl_batch_empty( GL_BATCH<VERTEX>* batch ) {
+ for( auto& it : batch->calls )
+ it.textures.clear();
batch->calls.clear();
}
@@ -119,6 +123,19 @@ inline void gl_batch_draw( GL_BATCH<VERTEX>* batch ) {
gl_set_clip( batch->gl, clip_start, clip_dim );
}
+inline U8 gl_batch_is_allowed_primitive( U16 primitive ) {
+ switch( primitive ) {
+ case GL_TRIANGLE_FAN:
+ case GL_TRIANGLE_STRIP:
+ case GL_QUAD_STRIP:
+ case GL_LINE_STRIP:
+ case GL_LINE_LOOP:
+ return 0;
+ default:
+ return 1;
+ }
+}
+
template <typename VERTEX>
inline GL_BATCH_CALL<VERTEX>* gl_batch_get_call( GL_BATCH<VERTEX>* batch, GL_TEX2D* tex, U16 primitive, I32* texid ) {
U32 n = batch->calls.size;
@@ -127,7 +144,7 @@ inline GL_BATCH_CALL<VERTEX>* gl_batch_get_call( GL_BATCH<VERTEX>* batch, GL_TEX
VEC2 clip_start = batch->clip_start;
VEC2 clip_dim = batch->clip_dim;
- if( n ) {
+ if( gl_batch_is_allowed_primitive( primitive ) && n ) {
GL_BATCH_CALL<VERTEX>* last = &batch->calls.data[n - 1];
if( last->primitive == primitive
&& vp_start == last->clip_start && vp_dim == last->viewport_dim
@@ -162,8 +179,11 @@ inline GL_BATCH_CALL<VERTEX>* gl_batch_get_call( GL_BATCH<VERTEX>* batch, GL_TEX
.textures = {},
};
- *texid = 0;
- call.textures.push( tex );
+ if( tex ) {
+ *texid = 0;
+ call.textures.push( tex );
+ } else *texid = SAMPLER_ID_NONE;
+
return batch->calls.push( call );
}
@@ -191,8 +211,11 @@ inline void gl_batch_insert(
call = gl_batch_get_call( batch, tex, primitive, &texid );
- for( U32 i = 0; i < count; ++i ) {
+ for( U32 i = 0; i < count; ++i )
vertices[i].sampler = texid;
- call->vertices.push( vertices[i] );
- }
+
+ if( call->vertices.capacity < call->vertices.size + count )
+ call->vertices.reserve( (call->vertices.size + count) * 4 );
+ memcpy( &call->vertices.data[call->vertices.size], vertices, sizeof( VERTEX ) * count );
+ call->vertices.size += count;
}