WIP optimization (does not compile!)
This commit is contained in:
parent
cdc6ebeb5a
commit
c77494d67f
41
include/draw_buffers.h
Normal file
41
include/draw_buffers.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* draw_buffers.h
|
||||||
|
*
|
||||||
|
* Created on: Nov 15, 2017
|
||||||
|
* Author: nullifiedcat
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct draw_buffer_t
|
||||||
|
{
|
||||||
|
uint32_t vao;
|
||||||
|
uint32_t vbo;
|
||||||
|
uint32_t attributes;
|
||||||
|
|
||||||
|
void *vertex;
|
||||||
|
uint32_t vertex_capacity;
|
||||||
|
uint32_t vertex_count;
|
||||||
|
uint32_t vertex_size;
|
||||||
|
|
||||||
|
uint32_t *index;
|
||||||
|
uint32_t index_capacity;
|
||||||
|
uint32_t index_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct draw_buffer_t buffer_pc;
|
||||||
|
struct draw_buffer_t buffer_ptc;
|
||||||
|
|
||||||
|
void
|
||||||
|
draw_buffers_init();
|
||||||
|
|
||||||
|
void
|
||||||
|
draw_buffers_refresh();
|
||||||
|
|
||||||
|
void
|
||||||
|
draw_buffer_push(struct draw_buffer_t *buffer, void *vertices, uint32_t vertices_count, uint32_t *indices, uint32_t indices_count);
|
||||||
|
|
||||||
|
void
|
||||||
|
draw_buffer_render(struct draw_buffer_t *buffer, uint32_t start, uint32_t count);
|
@ -23,9 +23,7 @@ enum
|
|||||||
{
|
{
|
||||||
DI_INVALID_INSTRUCTION,
|
DI_INVALID_INSTRUCTION,
|
||||||
DI_SWITCH_PROGRAM,
|
DI_SWITCH_PROGRAM,
|
||||||
DI_PUSH_VERTICES,
|
DI_DRAW_ARRAYS,
|
||||||
DI_PUSH_INDICES,
|
|
||||||
DI_PROGRAM_SWITCH_TEXTURE,
|
|
||||||
DI_PROGRAM_SWITCH_FONT,
|
DI_PROGRAM_SWITCH_FONT,
|
||||||
DI_TEXTUREAPI_BIND_TEXTURE,
|
DI_TEXTUREAPI_BIND_TEXTURE,
|
||||||
DI_TERMINATE
|
DI_TERMINATE
|
||||||
@ -39,82 +37,32 @@ struct draw_instruction_t
|
|||||||
/* DI_SWITCH_PROGRAM */
|
/* DI_SWITCH_PROGRAM */
|
||||||
int program;
|
int program;
|
||||||
/* DI_PUSH_VERTICES / DI_PUSH_INDICES */
|
/* DI_PUSH_VERTICES / DI_PUSH_INDICES */
|
||||||
size_t count;
|
struct
|
||||||
/* DI_PROGRAM_SWITCH_TEXTURE */
|
{
|
||||||
GLuint texture;
|
uint32_t arr_start;
|
||||||
|
uint32_t arr_count;
|
||||||
|
};
|
||||||
/* DI_PROGRAM_SWITCH_FONT */
|
/* DI_PROGRAM_SWITCH_FONT */
|
||||||
xoverlay_font_handle_t font;
|
xoverlay_font_handle_t font;
|
||||||
/* */
|
/* DI_TEXTUREAPI_BIND_TEXTURE */
|
||||||
xoverlay_texture_handle_t thandle;
|
xoverlay_texture_handle_t texture;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct draw_instruction_stream_t
|
void
|
||||||
{
|
ds_push_instruction(struct draw_instruction_t instr);
|
||||||
void *memory;
|
|
||||||
size_t capacity;
|
|
||||||
size_t write_ptr;
|
|
||||||
size_t read_ptr;
|
|
||||||
size_t last_draw_instruction_offset;
|
|
||||||
GLuint next_index;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct draw_instruction_stream_t dstream;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
dis_init();
|
ds_push_vertices(size_t count, size_t vertex_size, void *vertex_data);
|
||||||
|
|
||||||
void
|
|
||||||
dis_destroy();
|
|
||||||
|
|
||||||
void
|
|
||||||
dis_reset();
|
|
||||||
|
|
||||||
void
|
|
||||||
dis_reserve(size_t bytes);
|
|
||||||
|
|
||||||
struct draw_instruction_t*
|
struct draw_instruction_t*
|
||||||
dis_last_pushed_instruction();
|
ds_fetch_instruction();
|
||||||
|
|
||||||
void
|
|
||||||
dis_push_data(size_t bytes, void *data);
|
|
||||||
|
|
||||||
void
|
|
||||||
dis_push_instruction(struct draw_instruction_t instr);
|
|
||||||
|
|
||||||
size_t
|
|
||||||
dis_fetch_data(size_t bytes, void *data);
|
|
||||||
|
|
||||||
void*
|
|
||||||
dis_read_data(size_t bytes);
|
|
||||||
|
|
||||||
void
|
|
||||||
dis_switch_program(int program);
|
|
||||||
|
|
||||||
void
|
|
||||||
dis_push_vertices(size_t count, size_t vertex_size, void *vertex_data);
|
|
||||||
|
|
||||||
void
|
|
||||||
dis_push_indices(size_t count, GLuint *index_data);
|
|
||||||
|
|
||||||
void
|
|
||||||
dis_program_switch_texture(GLuint texture);
|
|
||||||
|
|
||||||
void
|
|
||||||
dis_textureapi_switch_texture(xoverlay_texture_handle_t texture);
|
|
||||||
|
|
||||||
void
|
|
||||||
dis_program_switch_font(xoverlay_font_handle_t font);
|
|
||||||
|
|
||||||
void
|
|
||||||
dis_finish();
|
|
||||||
|
|
||||||
struct draw_instruction_t*
|
|
||||||
dis_fetch_instruction();
|
|
||||||
|
|
||||||
struct draw_state
|
struct draw_state
|
||||||
{
|
{
|
||||||
mat4 model, view, projection;
|
vector_t instructions;
|
||||||
|
uint32_t next_fetch_instruction;
|
||||||
|
mat4 model, view, projection;
|
||||||
|
|
||||||
int program;
|
int program;
|
||||||
int dirty;
|
int dirty;
|
||||||
@ -158,10 +106,7 @@ ds_render_next_frame();
|
|||||||
/* To be called by draw functions */
|
/* To be called by draw functions */
|
||||||
|
|
||||||
void
|
void
|
||||||
ds_prepare_texture_handle(xoverlay_texture_handle_t handle);
|
ds_prepare_texture(xoverlay_texture_handle_t texture);
|
||||||
|
|
||||||
void
|
|
||||||
ds_prepare_texture(GLuint texture);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ds_prepare_font(xoverlay_font_handle_t font);
|
ds_prepare_font(xoverlay_font_handle_t font);
|
||||||
@ -169,7 +114,7 @@ ds_prepare_font(xoverlay_font_handle_t font);
|
|||||||
/* To be called from programs */
|
/* To be called from programs */
|
||||||
|
|
||||||
void
|
void
|
||||||
ds_bind_texture(GLuint texture);
|
ds_use_texture(GLuint texture);
|
||||||
|
|
||||||
void
|
void
|
||||||
ds_use_shader(GLuint shader);
|
ds_use_shader(GLuint shader);
|
||||||
|
@ -44,8 +44,7 @@ typedef void(*program_callback_empty_fn)();
|
|||||||
|
|
||||||
struct program_t
|
struct program_t
|
||||||
{
|
{
|
||||||
vertex_buffer_t *vertex;
|
struct draw_buffer_t *buffer;
|
||||||
size_t vertex_size;
|
|
||||||
GLuint shader;
|
GLuint shader;
|
||||||
|
|
||||||
program_callback_empty_fn init;
|
program_callback_empty_fn init;
|
||||||
|
104
src/draw_buffers.c
Normal file
104
src/draw_buffers.c
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* draw_buffers.c
|
||||||
|
*
|
||||||
|
* Created on: Nov 15, 2017
|
||||||
|
* Author: nullifiedcat
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "draw_buffers.h"
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <GL/gl.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
draw_buffers_init()
|
||||||
|
{
|
||||||
|
memset(&buffer_pc, 0, sizeof(buffer_pc));
|
||||||
|
memset(&buffer_pc, 0, sizeof(buffer_ptc));
|
||||||
|
|
||||||
|
glGenBuffers(1, &buffer_pc.vbo);
|
||||||
|
glGenVertexArrays(1, &buffer_pc.vao);
|
||||||
|
|
||||||
|
glBindVertexArray(buffer_pc.vao);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, buffer_pc.vbo);
|
||||||
|
|
||||||
|
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(struct vertex_v2fc4f), 0);
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(struct vertex_v2fc4f), 2 * sizeof(float));
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
buffer_pc.index_capacity = 800;
|
||||||
|
buffer_pc.index = malloc(buffer_pc.index_capacity);
|
||||||
|
buffer_pc.vertex_capacity = 800;
|
||||||
|
buffer_pc.vertex = malloc(buffer_pc.vertex_capacity);
|
||||||
|
buffer_pc.vertex_size = sizeof(struct vertex_v2fc4f);
|
||||||
|
buffer_pc.attributes = 2;
|
||||||
|
|
||||||
|
glGenBuffers(1, &buffer_ptc.vbo);
|
||||||
|
glGenVertexArrays(1, &buffer_ptc.vao);
|
||||||
|
|
||||||
|
glBindVertexArray(buffer_ptc.vao);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, buffer_ptc.vbo);
|
||||||
|
|
||||||
|
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(struct vertex_v2ft2fc4f), 0);
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(struct vertex_v2ft2fc4f), 2 * sizeof(float));
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(struct vertex_v2ft2fc4f), 4 * sizeof(float));
|
||||||
|
glEnableVertexAttribArray(2);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
buffer_ptc.index_capacity = 800;
|
||||||
|
buffer_ptc.index = malloc(buffer_ptc.index_capacity);
|
||||||
|
buffer_ptc.vertex_capacity = 800;
|
||||||
|
buffer_ptc.vertex = malloc(buffer_ptc.vertex_capacity);
|
||||||
|
buffer_ptc.vertex_size = sizeof(struct vertex_v2ft2fc4f);
|
||||||
|
buffer_ptc.attributes = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
draw_buffers_refresh()
|
||||||
|
{
|
||||||
|
buffer_pc.index_count = 0;
|
||||||
|
buffer_ptc.vertex_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
draw_buffer_push(struct draw_buffer_t *buffer, void *vertices, uint32_t vertices_count, unsigned *indices, uint32_t indices_count)
|
||||||
|
{
|
||||||
|
while (buffer->index_capacity <= buffer->index_count + indices_count)
|
||||||
|
{
|
||||||
|
buffer->index_capacity *= 2;
|
||||||
|
buffer->index = realloc(buffer->index, buffer->index_capacity);
|
||||||
|
}
|
||||||
|
while (buffer->vertex_capacity <= buffer->vertex_count + vertices_count)
|
||||||
|
{
|
||||||
|
buffer->vertex_capacity *= 2;
|
||||||
|
buffer->vertex = realloc(buffer->vertex, buffer->vertex_capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(buffer->vertex + buffer->vertex_count * buffer->vertex_size, vertices, vertices_count * buffer->vertex_size);
|
||||||
|
memcpy(buffer->index + buffer->index_count * sizeof(unsigned), indices, indices_count * sizeof(unsigned));
|
||||||
|
buffer->vertex_count += vertices_count;
|
||||||
|
buffer->index_count += indices_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
draw_buffer_render(struct draw_buffer_t *buffer, uint32_t start, uint32_t count)
|
||||||
|
{
|
||||||
|
glBindVertexArray(buffer->vao);
|
||||||
|
for (uint32_t i = 0; i < buffer->attributes; ++i)
|
||||||
|
glEnableVertexAttribArray(i);
|
||||||
|
|
||||||
|
glDrawArrays(GL_TRIANGLES, start, count);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < buffer->attributes; ++i)
|
||||||
|
glDisableVertexAttribArray(i);
|
||||||
|
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
@ -261,7 +261,7 @@ xoverlay_draw_line(float x, float y, float dx, float dy, xoverlay_rgba_t color,
|
|||||||
vertices[3].pos.y = ey + ny;
|
vertices[3].pos.y = ey + ny;
|
||||||
vertices[3].color = *(vec4*)&color;
|
vertices[3].color = *(vec4*)&color;
|
||||||
|
|
||||||
dis_push_vertices(4, sizeof(struct vertex_v2fc4f), vertices);
|
ds_push_vertices(4, sizeof(struct vertex_v2fc4f), vertices);
|
||||||
dis_push_indices(6, indices);
|
dis_push_indices(6, indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,7 +298,7 @@ xoverlay_draw_rect(float x, float y, float w, float h, xoverlay_rgba_t color)
|
|||||||
vertices[3].pos.y = y;
|
vertices[3].pos.y = y;
|
||||||
vertices[3].color = *(vec4*)&color;
|
vertices[3].color = *(vec4*)&color;
|
||||||
|
|
||||||
dis_push_vertices(4, sizeof(struct vertex_v2fc4f), vertices);
|
ds_push_vertices(4, sizeof(struct vertex_v2fc4f), vertices);
|
||||||
dis_push_indices(6, indices);
|
dis_push_indices(6, indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,7 +326,7 @@ xoverlay_draw_rect_textured(float x, float y, float w, float h, xoverlay_rgba_t
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
ds_prepare_program(PROGRAM_TRIANGLES_TEXTURED);
|
ds_prepare_program(PROGRAM_TRIANGLES_TEXTURED);
|
||||||
ds_prepare_texture_handle(texture);
|
ds_prepare_texture(texture);
|
||||||
|
|
||||||
x += 0.5f;
|
x += 0.5f;
|
||||||
y += 0.5f;
|
y += 0.5f;
|
||||||
@ -367,7 +367,7 @@ xoverlay_draw_rect_textured(float x, float y, float w, float h, xoverlay_rgba_t
|
|||||||
vertices[3].uv.y = t1;
|
vertices[3].uv.y = t1;
|
||||||
vertices[3].color = *(vec4*)&color;
|
vertices[3].color = *(vec4*)&color;
|
||||||
|
|
||||||
dis_push_vertices(4, sizeof(struct vertex_v2ft2fc4f), vertices);
|
ds_push_vertices(4, sizeof(struct vertex_v2ft2fc4f), vertices);
|
||||||
dis_push_indices(6, indices);
|
dis_push_indices(6, indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,7 +428,7 @@ draw_string_internal(float x, float y, const char *string, texture_font_t *fnt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
dis_push_indices(6 * len, indices);
|
dis_push_indices(6 * len, indices);
|
||||||
dis_push_vertices(4 * len, sizeof(struct vertex_v2ft2fc4f), vertices);
|
ds_push_vertices(4 * len, sizeof(struct vertex_v2ft2fc4f), vertices);
|
||||||
|
|
||||||
if (out_x)
|
if (out_x)
|
||||||
*out_x = pen_x - x;
|
*out_x = pen_x - x;
|
||||||
|
@ -20,243 +20,37 @@ drawglx_internal_init()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* STACK SAFE */
|
|
||||||
void
|
void
|
||||||
dis_init()
|
dis_push_arrays(void *vertices, uint32_t vertices_count, uint32_t *indices, uint32_t indices_count)
|
||||||
{
|
|
||||||
dstream.capacity = 128;
|
|
||||||
dstream.memory = malloc(dstream.capacity);
|
|
||||||
dstream.read_ptr = 0;
|
|
||||||
dstream.write_ptr = 0;
|
|
||||||
dstream.next_index = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* STACK SAFE */
|
|
||||||
void
|
|
||||||
dis_destroy()
|
|
||||||
{
|
|
||||||
free(dstream.memory);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* STACK SAFE */
|
|
||||||
void
|
|
||||||
dis_reset()
|
|
||||||
{
|
|
||||||
dstream.write_ptr = 0;
|
|
||||||
dstream.read_ptr = 0;
|
|
||||||
dstream.next_index = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* STACK SAFE */
|
|
||||||
void
|
|
||||||
dis_reserve(size_t bytes)
|
|
||||||
{
|
|
||||||
while (dstream.write_ptr + bytes > dstream.capacity)
|
|
||||||
{
|
|
||||||
dstream.capacity *= 2;
|
|
||||||
dstream.capacity += 4;
|
|
||||||
dstream.memory = realloc(dstream.memory, dstream.capacity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* STACK SAFE */
|
|
||||||
struct draw_instruction_t*
|
|
||||||
dis_last_pushed_instruction()
|
|
||||||
{
|
|
||||||
if (dstream.write_ptr == 0)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (dstream.last_draw_instruction_offset + sizeof(struct draw_instruction_t) > dstream.capacity)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return (struct draw_instruction_t *)(dstream.memory + dstream.last_draw_instruction_offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* STACK SAFE */
|
|
||||||
void
|
|
||||||
dis_push_data(size_t bytes, void *data)
|
|
||||||
{
|
|
||||||
dis_reserve(bytes);
|
|
||||||
memcpy(dstream.memory + dstream.write_ptr, data, bytes);
|
|
||||||
dstream.write_ptr += bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* STACK SAFE */
|
|
||||||
void
|
|
||||||
dis_push_instruction(struct draw_instruction_t instr)
|
|
||||||
{
|
|
||||||
dstream.last_draw_instruction_offset = dstream.write_ptr;
|
|
||||||
dis_push_data(sizeof(struct draw_instruction_t), &instr);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t
|
|
||||||
dis_fetch_data(size_t bytes, void *data)
|
|
||||||
{
|
|
||||||
size_t read_count = bytes;
|
|
||||||
if (dstream.read_ptr + bytes < dstream.capacity)
|
|
||||||
read_count = dstream.capacity - dstream.read_ptr;
|
|
||||||
memcpy(data, dstream.memory + dstream.read_ptr, bytes);
|
|
||||||
dstream.read_ptr += bytes;
|
|
||||||
return read_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
void*
|
|
||||||
dis_read_data(size_t bytes)
|
|
||||||
{
|
|
||||||
void *result = dstream.memory + dstream.read_ptr;
|
|
||||||
dstream.read_ptr += bytes;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
dis_switch_program(int program)
|
|
||||||
{
|
{
|
||||||
struct draw_instruction_t *last = dis_last_pushed_instruction();
|
struct draw_instruction_t *last = dis_last_pushed_instruction();
|
||||||
|
|
||||||
if (last && last->type == DI_SWITCH_PROGRAM)
|
if (last && (last->type == DI_DRAW_ARRAYS) && last->arr_start + last->arr_count == programs[ds.program].buffer->index_count)
|
||||||
{
|
{
|
||||||
if (last->program != program)
|
last->arr_count += indices_count;
|
||||||
{
|
|
||||||
last->program = program;
|
|
||||||
dstream.next_index = 0;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct draw_instruction_t instr;
|
struct draw_instruction_t instr;
|
||||||
|
|
||||||
instr.type = DI_SWITCH_PROGRAM;
|
instr.type = DI_DRAW_ARRAYS;
|
||||||
instr.program = program;
|
instr.arr_start = programs[ds.program].buffer->index_count;
|
||||||
dstream.next_index = 0;
|
instr.arr_count += indices_count;
|
||||||
dis_push_instruction(instr);
|
ds_push_instruction(instr);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void
|
draw_buffer_push(programs[ds.program].buffer, vertices, vertices_count, indices, indices_count);
|
||||||
dis_push_vertices(size_t count, size_t vertex_size, void *vertex_data)
|
|
||||||
{
|
|
||||||
struct draw_instruction_t *last = dis_last_pushed_instruction();
|
|
||||||
dstream.next_index += count;
|
|
||||||
|
|
||||||
if (last && (last->type == DI_PUSH_VERTICES))
|
|
||||||
{
|
|
||||||
dis_push_data(count * vertex_size, vertex_data);
|
|
||||||
last->count += count;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
struct draw_instruction_t instr;
|
|
||||||
|
|
||||||
instr.type = DI_PUSH_VERTICES;
|
|
||||||
instr.count = count;
|
|
||||||
dis_push_instruction(instr);
|
|
||||||
dis_push_data(count * vertex_size, vertex_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
dis_push_indices(size_t count, GLuint *index_data)
|
|
||||||
{
|
|
||||||
struct draw_instruction_t *last = dis_last_pushed_instruction();
|
|
||||||
|
|
||||||
if (last && (last->type == DI_PUSH_INDICES))
|
|
||||||
{
|
|
||||||
dis_push_data(count * sizeof(GLuint), index_data);
|
|
||||||
last->count += count;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
struct draw_instruction_t instr;
|
|
||||||
|
|
||||||
instr.type = DI_PUSH_INDICES;
|
|
||||||
instr.count = count;
|
|
||||||
dis_push_instruction(instr);
|
|
||||||
dis_push_data(count * sizeof(GLuint), index_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
dis_program_switch_texture(GLuint texture)
|
|
||||||
{
|
|
||||||
struct draw_instruction_t *last = dis_last_pushed_instruction();
|
|
||||||
|
|
||||||
if (last && last->type == DI_PROGRAM_SWITCH_TEXTURE)
|
|
||||||
{
|
|
||||||
last->texture = texture;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
struct draw_instruction_t instr;
|
|
||||||
|
|
||||||
instr.type = DI_PROGRAM_SWITCH_TEXTURE;
|
|
||||||
instr.texture = texture;
|
|
||||||
dis_push_instruction(instr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
dis_program_switch_font(xoverlay_font_handle_t font)
|
|
||||||
{
|
|
||||||
struct draw_instruction_t *last = dis_last_pushed_instruction();
|
|
||||||
|
|
||||||
if (last && last->type == DI_PROGRAM_SWITCH_FONT)
|
|
||||||
{
|
|
||||||
last->font = font;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
struct draw_instruction_t instr;
|
|
||||||
|
|
||||||
instr.type = DI_PROGRAM_SWITCH_FONT;
|
|
||||||
instr.font = font;
|
|
||||||
dis_push_instruction(instr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct draw_instruction_t terminate = { .type = DI_TERMINATE };
|
struct draw_instruction_t terminate = { .type = DI_TERMINATE };
|
||||||
|
|
||||||
void
|
|
||||||
dis_finish()
|
|
||||||
{
|
|
||||||
dis_push_instruction(terminate);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct draw_instruction_t*
|
struct draw_instruction_t*
|
||||||
dis_fetch_instruction()
|
ds_fetch_instruction()
|
||||||
{
|
{
|
||||||
if (dstream.read_ptr + sizeof(struct draw_instruction_t) > dstream.capacity)
|
if (ds.next_fetch_instruction >= ds.instructions.size)
|
||||||
return NULL;
|
return NULL;
|
||||||
struct draw_instruction_t *result;
|
return ds.instructions[ds.next_fetch_instruction++];
|
||||||
result = (struct draw_instruction_t *)(dstream.memory + dstream.read_ptr);
|
|
||||||
dstream.read_ptr += sizeof(struct draw_instruction_t);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
dis_textureapi_switch_texture(xoverlay_texture_handle_t texture)
|
|
||||||
{
|
|
||||||
struct draw_instruction_t *last = dis_last_pushed_instruction();
|
|
||||||
|
|
||||||
if (last && last->type == DI_TEXTUREAPI_BIND_TEXTURE)
|
|
||||||
{
|
|
||||||
last->thandle = texture;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
struct draw_instruction_t instr;
|
|
||||||
|
|
||||||
instr.type = DI_TEXTUREAPI_BIND_TEXTURE;
|
|
||||||
instr.thandle = texture;
|
|
||||||
dis_push_instruction(instr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -267,6 +61,7 @@ ds_init()
|
|||||||
dis_init();
|
dis_init();
|
||||||
ds.program = -1;
|
ds.program = -1;
|
||||||
ds.font = 0;
|
ds.font = 0;
|
||||||
|
ds.instructions = vector_new(sizeof(struct draw_instruction_t));
|
||||||
mat4_set_identity(&ds.projection);
|
mat4_set_identity(&ds.projection);
|
||||||
mat4_set_identity(&ds.view);
|
mat4_set_identity(&ds.view);
|
||||||
mat4_set_identity(&ds.model);
|
mat4_set_identity(&ds.model);
|
||||||
@ -343,21 +138,21 @@ ds_start_next_frame()
|
|||||||
ds.font = 0;
|
ds.font = 0;
|
||||||
ds.texture = 0;
|
ds.texture = 0;
|
||||||
ds.shader = 0;
|
ds.shader = 0;
|
||||||
|
ds.next_fetch_instruction = 0;
|
||||||
|
vector_clear(ds.instructions);
|
||||||
|
|
||||||
for (int i = 0; i < PROGRAM_COUNT; ++i)
|
draw_buffers_refresh();
|
||||||
{
|
|
||||||
vertex_buffer_clear(programs[i].vertex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ds_render_next_frame()
|
ds_render_next_frame()
|
||||||
{
|
{
|
||||||
ds_pre_render();
|
ds_pre_render();
|
||||||
dis_finish();
|
ds_push_instruction(terminate);
|
||||||
|
|
||||||
struct draw_instruction_t *instr;
|
struct draw_instruction_t *instr;
|
||||||
|
|
||||||
instr = dis_fetch_instruction();
|
instr = ds_fetch_instruction();
|
||||||
char valid = 1;
|
char valid = 1;
|
||||||
|
|
||||||
while (valid && instr)
|
while (valid && instr)
|
||||||
@ -375,25 +170,13 @@ ds_render_next_frame()
|
|||||||
programs[ds.program].load();
|
programs[ds.program].load();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DI_PUSH_VERTICES:
|
case DI_DRAW_ARRAYS:
|
||||||
ds_mark_dirty();
|
|
||||||
float *vert = dis_read_data(instr->count * programs[ds.program].vertex_size);
|
|
||||||
vertex_buffer_push_back_vertices(programs[ds.program].vertex, vert, instr->count);
|
|
||||||
vertex_buffer_render()
|
|
||||||
break;
|
|
||||||
case DI_PUSH_INDICES:
|
|
||||||
ds_mark_dirty();
|
|
||||||
GLuint *indices = dis_read_data(instr->count * sizeof(GLuint));
|
|
||||||
vertex_buffer_push_back_indices(programs[ds.program].vertex, indices, instr->count);
|
|
||||||
break;
|
|
||||||
case DI_PROGRAM_SWITCH_TEXTURE:
|
|
||||||
ds_bind_texture(instr->texture);
|
|
||||||
break;
|
break;
|
||||||
case DI_PROGRAM_SWITCH_FONT:
|
case DI_PROGRAM_SWITCH_FONT:
|
||||||
program_freetype_switch_font(instr->font);
|
program_freetype_switch_font(instr->font);
|
||||||
break;
|
break;
|
||||||
case DI_TEXTUREAPI_BIND_TEXTURE:
|
case DI_TEXTUREAPI_BIND_TEXTURE:
|
||||||
textureapi_bind(instr->thandle);
|
textureapi_bind(instr->texture);
|
||||||
break;
|
break;
|
||||||
case DI_INVALID_INSTRUCTION:
|
case DI_INVALID_INSTRUCTION:
|
||||||
case DI_TERMINATE:
|
case DI_TERMINATE:
|
||||||
@ -402,7 +185,7 @@ ds_render_next_frame()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
instr = dis_fetch_instruction();
|
instr = ds_fetch_instruction();
|
||||||
}
|
}
|
||||||
ds_render_if_needed();
|
ds_render_if_needed();
|
||||||
if (ds.program >= 0 && programs[ds.program].unload)
|
if (ds.program >= 0 && programs[ds.program].unload)
|
||||||
@ -410,12 +193,11 @@ ds_render_next_frame()
|
|||||||
programs[ds.program].unload();
|
programs[ds.program].unload();
|
||||||
ds.program = -1;
|
ds.program = -1;
|
||||||
}
|
}
|
||||||
dis_reset();
|
|
||||||
ds_post_render();
|
ds_post_render();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ds_bind_texture(GLuint texture)
|
ds_use_texture(GLuint texture)
|
||||||
{
|
{
|
||||||
if (ds.texture != texture)
|
if (ds.texture != texture)
|
||||||
{
|
{
|
||||||
@ -444,12 +226,26 @@ ds_use_font(xoverlay_font_handle_t font)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ds_prepare_texture_handle(xoverlay_texture_handle_t handle)
|
ds_prepare_texture(xoverlay_texture_handle_t texture)
|
||||||
{
|
{
|
||||||
if (handle != ds.thandle)
|
if (texture != ds.texture)
|
||||||
{
|
{
|
||||||
dis_textureapi_switch_texture(handle);
|
if (ds.instructions.size)
|
||||||
ds.thandle = handle;
|
{
|
||||||
|
struct draw_instruction_t *last = ds.instructions[ds.instructions.size - 1];
|
||||||
|
|
||||||
|
if (last && last->type == DI_TEXTUREAPI_BIND_TEXTURE)
|
||||||
|
{
|
||||||
|
last->texture = texture;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
struct draw_instruction_t instr;
|
||||||
|
|
||||||
|
instr.type = DI_TEXTUREAPI_BIND_TEXTURE;
|
||||||
|
instr.texture = texture;
|
||||||
|
ds_push_instruction(instr);
|
||||||
|
ds.texture = texture;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -458,18 +254,22 @@ ds_prepare_program(int program)
|
|||||||
{
|
{
|
||||||
if (program != ds.program)
|
if (program != ds.program)
|
||||||
{
|
{
|
||||||
dis_switch_program(program);
|
if (ds.instructions.size)
|
||||||
ds.program = program;
|
{
|
||||||
}
|
struct draw_instruction_t *last = ds.instructions[ds.instructions.size - 1];
|
||||||
}
|
|
||||||
|
|
||||||
void
|
if (last && last->type == DI_SWITCH_PROGRAM)
|
||||||
ds_prepare_texture(GLuint texture)
|
{
|
||||||
{
|
last->program = program;
|
||||||
if (texture != ds.texture)
|
return;
|
||||||
{
|
}
|
||||||
dis_program_switch_texture(texture);
|
}
|
||||||
ds.texture = texture;
|
struct draw_instruction_t instr;
|
||||||
|
|
||||||
|
instr.type = DI_SWITCH_PROGRAM;
|
||||||
|
instr.program = program;
|
||||||
|
ds_push_instruction(instr);
|
||||||
|
ds.program = program;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -478,7 +278,21 @@ ds_prepare_font(xoverlay_font_handle_t font)
|
|||||||
{
|
{
|
||||||
if (font != ds.font)
|
if (font != ds.font)
|
||||||
{
|
{
|
||||||
dis_program_switch_font(font);
|
if (ds.instructions.size)
|
||||||
|
{
|
||||||
|
struct draw_instruction_t *last = ds.instructions[ds.instructions.size - 1];
|
||||||
|
|
||||||
|
if (last && last->type == DI_PROGRAM_SWITCH_FONT)
|
||||||
|
{
|
||||||
|
last->font = font;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
struct draw_instruction_t instr;
|
||||||
|
|
||||||
|
instr.type = DI_PROGRAM_SWITCH_FONT;
|
||||||
|
instr.font = font;
|
||||||
|
ds_push_instruction(instr);
|
||||||
ds.font = font;
|
ds.font = font;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ DECL_PROGRAM_LOAD(freetype)
|
|||||||
texture_font_t *fnt = fontapi_get(ds.font);
|
texture_font_t *fnt = fontapi_get(ds.font);
|
||||||
if (fnt == NULL)
|
if (fnt == NULL)
|
||||||
return;
|
return;
|
||||||
ds_bind_texture(fnt->atlas->id);
|
ds_use_texture(fnt->atlas->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
DECL_PROGRAM_RENDER(freetype)
|
DECL_PROGRAM_RENDER(freetype)
|
||||||
@ -52,7 +52,7 @@ program_freetype_switch_font(xoverlay_font_handle_t font)
|
|||||||
{
|
{
|
||||||
glGenTextures(1, &fnt->atlas->id);
|
glGenTextures(1, &fnt->atlas->id);
|
||||||
}
|
}
|
||||||
ds_bind_texture(fnt->atlas->id);
|
ds_use_texture(fnt->atlas->id);
|
||||||
if (fnt->atlas->dirty) {
|
if (fnt->atlas->dirty) {
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
@ -77,11 +77,12 @@ program_init_inplace(struct program_t *program, const char *vertex_format, const
|
|||||||
program_init_inplace(location, format, fragment, vertex, PROGRAM_INIT(name), PROGRAM_LOAD(name), PROGRAM_RENDER(name), PROGRAM_UNLOAD(name), PROGRAM_DESTROY(name))
|
program_init_inplace(location, format, fragment, vertex, PROGRAM_INIT(name), PROGRAM_LOAD(name), PROGRAM_RENDER(name), PROGRAM_UNLOAD(name), PROGRAM_DESTROY(name))
|
||||||
|
|
||||||
const char *shader_v2fc4f_vert =
|
const char *shader_v2fc4f_vert =
|
||||||
|
"#version 330 core\n"
|
||||||
"uniform mat4 model;\n"
|
"uniform mat4 model;\n"
|
||||||
"uniform mat4 view;\n"
|
"uniform mat4 view;\n"
|
||||||
"uniform mat4 projection;\n"
|
"uniform mat4 projection;\n"
|
||||||
"attribute vec2 vertex;\n"
|
"layout(location = 0) in vec2 vertex;\n"
|
||||||
"attribute vec4 color;\n"
|
"layout(location = 1) in vec4 color;\n"
|
||||||
"void main()\n"
|
"void main()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" gl_FrontColor = color;\n"
|
" gl_FrontColor = color;\n"
|
||||||
@ -92,12 +93,13 @@ const char *shader_v2fc4f_frag =
|
|||||||
" gl_FragColor = gl_Color;\n"
|
" gl_FragColor = gl_Color;\n"
|
||||||
"}";
|
"}";
|
||||||
const char *shader_v2ft2fc4f_vert =
|
const char *shader_v2ft2fc4f_vert =
|
||||||
|
"#version 330 core\n"
|
||||||
"uniform mat4 model;\n"
|
"uniform mat4 model;\n"
|
||||||
"uniform mat4 view;\n"
|
"uniform mat4 view;\n"
|
||||||
"uniform mat4 projection;\n"
|
"uniform mat4 projection;\n"
|
||||||
"attribute vec2 vertex;\n"
|
"layout(location = 0) in vec2 vertex;\n"
|
||||||
"attribute vec2 tex_coord;\n"
|
"layout(location = 1) in vec2 tex_coord;\n"
|
||||||
"attribute vec4 color;\n"
|
"layout(location = 2) in vec4 color;\n"
|
||||||
"void main()\n"
|
"void main()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" gl_TexCoord[0].xy = tex_coord.xy;\n"
|
" gl_TexCoord[0].xy = tex_coord.xy;\n"
|
||||||
|
@ -115,7 +115,7 @@ textureapi_bind(xoverlay_texture_handle_t handle)
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
texture->bound = 1;
|
texture->bound = 1;
|
||||||
}
|
}
|
||||||
ds_bind_texture(texture->texture_id);
|
ds_use_texture(texture->texture_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
xoverlay_texture_handle_t
|
xoverlay_texture_handle_t
|
||||||
|
Loading…
x
Reference in New Issue
Block a user