working fonts
This commit is contained in:
parent
29914468df
commit
e79aa9488f
Binary file not shown.
Binary file not shown.
BIN
ftgl/makefont.o
BIN
ftgl/makefont.o
Binary file not shown.
Binary file not shown.
@ -36,6 +36,7 @@ texture_atlas_new( const size_t width,
|
||||
self->height = height;
|
||||
self->depth = depth;
|
||||
self->id = 0;
|
||||
self->dirty = 1;
|
||||
|
||||
vector_push_back( self->nodes, &node );
|
||||
self->data = (unsigned char *)
|
||||
@ -99,6 +100,7 @@ texture_atlas_set_region( texture_atlas_t * self,
|
||||
memcpy( self->data+((y+i)*self->width + x ) * charsize * depth,
|
||||
data + (i*stride) * charsize, width * charsize * depth );
|
||||
}
|
||||
self->dirty = 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -110,6 +110,11 @@ typedef struct texture_atlas_t
|
||||
*/
|
||||
unsigned char * data;
|
||||
|
||||
/**
|
||||
* Custom field
|
||||
*/
|
||||
char dirty;
|
||||
|
||||
} texture_atlas_t;
|
||||
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
@ -8,6 +8,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "drawglx.h"
|
||||
#include "fontapi_internal.h"
|
||||
#include "programs.h"
|
||||
|
||||
#include "vector.h"
|
||||
@ -34,13 +35,13 @@ struct draw_instruction_t
|
||||
union
|
||||
{
|
||||
/* DI_SWITCH_PROGRAM */
|
||||
int program;
|
||||
int program;
|
||||
/* DI_PUSH_VERTICES / DI_PUSH_INDICES */
|
||||
size_t count;
|
||||
size_t count;
|
||||
/* DI_PROGRAM_SWITCH_TEXTURE */
|
||||
GLuint texture;
|
||||
GLuint texture;
|
||||
/* DI_PROGRAM_SWITCH_FONT */
|
||||
texture_font_t *font;
|
||||
xoverlay_font_handle_t font;
|
||||
};
|
||||
};
|
||||
|
||||
@ -96,7 +97,7 @@ void
|
||||
dis_program_switch_texture(GLuint texture);
|
||||
|
||||
void
|
||||
dis_program_switch_font(texture_font_t *font);
|
||||
dis_program_switch_font(xoverlay_font_handle_t font);
|
||||
|
||||
void
|
||||
dis_finish();
|
||||
@ -111,7 +112,9 @@ struct draw_state
|
||||
int program;
|
||||
int dirty;
|
||||
|
||||
GLuint texture;
|
||||
GLuint texture;
|
||||
xoverlay_font_handle_t font;
|
||||
|
||||
GLuint shader;
|
||||
};
|
||||
|
||||
@ -141,6 +144,14 @@ ds_post_render();
|
||||
void
|
||||
ds_render_next_frame();
|
||||
|
||||
/* To be called by draw functions */
|
||||
|
||||
void
|
||||
ds_prepare_texture(GLuint texture);
|
||||
|
||||
void
|
||||
ds_prepare_font(xoverlay_font_handle_t font);
|
||||
|
||||
/* To be called from programs */
|
||||
|
||||
void
|
||||
@ -149,6 +160,9 @@ ds_bind_texture(GLuint texture);
|
||||
void
|
||||
ds_use_shader(GLuint shader);
|
||||
|
||||
void
|
||||
ds_use_font(xoverlay_font_handle_t font);
|
||||
|
||||
/* Primitive Internal Drawing API */
|
||||
|
||||
void
|
||||
@ -164,13 +178,10 @@ void
|
||||
draw_rect_textured(vec2 xy, vec2 hw, vec4 color, int texture, vec2 uv, vec2 st);
|
||||
|
||||
void
|
||||
draw_string(vec2 xy, const char *string, texture_font_t *font, vec4 color);
|
||||
draw_string_internal(vec2 xy, const char *string, xoverlay_font_handle_t font, vec4 color, int *out_x, int *out_y);
|
||||
|
||||
void
|
||||
draw_string_outline(vec2 xy, const char *string, texture_font_t *font, vec4 color);
|
||||
draw_string(vec2 xy, const char *string, xoverlay_font_handle_t font, vec4 color, int *out_x, int *out_y);
|
||||
|
||||
void
|
||||
draw_string_with_outline(vec2 xy, const char *string, texture_font_t *font, vec4 color, vec4 outline_color);
|
||||
|
||||
void
|
||||
get_string_size(const char *string, texture_font_t *font, vec2 *out);
|
||||
draw_string_with_outline(vec2 xy, const char *string, xoverlay_font_handle_t font, vec4 color, vec4 outline_color, float outline_width, int adjust_outline_alpha, int *out_x, int *out_y);
|
||||
|
20
include/fontapi.h
Normal file
20
include/fontapi.h
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* fontapi.h
|
||||
*
|
||||
* Created on: Nov 11, 2017
|
||||
* Author: nullifiedcat
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef unsigned int xoverlay_font_handle_t;
|
||||
#define XOVERLAY_FONT_COUNT 64
|
||||
|
||||
xoverlay_font_handle_t
|
||||
xoverlay_font_load(const char *path, float size);
|
||||
|
||||
void
|
||||
xoverlay_font_unload(xoverlay_font_handle_t handle);
|
||||
|
||||
void
|
||||
xoverlay_string_size(xoverlay_font_handle_t handle, const char *string, int *x, int *y);
|
34
include/fontapi_internal.h
Normal file
34
include/fontapi_internal.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* fontapi_internal.h
|
||||
*
|
||||
* Created on: Nov 11, 2017
|
||||
* Author: nullifiedcat
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "fontapi.h"
|
||||
|
||||
#include "freetype-gl.h"
|
||||
|
||||
struct fontapi_font_t
|
||||
{
|
||||
int init;
|
||||
|
||||
texture_font_t *font;
|
||||
texture_atlas_t *atlas;
|
||||
};
|
||||
|
||||
struct fontapi_font_t loaded_fonts[XOVERLAY_FONT_COUNT];
|
||||
|
||||
texture_font_t*
|
||||
fontapi_get(xoverlay_font_handle_t handle);
|
||||
|
||||
int
|
||||
fontapi_init();
|
||||
|
||||
void
|
||||
fontapi_destroy();
|
||||
|
||||
xoverlay_font_handle_t
|
||||
fontapi_add_font(struct fontapi_font_t font);
|
@ -7,6 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "fontapi.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/XKBlib.h>
|
||||
|
||||
@ -106,6 +108,11 @@ xoverlay_draw_rect(xoverlay_vec2_t xy, xoverlay_vec2_t hw, xoverlay_rgba_t color
|
||||
void
|
||||
xoverlay_draw_rect_outline(xoverlay_vec2_t xy, xoverlay_vec2_t hw, xoverlay_rgba_t color, float thickness);
|
||||
|
||||
void
|
||||
xoverlay_draw_string(xoverlay_vec2_t xy, const char *string, xoverlay_font_handle_t font, xoverlay_vec4_t color, int *out_x, int *out_y);
|
||||
|
||||
void
|
||||
xoverlay_draw_string_with_outline(xoverlay_vec2_t xy, const char *string, xoverlay_font_handle_t font, xoverlay_vec4_t color, xoverlay_vec4_t outline_color, float outline_width, int adjust_outline_alpha, int *out_x, int *out_y);
|
||||
|
||||
void xoverlay_poll_events();
|
||||
void xoverlay_draw_begin();
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "freetype-gl.h"
|
||||
#include "vertex-buffer.h"
|
||||
#include "fontapi.h"
|
||||
|
||||
struct draw_cmd;
|
||||
|
||||
@ -67,4 +68,4 @@ DECL_PROGRAM(triangles_textured);
|
||||
DECL_PROGRAM(freetype);
|
||||
|
||||
void
|
||||
program_freetype_switch_font(texture_font_t *font);
|
||||
program_freetype_switch_font(xoverlay_font_handle_t font);
|
||||
|
BIN
src/drawglx.o
BIN
src/drawglx.o
Binary file not shown.
@ -200,7 +200,7 @@ dis_program_switch_texture(GLuint texture)
|
||||
}
|
||||
|
||||
void
|
||||
dis_program_switch_font(texture_font_t *font)
|
||||
dis_program_switch_font(xoverlay_font_handle_t font)
|
||||
{
|
||||
struct draw_instruction_t *last = dis_last_pushed_instruction();
|
||||
|
||||
@ -245,6 +245,7 @@ ds_init()
|
||||
memset(&ds, 0, sizeof(struct draw_state));
|
||||
dis_init();
|
||||
ds.program = -1;
|
||||
ds.font = 0;
|
||||
mat4_set_identity(&ds.projection);
|
||||
mat4_set_identity(&ds.view);
|
||||
mat4_set_identity(&ds.model);
|
||||
@ -316,6 +317,9 @@ ds_render_next_frame()
|
||||
ds_pre_render();
|
||||
dis_finish();
|
||||
ds.program = -1;
|
||||
ds.font = 0;
|
||||
ds.texture = 0;
|
||||
ds.shader = 0;
|
||||
struct draw_instruction_t *instr;
|
||||
|
||||
instr = dis_fetch_instruction();
|
||||
@ -374,6 +378,7 @@ ds_bind_texture(GLuint texture)
|
||||
{
|
||||
if (ds.texture != texture)
|
||||
{
|
||||
printf("Swithing texture %u -> %u\n", ds.texture, texture);
|
||||
ds.texture = texture;
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
}
|
||||
@ -384,11 +389,21 @@ ds_use_shader(GLuint shader)
|
||||
{
|
||||
if (ds.shader != shader)
|
||||
{
|
||||
printf("Switching shader %u -> %u\n", ds.shader, shader);
|
||||
ds.shader = shader;
|
||||
glUseProgram(shader);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ds_use_font(xoverlay_font_handle_t font)
|
||||
{
|
||||
if (ds.font != font)
|
||||
{
|
||||
ds.font = font;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ds_prepare_program(int program)
|
||||
{
|
||||
@ -399,6 +414,26 @@ ds_prepare_program(int program)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ds_prepare_texture(GLuint texture)
|
||||
{
|
||||
if (texture != ds.texture)
|
||||
{
|
||||
dis_program_switch_texture(texture);
|
||||
ds.texture = texture;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ds_prepare_font(xoverlay_font_handle_t font)
|
||||
{
|
||||
if (font != ds.font)
|
||||
{
|
||||
dis_program_switch_font(font);
|
||||
ds.font = font;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
draw_line(vec2 xy, vec2 delta, vec4 color, float thickness)
|
||||
{
|
||||
@ -529,25 +564,96 @@ draw_rect_textured(vec2 xy, vec2 hw, vec4 color, int texture, vec2 uv, vec2 st)
|
||||
}
|
||||
|
||||
void
|
||||
draw_string(vec2 xy, const char *string, texture_font_t *font, vec4 color)
|
||||
draw_string_internal(vec2 xy, const char *string, xoverlay_font_handle_t font, vec4 color, int *out_x, int *out_y)
|
||||
{
|
||||
ds_prepare_program(PROGRAM_FREETYPE);
|
||||
ds_prepare_font(font);
|
||||
|
||||
texture_font_t *fnt = fontapi_get(font);
|
||||
if (!fnt)
|
||||
return;
|
||||
|
||||
vec2 pen = { xy.x, xy.y };
|
||||
vec2 pen_start = pen;
|
||||
vec2 size = { 0, 0 };
|
||||
texture_font_load_glyphs(fnt, string);
|
||||
|
||||
for (size_t i = 0; i < strlen(string); ++i)
|
||||
{
|
||||
texture_glyph_t *glyph = texture_font_find_glyph(fnt, &string[i]);
|
||||
if (glyph == NULL)
|
||||
{
|
||||
printf("glyph is NULL\n");
|
||||
continue;
|
||||
}
|
||||
if (i > 0)
|
||||
{
|
||||
pen.x += texture_glyph_get_kerning(glyph, &string[i - 1]);
|
||||
}
|
||||
|
||||
float x0 = (pen.x + glyph->offset_x);
|
||||
float y0 = (pen.y - glyph->offset_y);
|
||||
float x1 = (x0 + glyph->width);
|
||||
float y1 = (y0 + glyph->height);
|
||||
float s0 = glyph->s0;
|
||||
float t0 = glyph->t0;
|
||||
float s1 = glyph->s1;
|
||||
float t1 = glyph->t1;
|
||||
|
||||
GLuint idx = dstream.next_index;
|
||||
GLuint indices[] = { idx, idx + 1, idx + 2,
|
||||
idx + 2, idx + 3, idx };
|
||||
struct vertex_v2ft2fc4f vertices[] = {
|
||||
{ (vec2){ x0, y0 }, (vec2){ s0, t0 }, color },
|
||||
{ (vec2){ x0, y1 }, (vec2){ s0, t1 }, color },
|
||||
{ (vec2){ x1, y1 }, (vec2){ s1, t1 }, color },
|
||||
{ (vec2){ x1, y0 }, (vec2){ s1, t0 }, color }
|
||||
};
|
||||
|
||||
dis_push_indices(6, indices);
|
||||
dis_push_vertices(4, sizeof(struct vertex_v2ft2fc4f), vertices);
|
||||
|
||||
pen.x += glyph->advance_x;
|
||||
if (glyph->height > size.y)
|
||||
size.y = glyph->height;
|
||||
}
|
||||
size.x = pen.x - pen_start.x;
|
||||
if (out_x)
|
||||
*out_x = size.x;
|
||||
if (out_y)
|
||||
*out_y = size.y;
|
||||
}
|
||||
|
||||
void
|
||||
draw_string_outline(vec2 xy, const char *string, texture_font_t *font, vec4 color)
|
||||
draw_string(vec2 xy, const char *string, xoverlay_font_handle_t font, vec4 color, int *out_x, int *out_y)
|
||||
{
|
||||
ds_prepare_program(PROGRAM_FREETYPE);
|
||||
ds_prepare_font(font);
|
||||
|
||||
texture_font_t *fnt = fontapi_get(font);
|
||||
fnt->rendermode = RENDER_NORMAL;
|
||||
fnt->outline_thickness = 0.0f;
|
||||
|
||||
draw_string_internal(xy, string, font, color, out_x, out_y);
|
||||
}
|
||||
|
||||
void
|
||||
draw_string_with_outline(vec2 xy, const char *string, texture_font_t *font, vec4 color, vec4 outline_color)
|
||||
draw_string_with_outline(vec2 xy, const char *string, xoverlay_font_handle_t font, vec4 color, vec4 outline_color, float outline_width, int adjust_outline_alpha, int *out_x, int *out_y)
|
||||
{
|
||||
ds_prepare_program(PROGRAM_FREETYPE);
|
||||
}
|
||||
ds_prepare_font(font);
|
||||
|
||||
void
|
||||
get_string_size(const char *string, texture_font_t *font, vec2 *out)
|
||||
{
|
||||
if (adjust_outline_alpha)
|
||||
outline_color.a = color.a;
|
||||
|
||||
texture_font_t *fnt = fontapi_get(font);
|
||||
|
||||
fnt->rendermode = RENDER_OUTLINE_POSITIVE;
|
||||
fnt->outline_thickness = outline_width;
|
||||
draw_string_internal(xy, string, font, outline_color, 0, 0);
|
||||
|
||||
fnt->rendermode = RENDER_NORMAL;
|
||||
fnt->outline_thickness = 0.0f;
|
||||
draw_string_internal(xy, string, font, color, out_x, out_y);
|
||||
|
||||
}
|
||||
|
Binary file not shown.
82
src/fontapi.c
Normal file
82
src/fontapi.c
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* fontapi.c
|
||||
*
|
||||
* Created on: Nov 11, 2017
|
||||
* Author: nullifiedcat
|
||||
*/
|
||||
|
||||
#include "fontapi_internal.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <memory.h>
|
||||
|
||||
int
|
||||
fontapi_init()
|
||||
{
|
||||
memset(loaded_fonts, 0, sizeof(loaded_fonts));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
fontapi_destroy()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
xoverlay_font_handle_t
|
||||
xoverlay_font_load(const char *path, float size)
|
||||
{
|
||||
struct fontapi_font_t result;
|
||||
memset(&result, 0, sizeof(result));
|
||||
result.atlas = texture_atlas_new(1024, 1024, 1);
|
||||
result.font = texture_font_new_from_file(result.atlas, size, path);
|
||||
|
||||
return fontapi_add_font(result);
|
||||
}
|
||||
|
||||
void
|
||||
xoverlay_font_unload(xoverlay_font_handle_t handle)
|
||||
{
|
||||
if (handle == 0)
|
||||
return;
|
||||
if (handle > XOVERLAY_FONT_COUNT)
|
||||
return;
|
||||
if (loaded_fonts[handle - 1].init == 0)
|
||||
return;
|
||||
|
||||
texture_atlas_delete(loaded_fonts[handle - 1].atlas);
|
||||
texture_font_delete(loaded_fonts[handle - 1].font);
|
||||
}
|
||||
|
||||
xoverlay_font_handle_t
|
||||
fontapi_add_font(struct fontapi_font_t font)
|
||||
{
|
||||
for (xoverlay_font_handle_t i = 0; i < XOVERLAY_FONT_COUNT; ++i)
|
||||
{
|
||||
if (loaded_fonts[i].init == 0)
|
||||
{
|
||||
memcpy(&loaded_fonts[i], &font, sizeof(font));
|
||||
loaded_fonts[i].init = 1;
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
texture_font_t*
|
||||
fontapi_get(xoverlay_font_handle_t handle)
|
||||
{
|
||||
if (handle == 0)
|
||||
return NULL;
|
||||
if (handle >= XOVERLAY_FONT_COUNT)
|
||||
return NULL;
|
||||
if (loaded_fonts[handle - 1].init == 0)
|
||||
return NULL;
|
||||
return loaded_fonts[handle - 1].font;
|
||||
}
|
||||
|
||||
void
|
||||
xoverlay_string_size(xoverlay_font_handle_t handle, const char *string, int *x, int *y)
|
||||
{
|
||||
|
||||
}
|
BIN
src/fontapi.o
Normal file
BIN
src/fontapi.o
Normal file
Binary file not shown.
@ -251,6 +251,19 @@ void xoverlay_poll_events()
|
||||
}*/
|
||||
}
|
||||
|
||||
void
|
||||
xoverlay_draw_string(xoverlay_vec2_t xy, const char *string, xoverlay_font_handle_t font, xoverlay_vec4_t color, int *out_x, int *out_y)
|
||||
{
|
||||
draw_string(*(vec2*)&xy, string, font, *(vec4*)&color, out_x, out_y);
|
||||
}
|
||||
|
||||
void
|
||||
xoverlay_draw_string_with_outline(xoverlay_vec2_t xy, const char *string, xoverlay_font_handle_t font, xoverlay_vec4_t color, xoverlay_vec4_t outline_color, float outline_width, int adjust_outline_alpha, int *out_x, int *out_y)
|
||||
{
|
||||
draw_string_with_outline(*(vec2*)&xy, string, font, *(vec4*)&color, *(vec4*)&outline_color, outline_width, adjust_outline_alpha, out_x, out_y);
|
||||
}
|
||||
|
||||
|
||||
void xoverlay_draw_begin()
|
||||
{
|
||||
if (!xoverlay_library.init) return;
|
||||
|
BIN
src/overlay.o
BIN
src/overlay.o
Binary file not shown.
@ -10,21 +10,20 @@
|
||||
#include "freetype-gl.h"
|
||||
#include "programs.h"
|
||||
#include "texture-atlas.h"
|
||||
|
||||
texture_atlas_t *atlas;
|
||||
texture_font_t *font;
|
||||
vec2 pen;
|
||||
#include "drawglx_internal.h"
|
||||
|
||||
DECL_PROGRAM_INIT(freetype)
|
||||
{
|
||||
atlas = texture_atlas_new(1024, 1024, 1);
|
||||
font = texture_font_new_from_file(atlas, 14, "/usr/share/fonts/truetype/freefont/FreeMono.ttf");
|
||||
glGenTextures(1, &atlas->id);
|
||||
}
|
||||
|
||||
DECL_PROGRAM_LOAD(freetype)
|
||||
{
|
||||
vertex_buffer_clear(programs[PROGRAM_FREETYPE].vertex);
|
||||
ds_use_shader(programs[PROGRAM_FREETYPE].shader);
|
||||
texture_font_t *fnt = fontapi_get(ds.font);
|
||||
if (fnt == NULL)
|
||||
return;
|
||||
ds_bind_texture(fnt->atlas->id);
|
||||
}
|
||||
|
||||
DECL_PROGRAM_RENDER(freetype)
|
||||
@ -41,13 +40,28 @@ DECL_PROGRAM_UNLOAD(freetype)
|
||||
|
||||
DECL_PROGRAM_DESTROY(freetype)
|
||||
{
|
||||
texture_atlas_delete(atlas);
|
||||
texture_font_delete(font);
|
||||
}
|
||||
|
||||
void
|
||||
program_freetype_switch_font(texture_font_t *font)
|
||||
program_freetype_switch_font(xoverlay_font_handle_t font)
|
||||
{
|
||||
|
||||
texture_font_t *fnt = fontapi_get(font);
|
||||
if (fnt == NULL)
|
||||
return;
|
||||
printf("Switching font to %u\n", font);
|
||||
if (fnt->atlas->id == 0)
|
||||
{
|
||||
glGenTextures(1, &fnt->atlas->id);
|
||||
}
|
||||
ds_bind_texture(fnt->atlas->id);
|
||||
if (fnt->atlas->dirty) {
|
||||
printf("Refreshing atlas\n");
|
||||
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_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, fnt->atlas->width, fnt->atlas->height, 0, GL_RED, GL_UNSIGNED_BYTE, fnt->atlas->data);
|
||||
fnt->atlas->dirty = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
Binary file not shown.
@ -8,6 +8,7 @@
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "programs.h"
|
||||
#include "drawglx_internal.h"
|
||||
|
||||
DECL_PROGRAM_INIT(triangles_plain)
|
||||
{
|
||||
|
Binary file not shown.
Binary file not shown.
@ -108,7 +108,8 @@ const char *shader_v2ft2fc4f_frag =
|
||||
"uniform sampler2D texture;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_FragColor = texture2D(texture, gl_TexCoord[0].xy) * gl_Color;\n"
|
||||
" float a = texture2D(texture, gl_TexCoord[0].xy).r;\n"
|
||||
"gl_FragColor = vec4(gl_Color.rgb, gl_Color.a*a);\n"
|
||||
"}";
|
||||
|
||||
void
|
||||
|
BIN
src/programs.o
BIN
src/programs.o
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user