Trying something crazy --- maybe

master
Allen Webster 2020-02-19 22:41:11 -08:00
parent ac0bd78485
commit 99dc2fc570
1 changed files with 269 additions and 268 deletions

View File

@ -57,304 +57,305 @@ internal void
#ifdef OS_LINUX #ifdef OS_LINUX
gl__error_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char *message, const void *userParam){ gl__error_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char *message, const void *userParam){
#else #else
gl__error_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, char *message, void *userParam){ gl__error_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, char *message, void *userParam){
#endif #endif
switch (id){ switch (id){
case 131218: case 131218:
{ {
// NOTE(allen): performance warning, do nothing. // NOTE(allen): performance warning, do nothing.
}break; }break;
default: default:
{ {
InvalidPath; InvalidPath;
}break; }break;
}
} }
}
char *gl__header = R"foo(#version 130
char *gl__header = R"foo(#version 150 )foo";
)foo";
char *gl__vertex = R"foo(
char *gl__vertex = R"foo( uniform vec2 view_t;
uniform vec2 view_t; uniform mat2x2 view_m;
uniform mat2x2 view_m; in vec2 vertex_p;
in vec2 vertex_p; in vec3 vertex_t;
in vec3 vertex_t; in uint vertex_c;
in uint vertex_c; in float vertex_ht;
in float vertex_ht; smooth out vec4 fragment_color;
smooth out vec4 fragment_color; smooth out vec3 uvw;
smooth out vec3 uvw; smooth out vec2 xy;
smooth out vec2 xy; smooth out vec2 adjusted_half_dim;
smooth out vec2 adjusted_half_dim; smooth out float half_thickness;
smooth out float half_thickness; void main(void)
void main(void) {
{ gl_Position = vec4(view_m*(vertex_p - view_t), 0.0, 1.0);
gl_Position = vec4(view_m*(vertex_p - view_t), 0.0, 1.0); fragment_color.b = (float((vertex_c )&0xFFu))/255.0;
fragment_color.b = (float((vertex_c )&0xFFu))/255.0; fragment_color.g = (float((vertex_c>> 8u)&0xFFu))/255.0;
fragment_color.g = (float((vertex_c>> 8u)&0xFFu))/255.0; fragment_color.r = (float((vertex_c>>16u)&0xFFu))/255.0;
fragment_color.r = (float((vertex_c>>16u)&0xFFu))/255.0; fragment_color.a = (float((vertex_c>>24u)&0xFFu))/255.0;
fragment_color.a = (float((vertex_c>>24u)&0xFFu))/255.0; uvw = vertex_t;
uvw = vertex_t; vec2 center = vertex_t.xy;
vec2 center = vertex_t.xy; vec2 half_dim = abs(vertex_p - center);
vec2 half_dim = abs(vertex_p - center); adjusted_half_dim = half_dim - vertex_t.zz + vec2(0.5, 0.5);
adjusted_half_dim = half_dim - vertex_t.zz + vec2(0.5, 0.5); half_thickness = vertex_ht;
half_thickness = vertex_ht; xy = vertex_p;
xy = vertex_p; }
} )foo";
)foo";
char *gl__fragment = R"foo(
char *gl__fragment = R"foo( smooth in vec4 fragment_color;
smooth in vec4 fragment_color; smooth in vec3 uvw;
smooth in vec3 uvw; smooth in vec2 xy;
smooth in vec2 xy; smooth in vec2 adjusted_half_dim;
smooth in vec2 adjusted_half_dim; smooth in float half_thickness;
smooth in float half_thickness; uniform sampler2DArray sampler;
uniform sampler2DArray sampler; out vec4 out_color;
out vec4 out_color;
float rectangle_sd(vec2 p, vec2 b){
float rectangle_sd(vec2 p, vec2 b){ vec2 d = abs(p) - b;
vec2 d = abs(p) - b; return(length(max(d, vec2(0.0, 0.0))) + min(max(d.x, d.y), 0.0));
return(length(max(d, vec2(0.0, 0.0))) + min(max(d.x, d.y), 0.0)); }
}
void main(void)
void main(void) {
{ float has_thickness = (step(0.49, half_thickness));
float has_thickness = (step(0.49, half_thickness)); float does_not_have_thickness = 1.0 - has_thickness;
float does_not_have_thickness = 1.0 - has_thickness;
float sample_value = texture(sampler, uvw).r;
float sample_value = texture(sampler, uvw).r; sample_value *= does_not_have_thickness;
sample_value *= does_not_have_thickness;
vec2 center = uvw.xy;
vec2 center = uvw.xy; float roundness = uvw.z;
float roundness = uvw.z; float sd = rectangle_sd(xy - center, adjusted_half_dim);
float sd = rectangle_sd(xy - center, adjusted_half_dim); sd = sd - roundness;
sd = sd - roundness; sd = abs(sd + half_thickness) - half_thickness;
sd = abs(sd + half_thickness) - half_thickness; float shape_value = 1.0 - smoothstep(-1.0, 0.0, sd);
float shape_value = 1.0 - smoothstep(-1.0, 0.0, sd); shape_value *= has_thickness;
shape_value *= has_thickness;
out_color = vec4(fragment_color.xyz, fragment_color.a*(sample_value + shape_value));
out_color = vec4(fragment_color.xyz, fragment_color.a*(sample_value + shape_value)); }
} )foo";
)foo";
#define AttributeList(X) \ #define AttributeList(X) \
X(vertex_p) \ X(vertex_p) \
X(vertex_t) \ X(vertex_t) \
X(vertex_c) \ X(vertex_c) \
X(vertex_ht) X(vertex_ht)
#define UniformList(X) \ #define UniformList(X) \
X(view_t) \ X(view_t) \
X(view_m) \ X(view_m) \
X(sampler) X(sampler)
struct GL_Program{ struct GL_Program{
u32 program; u32 program;
#define GetAttributeLocation(N) i32 N; #define GetAttributeLocation(N) i32 N;
AttributeList(GetAttributeLocation) AttributeList(GetAttributeLocation)
#undef GetAttributeLocation #undef GetAttributeLocation
#define GetUniformLocation(N) i32 N; #define GetUniformLocation(N) i32 N;
UniformList(GetUniformLocation) UniformList(GetUniformLocation)
#undef GetUniformLocation #undef GetUniformLocation
}; };
internal GL_Program
gl__make_program(char *header, char *vertex, char *fragment){
if (header == 0){
header = "";
}
GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); internal GL_Program
GLchar *vertex_source_array[] = { header, vertex }; gl__make_program(char *header, char *vertex, char *fragment){
glShaderSource(vertex_shader, ArrayCount(vertex_source_array), vertex_source_array, 0); if (header == 0){
glCompileShader(vertex_shader); header = "";
}
GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
GLchar *fragment_source_array[] = { header, fragment }; GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(fragment_shader, ArrayCount(fragment_source_array), fragment_source_array, 0); GLchar *vertex_source_array[] = { header, vertex };
glCompileShader(fragment_shader); glShaderSource(vertex_shader, ArrayCount(vertex_source_array), vertex_source_array, 0);
glCompileShader(vertex_shader);
GLuint program = glCreateProgram();
glAttachShader(program, vertex_shader); GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
glAttachShader(program, fragment_shader); GLchar *fragment_source_array[] = { header, fragment };
glLinkProgram(program); glShaderSource(fragment_shader, ArrayCount(fragment_source_array), fragment_source_array, 0);
glValidateProgram(program); glCompileShader(fragment_shader);
GLint success = false; GLuint program = glCreateProgram();
glGetProgramiv(program, GL_LINK_STATUS, &success); glAttachShader(program, vertex_shader);
if (!success){ glAttachShader(program, fragment_shader);
GLsizei ignore = 0; glLinkProgram(program);
char vertex_errors[KB(4)]; glValidateProgram(program);
char fragment_errors[KB(4)];
char program_errors[KB(4)]; GLint success = false;
glGetShaderInfoLog(vertex_shader, sizeof(vertex_errors), &ignore, vertex_errors); glGetProgramiv(program, GL_LINK_STATUS, &success);
glGetShaderInfoLog(fragment_shader, sizeof(fragment_errors), &ignore, fragment_errors); if (!success){
glGetProgramInfoLog(program, sizeof(program_errors), &ignore, program_errors); GLsizei ignore = 0;
char vertex_errors[KB(4)];
char fragment_errors[KB(4)];
char program_errors[KB(4)];
glGetShaderInfoLog(vertex_shader, sizeof(vertex_errors), &ignore, vertex_errors);
glGetShaderInfoLog(fragment_shader, sizeof(fragment_errors), &ignore, fragment_errors);
glGetProgramInfoLog(program, sizeof(program_errors), &ignore, program_errors);
#if SHIP_MODE #if SHIP_MODE
os_popup_error("Error", "Shader compilation failed."); os_popup_error("Error", "Shader compilation failed.");
#endif #endif
InvalidPath; InvalidPath;
} }
glDeleteShader(vertex_shader); glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader); glDeleteShader(fragment_shader);
GL_Program result = {}; GL_Program result = {};
result.program = program; result.program = program;
#define GetAttributeLocation(N) result.N = glGetAttribLocation(program, #N); #define GetAttributeLocation(N) result.N = glGetAttribLocation(program, #N);
AttributeList(GetAttributeLocation) AttributeList(GetAttributeLocation)
#undef GetAttributeLocation #undef GetAttributeLocation
#define GetUniformLocation(N) result.N = glGetUniformLocation(program, #N); #define GetUniformLocation(N) result.N = glGetUniformLocation(program, #N);
UniformList(GetUniformLocation) UniformList(GetUniformLocation)
#undef GetUniformLocation #undef GetUniformLocation
return(result); return(result);
} }
#define GLOffsetStruct(p,m) ((void*)(OffsetOfMemberStruct(p,m))) #define GLOffsetStruct(p,m) ((void*)(OffsetOfMemberStruct(p,m)))
#define GLOffset(S,m) ((void*)(OffsetOfMember(S,m))) #define GLOffset(S,m) ((void*)(OffsetOfMember(S,m)))
internal void
gl_render(Render_Target *t){
Font_Set *font_set = (Font_Set*)t->font_set;
local_persist b32 first_opengl_call = true; internal void
local_persist u32 attribute_buffer = 0; gl_render(Render_Target *t){
local_persist GL_Program gpu_program = {}; Font_Set *font_set = (Font_Set*)t->font_set;
if (first_opengl_call){
first_opengl_call = false;
local_persist b32 first_opengl_call = true;
local_persist u32 attribute_buffer = 0;
local_persist GL_Program gpu_program = {};
if (first_opengl_call){
first_opengl_call = false;
#if !SHIP_MODE #if !SHIP_MODE
glEnable(GL_DEBUG_OUTPUT); glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
if (glDebugMessageControl){ if (glDebugMessageControl){
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, 0, false); glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, 0, false);
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, 0, false); glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, 0, false);
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0, 0, true); glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0, 0, true);
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0, 0, true); glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0, 0, true);
} }
if (glDebugMessageCallback){ if (glDebugMessageCallback){
glDebugMessageCallback(gl__error_callback, 0); glDebugMessageCallback(gl__error_callback, 0);
} }
#endif #endif
//////////////////////////////// ////////////////////////////////
GLuint dummy_vao = 0; GLuint dummy_vao = 0;
glGenVertexArrays(1, &dummy_vao); glGenVertexArrays(1, &dummy_vao);
glBindVertexArray(dummy_vao); glBindVertexArray(dummy_vao);
//////////////////////////////// ////////////////////////////////
glGenBuffers(1, &attribute_buffer); glGenBuffers(1, &attribute_buffer);
glBindBuffer(GL_ARRAY_BUFFER, attribute_buffer); glBindBuffer(GL_ARRAY_BUFFER, attribute_buffer);
//////////////////////////////// ////////////////////////////////
glEnable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//////////////////////////////// ////////////////////////////////
gpu_program = gl__make_program(gl__header, gl__vertex, gl__fragment); gpu_program = gl__make_program(gl__header, gl__vertex, gl__fragment);
glUseProgram(gpu_program.program); glUseProgram(gpu_program.program);
//////////////////////////////// ////////////////////////////////
{ {
t->fallback_texture_id = gl__get_texture(V3i32(2, 2, 1), TextureKind_Mono); t->fallback_texture_id = gl__get_texture(V3i32(2, 2, 1), TextureKind_Mono);
u8 white_block[] = { 0xFF, 0xFF, 0xFF, 0xFF, }; u8 white_block[] = { 0xFF, 0xFF, 0xFF, 0xFF, };
gl__fill_texture(TextureKind_Mono, 0, V3i32(0, 0, 0), V3i32(2, 2, 1), white_block); gl__fill_texture(TextureKind_Mono, 0, V3i32(0, 0, 0), V3i32(2, 2, 1), white_block);
}
} }
}
i32 width = t->width;
i32 height = t->height;
glViewport(0, 0, width, height);
glScissor(0, 0, width, height);
glClearColor(1.f, 0.f, 1.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, 0);
t->bound_texture = 0;
for (Render_Free_Texture *free_texture = t->free_texture_first;
free_texture != 0;
free_texture = free_texture->next){
glDeleteTextures(1, &free_texture->tex_id);
}
t->free_texture_first = 0;
t->free_texture_last = 0;
for (Render_Group *group = t->group_first;
group != 0;
group = group->next){
Rect_i32 box = Ri32(group->clip_box);
Rect_i32 scissor_box = { i32 width = t->width;
box.x0, height - box.y1, box.x1 - box.x0, box.y1 - box.y0, i32 height = t->height;
};
scissor_box.x0 = clamp_bot(0, scissor_box.x0);
scissor_box.y0 = clamp_bot(0, scissor_box.y0);
scissor_box.x1 = clamp_bot(0, scissor_box.x1);
scissor_box.y1 = clamp_bot(0, scissor_box.y1);
glScissor(scissor_box.x0, scissor_box.y0, scissor_box.x1, scissor_box.y1);
i32 vertex_count = group->vertex_list.vertex_count; glViewport(0, 0, width, height);
if (vertex_count > 0){ glScissor(0, 0, width, height);
Face *face = font_set_face_from_id(font_set, group->face_id); glClearColor(1.f, 0.f, 1.f, 1.f);
if (face != 0){ glClear(GL_COLOR_BUFFER_BIT);
gl__bind_texture(t, face->texture);
} glBindTexture(GL_TEXTURE_2D, 0);
else{ t->bound_texture = 0;
gl__bind_any_texture(t);
} for (Render_Free_Texture *free_texture = t->free_texture_first;
free_texture != 0;
free_texture = free_texture->next){
glDeleteTextures(1, &free_texture->tex_id);
}
t->free_texture_first = 0;
t->free_texture_last = 0;
for (Render_Group *group = t->group_first;
group != 0;
group = group->next){
Rect_i32 box = Ri32(group->clip_box);
glBufferData(GL_ARRAY_BUFFER, vertex_count*sizeof(Render_Vertex), 0, GL_STREAM_DRAW); Rect_i32 scissor_box = {
i32 cursor = 0; box.x0, height - box.y1, box.x1 - box.x0, box.y1 - box.y0,
for (Render_Vertex_Array_Node *node = group->vertex_list.first;
node != 0;
node = node->next){
i32 size = node->vertex_count*sizeof(*node->vertices);
glBufferSubData(GL_ARRAY_BUFFER, cursor, size, node->vertices);
cursor += size;
}
glEnableVertexAttribArray(gpu_program.vertex_p);
glEnableVertexAttribArray(gpu_program.vertex_t);
glEnableVertexAttribArray(gpu_program.vertex_c);
glEnableVertexAttribArray(gpu_program.vertex_ht);
glVertexAttribPointer(gpu_program.vertex_p, 2, GL_FLOAT, true, sizeof(Render_Vertex),
GLOffset(Render_Vertex, xy));
glVertexAttribPointer(gpu_program.vertex_t, 3, GL_FLOAT, true, sizeof(Render_Vertex),
GLOffset(Render_Vertex, uvw));
glVertexAttribIPointer(gpu_program.vertex_c, 1, GL_UNSIGNED_INT, sizeof(Render_Vertex),
GLOffset(Render_Vertex, color));
glVertexAttribPointer(gpu_program.vertex_ht, 1, GL_FLOAT, true, sizeof(Render_Vertex),
GLOffset(Render_Vertex, half_thickness));
glUniform2f(gpu_program.view_t, width/2.f, height/2.f);
f32 m[4] = {
2.f/width, 0.f,
0.f, -2.f/height,
}; };
glUniformMatrix2fv(gpu_program.view_m, 1, GL_FALSE, m); scissor_box.x0 = clamp_bot(0, scissor_box.x0);
glUniform1i(gpu_program.sampler, 0); scissor_box.y0 = clamp_bot(0, scissor_box.y0);
scissor_box.x1 = clamp_bot(0, scissor_box.x1);
scissor_box.y1 = clamp_bot(0, scissor_box.y1);
glScissor(scissor_box.x0, scissor_box.y0, scissor_box.x1, scissor_box.y1);
glDrawArrays(GL_TRIANGLES, 0, vertex_count); i32 vertex_count = group->vertex_list.vertex_count;
glDisableVertexAttribArray(gpu_program.vertex_p); if (vertex_count > 0){
glDisableVertexAttribArray(gpu_program.vertex_t); Face *face = font_set_face_from_id(font_set, group->face_id);
glDisableVertexAttribArray(gpu_program.vertex_c); if (face != 0){
glDisableVertexAttribArray(gpu_program.vertex_ht); gl__bind_texture(t, face->texture);
}
else{
gl__bind_any_texture(t);
}
glBufferData(GL_ARRAY_BUFFER, vertex_count*sizeof(Render_Vertex), 0, GL_STREAM_DRAW);
i32 cursor = 0;
for (Render_Vertex_Array_Node *node = group->vertex_list.first;
node != 0;
node = node->next){
i32 size = node->vertex_count*sizeof(*node->vertices);
glBufferSubData(GL_ARRAY_BUFFER, cursor, size, node->vertices);
cursor += size;
}
glEnableVertexAttribArray(gpu_program.vertex_p);
glEnableVertexAttribArray(gpu_program.vertex_t);
glEnableVertexAttribArray(gpu_program.vertex_c);
glEnableVertexAttribArray(gpu_program.vertex_ht);
glVertexAttribPointer(gpu_program.vertex_p, 2, GL_FLOAT, true, sizeof(Render_Vertex),
GLOffset(Render_Vertex, xy));
glVertexAttribPointer(gpu_program.vertex_t, 3, GL_FLOAT, true, sizeof(Render_Vertex),
GLOffset(Render_Vertex, uvw));
glVertexAttribIPointer(gpu_program.vertex_c, 1, GL_UNSIGNED_INT, sizeof(Render_Vertex),
GLOffset(Render_Vertex, color));
glVertexAttribPointer(gpu_program.vertex_ht, 1, GL_FLOAT, true, sizeof(Render_Vertex),
GLOffset(Render_Vertex, half_thickness));
glUniform2f(gpu_program.view_t, width/2.f, height/2.f);
f32 m[4] = {
2.f/width, 0.f,
0.f, -2.f/height,
};
glUniformMatrix2fv(gpu_program.view_m, 1, GL_FALSE, m);
glUniform1i(gpu_program.sampler, 0);
glDrawArrays(GL_TRIANGLES, 0, vertex_count);
glDisableVertexAttribArray(gpu_program.vertex_p);
glDisableVertexAttribArray(gpu_program.vertex_t);
glDisableVertexAttribArray(gpu_program.vertex_c);
glDisableVertexAttribArray(gpu_program.vertex_ht);
}
} }
glFlush();
} }
glFlush(); // BOTTOM
}
// BOTTOM