Fixed indexing in gles_canvas_fragment shaders and fixed native keys buffer
This commit is contained in:
parent
8e87837fcc
commit
e0300e9e3c
|
@ -1,6 +1,8 @@
|
||||||
|
|
||||||
if not exist bin mkdir bin
|
if not exist bin mkdir bin
|
||||||
|
|
||||||
|
call python scripts\embed_text.py src\gles_canvas_shaders\gles_canvas_fragment.glsl src\gles_canvas_shaders\gles_canvas_vertex.glsl --output src\gles_canvas_shaders.h
|
||||||
|
|
||||||
set INCLUDES=/I src /I src/util /I src/platform /I ext /I ext/angle_headers
|
set INCLUDES=/I src /I src/util /I src/platform /I ext /I ext/angle_headers
|
||||||
cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% /c /Fo:bin/milepost.obj src/milepost.c
|
cl /we4013 /Zi /Zc:preprocessor /DMG_IMPLEMENTS_BACKEND_GLES /std:c11 %INCLUDES% /c /Fo:bin/milepost.obj src/milepost.c
|
||||||
lib bin/milepost.obj /OUT:bin/milepost.lib
|
lib bin/milepost.obj /OUT:bin/milepost.lib
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext /I ../../ext/angle_headers
|
||||||
|
cl /we4013 /Zi /Zc:preprocessor /DMG_IMPLEMENTS_BACKEND_GLES /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib /LIBPATH:../../bin libEGL.dll.lib libGLESv2.dll.lib user32.lib opengl32.lib gdi32.lib /out:../../bin/example_canvas.exe
|
|
@ -13,7 +13,6 @@
|
||||||
#include<math.h>
|
#include<math.h>
|
||||||
|
|
||||||
#include"milepost.h"
|
#include"milepost.h"
|
||||||
#include"metal_surface.h"
|
|
||||||
|
|
||||||
#define LOG_SUBSYSTEM "Main"
|
#define LOG_SUBSYSTEM "Main"
|
||||||
|
|
||||||
|
@ -27,7 +26,13 @@ int main()
|
||||||
mp_window window = mp_window_create(rect, "test", 0);
|
mp_window window = mp_window_create(rect, "test", 0);
|
||||||
|
|
||||||
//NOTE: create surface
|
//NOTE: create surface
|
||||||
|
#if defined(OS_MACOS)
|
||||||
mg_surface surface = mg_metal_surface_create_for_window(window);
|
mg_surface surface = mg_metal_surface_create_for_window(window);
|
||||||
|
#elif defined(OS_WIN64)
|
||||||
|
mg_surface surface = mg_gles_surface_create_for_window(window);
|
||||||
|
#else
|
||||||
|
#error "unsupported OS"
|
||||||
|
#endif
|
||||||
|
|
||||||
//TODO: create canvas
|
//TODO: create canvas
|
||||||
mg_canvas canvas = mg_canvas_create(surface);
|
mg_canvas canvas = mg_canvas_create(surface);
|
||||||
|
@ -118,19 +123,23 @@ int main()
|
||||||
}
|
}
|
||||||
|
|
||||||
mg_surface_prepare(surface);
|
mg_surface_prepare(surface);
|
||||||
|
// background
|
||||||
mg_set_color_rgba(1, 0, 1, 1);
|
mg_set_color_rgba(1, 0, 1, 1);
|
||||||
mg_clear();
|
mg_clear();
|
||||||
|
|
||||||
|
// head
|
||||||
mg_set_color_rgba(1, 1, 0, 1);
|
mg_set_color_rgba(1, 1, 0, 1);
|
||||||
mg_circle_fill(400, 300, 200);
|
mg_circle_fill(400, 300, 200);
|
||||||
|
|
||||||
mg_set_color_rgba(0, 0, 0, 1);
|
// smile
|
||||||
mg_set_width(20);
|
mg_set_color_rgba(1, 0, 0, 1);
|
||||||
|
|
||||||
|
mg_set_width(20);
|
||||||
mg_move_to(300, 200);
|
mg_move_to(300, 200);
|
||||||
mg_cubic_to(350, 150, 450, 150, 500, 200);
|
mg_cubic_to(350, 150, 450, 150, 500, 200);
|
||||||
mg_stroke();
|
mg_stroke();
|
||||||
|
|
||||||
|
// eyes
|
||||||
mg_ellipse_fill(330, 350, 30, 50);
|
mg_ellipse_fill(330, 350, 30, 50);
|
||||||
mg_ellipse_fill(470, 350, 30, 50);
|
mg_ellipse_fill(470, 350, 30, 50);
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext /I ../../ext/angle_headers
|
set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext /I ../../ext/angle_headers
|
||||||
cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib /LIBPATH:./ libEGL.dll.lib libGLESv2.dll.lib user32.lib opengl32.lib gdi32.lib /out:test.exe
|
cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib /LIBPATH:../../bin libEGL.dll.lib libGLESv2.dll.lib user32.lib opengl32.lib gdi32.lib /out:../../bin/example_gles_triangle.exe
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext /I ../../ext/angle_headers
|
||||||
|
cl /we4013 /Zi /Zc:preprocessor /DMG_IMPLEMENTS_BACKEND_GLES /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib /LIBPATH:../../bin libEGL.dll.lib libGLESv2.dll.lib user32.lib opengl32.lib gdi32.lib /out:../../bin/example_canvas.exe
|
|
@ -0,0 +1,11 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
BINDIR=../../bin
|
||||||
|
RESDIR=../../resources
|
||||||
|
SRCDIR=../../src
|
||||||
|
|
||||||
|
INCLUDES="-I$SRCDIR -I$SRCDIR/util -I$SRCDIR/platform -I$SRCDIR/app"
|
||||||
|
LIBS="-L$BINDIR -lmilepost -framework Carbon -framework Cocoa -framework Metal -framework QuartzCore"
|
||||||
|
FLAGS="-mmacos-version-min=10.15.4 -DDEBUG -DLOG_COMPILE_DEBUG -Wl,-dead_strip"
|
||||||
|
|
||||||
|
clang -g $FLAGS $LIBS $INCLUDES -o $BINDIR/example_canvas main.c
|
|
@ -0,0 +1,136 @@
|
||||||
|
/************************************************************//**
|
||||||
|
*
|
||||||
|
* @file: main.cpp
|
||||||
|
* @author: Martin Fouilleul
|
||||||
|
* @date: 30/07/2022
|
||||||
|
* @revision:
|
||||||
|
*
|
||||||
|
*****************************************************************/
|
||||||
|
#include<stdlib.h>
|
||||||
|
#include<string.h>
|
||||||
|
|
||||||
|
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC
|
||||||
|
#include<math.h>
|
||||||
|
|
||||||
|
#include"milepost.h"
|
||||||
|
|
||||||
|
#define LOG_SUBSYSTEM "Main"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
LogLevel(LOG_LEVEL_DEBUG);
|
||||||
|
|
||||||
|
mp_init();
|
||||||
|
|
||||||
|
mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600};
|
||||||
|
mp_window window = mp_window_create(rect, "test", 0);
|
||||||
|
|
||||||
|
//NOTE: create surface
|
||||||
|
#if defined(OS_MACOS)
|
||||||
|
mg_surface surface = mg_metal_surface_create_for_window(window);
|
||||||
|
#elif defined(OS_WIN64)
|
||||||
|
mg_surface surface = mg_gles_surface_create_for_window(window);
|
||||||
|
#else
|
||||||
|
#error "unsupported OS"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//TODO: create canvas
|
||||||
|
mg_canvas canvas = mg_canvas_create(surface);
|
||||||
|
|
||||||
|
// start app
|
||||||
|
mp_window_bring_to_front(window);
|
||||||
|
mp_window_focus(window);
|
||||||
|
|
||||||
|
f32 dx = 17.000029, dy = 0;
|
||||||
|
|
||||||
|
while(!mp_should_quit())
|
||||||
|
{
|
||||||
|
mp_pump_events(0);
|
||||||
|
mp_event event = {0};
|
||||||
|
while(mp_next_event(&event))
|
||||||
|
{
|
||||||
|
switch(event.type)
|
||||||
|
{
|
||||||
|
case MP_EVENT_WINDOW_CLOSE:
|
||||||
|
{
|
||||||
|
mp_request_quit();
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case MP_EVENT_WINDOW_RESIZE:
|
||||||
|
{
|
||||||
|
printf("resized, rect = {%f, %f, %f, %f}\n",
|
||||||
|
event.frame.rect.x,
|
||||||
|
event.frame.rect.y,
|
||||||
|
event.frame.rect.w,
|
||||||
|
event.frame.rect.h);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case MP_EVENT_KEYBOARD_KEY:
|
||||||
|
{
|
||||||
|
printf("key %i: %s\n",
|
||||||
|
event.key.code,
|
||||||
|
event.key.action == MP_KEY_PRESS ? "press" : (event.key.action == MP_KEY_RELEASE ? "release" : "repeat"));
|
||||||
|
if(event.key.action == MP_KEY_PRESS || event.key.action == MP_KEY_REPEAT)
|
||||||
|
{
|
||||||
|
if(event.key.code == MP_KEY_LEFT)
|
||||||
|
{
|
||||||
|
printf("left\n");
|
||||||
|
dx-=0.1;
|
||||||
|
}
|
||||||
|
else if(event.key.code == MP_KEY_RIGHT)
|
||||||
|
{
|
||||||
|
printf("right\n");
|
||||||
|
dx+=0.1;
|
||||||
|
}
|
||||||
|
else if(event.key.code == MP_KEY_UP)
|
||||||
|
{
|
||||||
|
printf("up\n");
|
||||||
|
dy+=0.1;
|
||||||
|
}
|
||||||
|
else if(event.key.code == MP_KEY_DOWN)
|
||||||
|
{
|
||||||
|
printf("down\n");
|
||||||
|
dy-=0.1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mg_surface_prepare(surface);
|
||||||
|
|
||||||
|
printf("dx = %f, dy = %f\n", dx, dy);
|
||||||
|
|
||||||
|
// background
|
||||||
|
mg_set_color_rgba(1, 0, 1, 1);
|
||||||
|
mg_clear();
|
||||||
|
/*
|
||||||
|
// head
|
||||||
|
mg_set_color_rgba(1, 1, 0, 1);
|
||||||
|
mg_circle_fill(dx+400, dy+300, 200);
|
||||||
|
|
||||||
|
// smile
|
||||||
|
mg_set_color_rgba(0, 0, 0, 1);
|
||||||
|
|
||||||
|
mg_set_width(20);
|
||||||
|
mg_move_to(dx+300, dy+200);
|
||||||
|
mg_cubic_to(dx+350, dy+150, dx+450, dy+150, dx+500, dy+200);
|
||||||
|
mg_stroke();
|
||||||
|
|
||||||
|
// eyes
|
||||||
|
mg_ellipse_fill(dx+330, dy+350, 30, 50);
|
||||||
|
mg_ellipse_fill(dx+470, dy+350, 30, 50);
|
||||||
|
*/
|
||||||
|
mg_rectangle_fill((int)(dx + 200), 200, (int)(dy+300), (int)(dy+300));
|
||||||
|
|
||||||
|
mg_flush();
|
||||||
|
mg_surface_present(surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_terminate();
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
|
@ -38,41 +38,19 @@ mg_gles_surface* mg_gles_canvas_get_surface(mg_gles_canvas_backend* canvas)
|
||||||
return(res);
|
return(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_gles_canvas_draw_buffers(mg_canvas_backend* interface, u32 vertexCount, u32 indexCount, mg_color clearColor)
|
//NOTE: debugger
|
||||||
|
typedef struct debug_vertex
|
||||||
{
|
{
|
||||||
mg_gles_canvas_backend* backend = (mg_gles_canvas_backend*)interface;
|
vec2 pos;
|
||||||
mg_gles_surface* surface = mg_gles_canvas_get_surface(backend);
|
u8 align0[8];
|
||||||
if(!surface)
|
vec4 cubic;
|
||||||
{
|
vec2 uv;
|
||||||
return;
|
u8 align1[8];
|
||||||
}
|
vec4 color;
|
||||||
|
vec4 clip;
|
||||||
//WARN: dummy test code
|
int zIndex;
|
||||||
|
u8 align2[12];
|
||||||
indexCount = 3;
|
} debug_vertex;
|
||||||
*(vec2*)(interface->vertexLayout.posBuffer) = (vec2){400, 300};
|
|
||||||
*(vec2*)(interface->vertexLayout.posBuffer + interface->vertexLayout.posStride) = (vec2){450, 300};
|
|
||||||
*(vec2*)(interface->vertexLayout.posBuffer + 2*interface->vertexLayout.posStride) = (vec2){400, 350};
|
|
||||||
|
|
||||||
for(int i=0; i<3; i++)
|
|
||||||
{
|
|
||||||
*(vec4*)(interface->vertexLayout.cubicBuffer + i*interface->vertexLayout.cubicStride) = (vec4){1, 1, 1, 1};
|
|
||||||
*(vec2*)(interface->vertexLayout.uvBuffer + i*interface->vertexLayout.uvStride) = (vec2){0, 0};
|
|
||||||
*(vec4*)(interface->vertexLayout.colorBuffer + i*interface->vertexLayout.colorStride) = (vec4){1, 0, 0, 1};
|
|
||||||
*(vec4*)(interface->vertexLayout.clipBuffer + i*interface->vertexLayout.clipStride) = (vec4){-FLT_MAX/2, -FLT_MAX/2, FLT_MAX, FLT_MAX};
|
|
||||||
*(u32*)(interface->vertexLayout.zIndexBuffer + i*interface->vertexLayout.zIndexStride) = 1;
|
|
||||||
*(u32*)(interface->vertexLayout.indexBuffer + i*interface->vertexLayout.indexStride) = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
// end dummy test code
|
|
||||||
|
|
||||||
glUseProgram(backend->program);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, backend->dummyVertexBuffer);
|
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, backend->vertexBuffer);
|
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, backend->indexBuffer);
|
|
||||||
glUniform1i(0, indexCount);
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define LayoutNext(prevName, prevType, nextType) \
|
#define LayoutNext(prevName, prevType, nextType) \
|
||||||
AlignUpOnPow2(_cat3_(LAYOUT_, prevName, _OFFSET)+_cat3_(LAYOUT_, prevType, _SIZE), _cat3_(LAYOUT_, nextType, _ALIGN))
|
AlignUpOnPow2(_cat3_(LAYOUT_, prevName, _OFFSET)+_cat3_(LAYOUT_, prevType, _SIZE), _cat3_(LAYOUT_, nextType, _ALIGN))
|
||||||
|
@ -104,17 +82,9 @@ enum {
|
||||||
|
|
||||||
void mg_gles_canvas_update_vertex_layout(mg_gles_canvas_backend* backend)
|
void mg_gles_canvas_update_vertex_layout(mg_gles_canvas_backend* backend)
|
||||||
{
|
{
|
||||||
if(backend->vertexMapping)
|
|
||||||
{
|
|
||||||
glUnmapBuffer(backend->vertexBuffer);
|
|
||||||
}
|
|
||||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->vertexBuffer);
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->vertexBuffer);
|
||||||
backend->vertexMapping = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, MG_GLES_CANVAS_VERTEX_BUFFER_SIZE, GL_MAP_WRITE_BIT);
|
backend->vertexMapping = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, MG_GLES_CANVAS_VERTEX_BUFFER_SIZE, GL_MAP_WRITE_BIT);
|
||||||
|
|
||||||
if(backend->indexMapping)
|
|
||||||
{
|
|
||||||
free(backend->indexMapping);
|
|
||||||
}
|
|
||||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->indexBuffer);
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->indexBuffer);
|
||||||
backend->indexMapping = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, MG_GLES_CANVAS_INDEX_BUFFER_SIZE, GL_MAP_WRITE_BIT);
|
backend->indexMapping = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, MG_GLES_CANVAS_INDEX_BUFFER_SIZE, GL_MAP_WRITE_BIT);
|
||||||
|
|
||||||
|
@ -137,6 +107,35 @@ void mg_gles_canvas_update_vertex_layout(mg_gles_canvas_backend* backend)
|
||||||
.indexStride = LAYOUT_INT_SIZE};
|
.indexStride = LAYOUT_INT_SIZE};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mg_gles_canvas_draw_buffers(mg_canvas_backend* interface, u32 vertexCount, u32 indexCount, mg_color clearColor)
|
||||||
|
{
|
||||||
|
mg_gles_canvas_backend* backend = (mg_gles_canvas_backend*)interface;
|
||||||
|
mg_gles_surface* surface = mg_gles_canvas_get_surface(backend);
|
||||||
|
if(!surface)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*NOTE: if we want debug_vertex while debugging, the following ensures the struct def doesn't get stripped away
|
||||||
|
debug_vertex vertex;
|
||||||
|
printf("foo %p\n", &vertex);
|
||||||
|
//*/
|
||||||
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->vertexBuffer);
|
||||||
|
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
|
||||||
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->indexBuffer);
|
||||||
|
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
|
||||||
|
|
||||||
|
|
||||||
|
glUseProgram(backend->program);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, backend->dummyVertexBuffer);
|
||||||
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, backend->vertexBuffer);
|
||||||
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, backend->indexBuffer);
|
||||||
|
glUniform1i(0, indexCount);
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||||
|
|
||||||
|
mg_gles_canvas_update_vertex_layout(backend);
|
||||||
|
}
|
||||||
|
|
||||||
void mg_gles_canvas_destroy(mg_canvas_backend* interface)
|
void mg_gles_canvas_destroy(mg_canvas_backend* interface)
|
||||||
{
|
{
|
||||||
mg_gles_canvas_backend* backend = (mg_gles_canvas_backend*)interface;
|
mg_gles_canvas_backend* backend = (mg_gles_canvas_backend*)interface;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
*
|
*
|
||||||
* file: gles_canvas_shaders.h
|
* file: gles_canvas_shaders.h
|
||||||
* note: string literals auto-generated by embed_text.py
|
* note: string literals auto-generated by embed_text.py
|
||||||
* date: 31/012023
|
* date: 01/022023
|
||||||
*
|
*
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
#ifndef __GLES_CANVAS_SHADERS_H__
|
#ifndef __GLES_CANVAS_SHADERS_H__
|
||||||
|
@ -30,15 +30,112 @@ const char* gles_canvas_fragment =
|
||||||
"} vertexBuffer ;\n"
|
"} vertexBuffer ;\n"
|
||||||
"\n"
|
"\n"
|
||||||
"layout(binding = 1) buffer indexBufferSSBO {\n"
|
"layout(binding = 1) buffer indexBufferSSBO {\n"
|
||||||
" vec2 elements[];\n"
|
" uint elements[];\n"
|
||||||
"} indexBuffer ;\n"
|
"} indexBuffer ;\n"
|
||||||
"\n"
|
"\n"
|
||||||
"layout(location = 0) uniform int indexCount;\n"
|
"layout(location = 0) uniform int indexCount;\n"
|
||||||
"layout(location = 0) out vec4 fragColor;\n"
|
"layout(location = 0) out vec4 fragColor;\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
"bool is_top_left(vec2 a, vec2 b)\n"
|
||||||
|
"{\n"
|
||||||
|
" return( (a.y == b.y && b.x < a.x)\n"
|
||||||
|
" ||(b.y < a.y));\n"
|
||||||
|
"}\n"
|
||||||
|
"\n"
|
||||||
|
"float orient2d(vec2 a, vec2 b, vec2 c)\n"
|
||||||
|
"{\n"
|
||||||
|
" //////////////////////////////////////////////////////////////////////////////////////////\n"
|
||||||
|
" //TODO(martin): FIX this. This is a **horrible** quick hack to fix the precision issues\n"
|
||||||
|
" // arising when a, b, and c are close. But it degrades when a, c, and c\n"
|
||||||
|
" // are big. The proper solution is to change the expression to avoid\n"
|
||||||
|
" // precision loss but I'm too busy/lazy to do it now.\n"
|
||||||
|
" //////////////////////////////////////////////////////////////////////////////////////////\n"
|
||||||
|
" a *= 10.;\n"
|
||||||
|
" b *= 10.;\n"
|
||||||
|
" c *= 10.;\n"
|
||||||
|
" return((b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x));\n"
|
||||||
|
"}\n"
|
||||||
|
"\n"
|
||||||
"void main()\n"
|
"void main()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" fragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
|
" vec4 pixelColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
|
||||||
|
" vec4 currentColor = vec4(0., 0., 0., 1.0);\n"
|
||||||
|
"\n"
|
||||||
|
" vec2 samplePoint = gl_FragCoord.xy;\n"
|
||||||
|
"\n"
|
||||||
|
" int currentZIndex = -1;\n"
|
||||||
|
" int flipCount = 0;\n"
|
||||||
|
"\n"
|
||||||
|
"\n"
|
||||||
|
" for(int i=0; i<indexCount; i+=3)\n"
|
||||||
|
" {\n"
|
||||||
|
" uint i0 = indexBuffer.elements[i];\n"
|
||||||
|
" uint i1 = indexBuffer.elements[i+1];\n"
|
||||||
|
" uint i2 = indexBuffer.elements[i+2];\n"
|
||||||
|
"\n"
|
||||||
|
" vec2 p0 = vertexBuffer.elements[i0].pos;\n"
|
||||||
|
" vec2 p1 = vertexBuffer.elements[i1].pos;\n"
|
||||||
|
" vec2 p2 = vertexBuffer.elements[i2].pos;\n"
|
||||||
|
"\n"
|
||||||
|
" int zIndex = vertexBuffer.elements[i0].zIndex;\n"
|
||||||
|
" vec4 color = vertexBuffer.elements[i0].color;\n"
|
||||||
|
"\n"
|
||||||
|
" //NOTE(martin): reorder triangle counter-clockwise and compute bias for each edge\n"
|
||||||
|
" float cw = (p1 - p0).x*(p2 - p0).y - (p1 - p0).y*(p2 - p0).x;\n"
|
||||||
|
" if(cw < 0.)\n"
|
||||||
|
" {\n"
|
||||||
|
" uint tmpIndex = i1;\n"
|
||||||
|
" i1 = i2;\n"
|
||||||
|
" i2 = tmpIndex;\n"
|
||||||
|
"\n"
|
||||||
|
" vec2 tmpPoint = p1;\n"
|
||||||
|
" p1 = p2;\n"
|
||||||
|
" p2 = tmpPoint;\n"
|
||||||
|
" }\n"
|
||||||
|
"\n"
|
||||||
|
" vec4 cubic0 = vertexBuffer.elements[i0].cubic;\n"
|
||||||
|
" vec4 cubic1 = vertexBuffer.elements[i1].cubic;\n"
|
||||||
|
" vec4 cubic2 = vertexBuffer.elements[i2].cubic;\n"
|
||||||
|
"\n"
|
||||||
|
" int bias0 = is_top_left(p1, p2) ? 0 : -1;\n"
|
||||||
|
" int bias1 = is_top_left(p2, p0) ? 0 : -1;\n"
|
||||||
|
" int bias2 = is_top_left(p0, p1) ? 0 : -1;\n"
|
||||||
|
"\n"
|
||||||
|
" float w0 = orient2d(p1, p2, samplePoint);\n"
|
||||||
|
" float w1 = orient2d(p2, p0, samplePoint);\n"
|
||||||
|
" float w2 = orient2d(p0, p1, samplePoint);\n"
|
||||||
|
"\n"
|
||||||
|
" if((int(w0)+bias0) >= 0 && (int(w1)+bias1) >= 0 && (int(w2)+bias2) >= 0)\n"
|
||||||
|
" {\n"
|
||||||
|
" //TODO check cubic\n"
|
||||||
|
" vec4 cubic = (cubic0*w0 + cubic1*w1 + cubic2*w2)/(w0+w1+w2);\n"
|
||||||
|
"\n"
|
||||||
|
" float eps = 0.0001;\n"
|
||||||
|
" if(cubic.w*(cubic.x*cubic.x*cubic.x - cubic.y*cubic.z) <= eps)\n"
|
||||||
|
" {\n"
|
||||||
|
" if(zIndex == currentZIndex)\n"
|
||||||
|
" {\n"
|
||||||
|
" flipCount++;\n"
|
||||||
|
" }\n"
|
||||||
|
" else\n"
|
||||||
|
" {\n"
|
||||||
|
" if((flipCount & 0x01) != 0)\n"
|
||||||
|
" {\n"
|
||||||
|
" pixelColor = currentColor;\n"
|
||||||
|
" }\n"
|
||||||
|
" currentColor = pixelColor*(1.-color.a) + color.a*color;\n"
|
||||||
|
" currentZIndex = zIndex;\n"
|
||||||
|
" flipCount = 1;\n"
|
||||||
|
" }\n"
|
||||||
|
" }\n"
|
||||||
|
" }\n"
|
||||||
|
" }\n"
|
||||||
|
" if((flipCount & 0x01) != 0)\n"
|
||||||
|
" {\n"
|
||||||
|
" pixelColor = currentColor;\n"
|
||||||
|
" }\n"
|
||||||
|
"\n"
|
||||||
|
" fragColor = pixelColor;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
//NOTE: string imported from src\gles_canvas_shaders\gles_canvas_vertex.glsl
|
//NOTE: string imported from src\gles_canvas_shaders\gles_canvas_vertex.glsl
|
||||||
|
|
|
@ -17,13 +17,110 @@ layout(binding = 0) buffer vertexBufferSSBO {
|
||||||
} vertexBuffer ;
|
} vertexBuffer ;
|
||||||
|
|
||||||
layout(binding = 1) buffer indexBufferSSBO {
|
layout(binding = 1) buffer indexBufferSSBO {
|
||||||
vec2 elements[];
|
uint elements[];
|
||||||
} indexBuffer ;
|
} indexBuffer ;
|
||||||
|
|
||||||
layout(location = 0) uniform int indexCount;
|
layout(location = 0) uniform int indexCount;
|
||||||
layout(location = 0) out vec4 fragColor;
|
layout(location = 0) out vec4 fragColor;
|
||||||
|
|
||||||
|
bool is_top_left(vec2 a, vec2 b)
|
||||||
|
{
|
||||||
|
return( (a.y == b.y && b.x < a.x)
|
||||||
|
||(b.y < a.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
float orient2d(vec2 a, vec2 b, vec2 c)
|
||||||
|
{
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//TODO(martin): FIX this. This is a **horrible** quick hack to fix the precision issues
|
||||||
|
// arising when a, b, and c are close. But it degrades when a, c, and c
|
||||||
|
// are big. The proper solution is to change the expression to avoid
|
||||||
|
// precision loss but I'm too busy/lazy to do it now.
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
a *= 10.;
|
||||||
|
b *= 10.;
|
||||||
|
c *= 10.;
|
||||||
|
return((b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x));
|
||||||
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
fragColor = vec4(0.0, 1.0, 0.0, 1.0);
|
vec4 pixelColor = vec4(0.0, 1.0, 0.0, 1.0);
|
||||||
|
vec4 currentColor = vec4(0., 0., 0., 1.0);
|
||||||
|
|
||||||
|
vec2 samplePoint = gl_FragCoord.xy;
|
||||||
|
|
||||||
|
int currentZIndex = -1;
|
||||||
|
int flipCount = 0;
|
||||||
|
|
||||||
|
|
||||||
|
for(int i=0; i<indexCount; i+=3)
|
||||||
|
{
|
||||||
|
uint i0 = indexBuffer.elements[i];
|
||||||
|
uint i1 = indexBuffer.elements[i+1];
|
||||||
|
uint i2 = indexBuffer.elements[i+2];
|
||||||
|
|
||||||
|
vec2 p0 = vertexBuffer.elements[i0].pos;
|
||||||
|
vec2 p1 = vertexBuffer.elements[i1].pos;
|
||||||
|
vec2 p2 = vertexBuffer.elements[i2].pos;
|
||||||
|
|
||||||
|
int zIndex = vertexBuffer.elements[i0].zIndex;
|
||||||
|
vec4 color = vertexBuffer.elements[i0].color;
|
||||||
|
|
||||||
|
//NOTE(martin): reorder triangle counter-clockwise and compute bias for each edge
|
||||||
|
float cw = (p1 - p0).x*(p2 - p0).y - (p1 - p0).y*(p2 - p0).x;
|
||||||
|
if(cw < 0.)
|
||||||
|
{
|
||||||
|
uint tmpIndex = i1;
|
||||||
|
i1 = i2;
|
||||||
|
i2 = tmpIndex;
|
||||||
|
|
||||||
|
vec2 tmpPoint = p1;
|
||||||
|
p1 = p2;
|
||||||
|
p2 = tmpPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 cubic0 = vertexBuffer.elements[i0].cubic;
|
||||||
|
vec4 cubic1 = vertexBuffer.elements[i1].cubic;
|
||||||
|
vec4 cubic2 = vertexBuffer.elements[i2].cubic;
|
||||||
|
|
||||||
|
int bias0 = is_top_left(p1, p2) ? 0 : -1;
|
||||||
|
int bias1 = is_top_left(p2, p0) ? 0 : -1;
|
||||||
|
int bias2 = is_top_left(p0, p1) ? 0 : -1;
|
||||||
|
|
||||||
|
float w0 = orient2d(p1, p2, samplePoint);
|
||||||
|
float w1 = orient2d(p2, p0, samplePoint);
|
||||||
|
float w2 = orient2d(p0, p1, samplePoint);
|
||||||
|
|
||||||
|
if((int(w0)+bias0) >= 0 && (int(w1)+bias1) >= 0 && (int(w2)+bias2) >= 0)
|
||||||
|
{
|
||||||
|
//TODO check cubic
|
||||||
|
vec4 cubic = (cubic0*w0 + cubic1*w1 + cubic2*w2)/(w0+w1+w2);
|
||||||
|
|
||||||
|
float eps = 0.0001;
|
||||||
|
if(cubic.w*(cubic.x*cubic.x*cubic.x - cubic.y*cubic.z) <= eps)
|
||||||
|
{
|
||||||
|
if(zIndex == currentZIndex)
|
||||||
|
{
|
||||||
|
flipCount++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if((flipCount & 0x01) != 0)
|
||||||
|
{
|
||||||
|
pixelColor = currentColor;
|
||||||
|
}
|
||||||
|
currentColor = pixelColor*(1.-color.a) + color.a*color;
|
||||||
|
currentZIndex = zIndex;
|
||||||
|
flipCount = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if((flipCount & 0x01) != 0)
|
||||||
|
{
|
||||||
|
pixelColor = currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
fragColor = pixelColor;
|
||||||
}
|
}
|
||||||
|
|
|
@ -451,7 +451,7 @@ void mg_push_textured_vertex(mg_canvas_data* canvas, vec2 pos, vec4 cubic, vec2
|
||||||
*(vec2*)(((char*)layout->uvBuffer) + offset*layout->uvStride) = uv;
|
*(vec2*)(((char*)layout->uvBuffer) + offset*layout->uvStride) = uv;
|
||||||
*(mg_color*)(((char*)layout->colorBuffer) + offset*layout->colorStride) = color;
|
*(mg_color*)(((char*)layout->colorBuffer) + offset*layout->colorStride) = color;
|
||||||
*(u32*)(((char*)layout->zIndexBuffer) + offset*layout->zIndexStride) = zIndex;
|
*(u32*)(((char*)layout->zIndexBuffer) + offset*layout->zIndexStride) = zIndex;
|
||||||
*(mp_rect*)(((char*)layout->clipsBuffer) + offset*layout->clipsStride) = canvas->clip;
|
*(mp_rect*)(((char*)layout->clipBuffer) + offset*layout->clipStride) = canvas->clip;
|
||||||
|
|
||||||
canvas->vertexCount++;
|
canvas->vertexCount++;
|
||||||
}
|
}
|
||||||
|
@ -468,7 +468,9 @@ int* mg_reserve_indices(mg_canvas_data* canvas, u32 indexCount)
|
||||||
{
|
{
|
||||||
mg_vertex_layout* layout = &canvas->backend->vertexLayout;
|
mg_vertex_layout* layout = &canvas->backend->vertexLayout;
|
||||||
|
|
||||||
|
//TODO: do something here...
|
||||||
ASSERT(canvas->indexCount + indexCount < layout->maxIndexCount);
|
ASSERT(canvas->indexCount + indexCount < layout->maxIndexCount);
|
||||||
|
|
||||||
int* base = ((int*)layout->indexBuffer) + canvas->indexCount;
|
int* base = ((int*)layout->indexBuffer) + canvas->indexCount;
|
||||||
canvas->indexCount += indexCount;
|
canvas->indexCount += indexCount;
|
||||||
return(base);
|
return(base);
|
||||||
|
@ -2010,13 +2012,12 @@ void mg_render_ellipse_fill_with_z_index(mg_canvas_data* canvas,
|
||||||
{
|
{
|
||||||
//NOTE(martin): draw a filled ellipse by drawing a diamond and 4 corners,
|
//NOTE(martin): draw a filled ellipse by drawing a diamond and 4 corners,
|
||||||
// approximating an arc by a precomputed bezier curve
|
// approximating an arc by a precomputed bezier curve
|
||||||
|
f32 rx = rect.w/2;
|
||||||
|
f32 ry = rect.h/2;
|
||||||
|
|
||||||
u32 baseIndex = mg_vertices_base_index(canvas);
|
u32 baseIndex = mg_vertices_base_index(canvas);
|
||||||
i32* indices = mg_reserve_indices(canvas, 6);
|
i32* indices = mg_reserve_indices(canvas, 6);
|
||||||
|
|
||||||
f32 rx = rect.w/2;
|
|
||||||
f32 ry = rect.h/2;
|
|
||||||
|
|
||||||
//NOTE(martin): inner diamond
|
//NOTE(martin): inner diamond
|
||||||
vec2 points[4] = {{rect.x, rect.y + ry},
|
vec2 points[4] = {{rect.x, rect.y + ry},
|
||||||
{rect.x + rx, rect.y},
|
{rect.x + rx, rect.y},
|
||||||
|
@ -2605,6 +2606,10 @@ mp_rect mg_text_bounding_box(mg_font font, f32 fontSize, str8 text)
|
||||||
mg_canvas_backend* mg_metal_canvas_create(mg_surface surface);
|
mg_canvas_backend* mg_metal_canvas_create(mg_surface surface);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MG_IMPLEMENTS_BACKEND_GLES
|
||||||
|
mg_canvas_backend* mg_gles_canvas_create(mg_surface surface);
|
||||||
|
#endif
|
||||||
|
|
||||||
mg_canvas mg_canvas_create(mg_surface surface)
|
mg_canvas mg_canvas_create(mg_surface surface)
|
||||||
{
|
{
|
||||||
mg_canvas canvas = mg_canvas_nil();
|
mg_canvas canvas = mg_canvas_nil();
|
||||||
|
@ -2620,6 +2625,12 @@ mg_canvas mg_canvas_create(mg_surface surface)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MG_IMPLEMENTS_BACKEND_GLES
|
||||||
|
case MG_BACKEND_GLES:
|
||||||
|
backend = mg_gles_canvas_create(surface);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
case MG_BACKEND_OPENGL:
|
case MG_BACKEND_OPENGL:
|
||||||
canvasData = mg_opengl_canvas_create(surface);
|
canvasData = mg_opengl_canvas_create(surface);
|
||||||
|
|
|
@ -196,25 +196,25 @@ typedef struct mg_vertex_layout
|
||||||
u32 maxVertexCount;
|
u32 maxVertexCount;
|
||||||
u32 maxIndexCount;
|
u32 maxIndexCount;
|
||||||
|
|
||||||
void* posBuffer;
|
char* posBuffer;
|
||||||
u32 posStride;
|
u32 posStride;
|
||||||
|
|
||||||
void* cubicBuffer;
|
char* cubicBuffer;
|
||||||
u32 cubicStride;
|
u32 cubicStride;
|
||||||
|
|
||||||
void* uvBuffer;
|
char* uvBuffer;
|
||||||
u32 uvStride;
|
u32 uvStride;
|
||||||
|
|
||||||
void* colorBuffer;
|
char* colorBuffer;
|
||||||
u32 colorStride;
|
u32 colorStride;
|
||||||
|
|
||||||
void* zIndexBuffer;
|
char* zIndexBuffer;
|
||||||
u32 zIndexStride;
|
u32 zIndexStride;
|
||||||
|
|
||||||
void* clipsBuffer;
|
char* clipBuffer;
|
||||||
u32 clipsStride;
|
u32 clipStride;
|
||||||
|
|
||||||
void* indexBuffer;
|
char* indexBuffer;
|
||||||
u32 indexStride;
|
u32 indexStride;
|
||||||
|
|
||||||
} mg_vertex_layout;
|
} mg_vertex_layout;
|
||||||
|
|
|
@ -235,8 +235,8 @@ void mg_metal_canvas_update_vertex_layout(mg_metal_canvas_backend* backend)
|
||||||
.colorStride = sizeof(mg_vertex),
|
.colorStride = sizeof(mg_vertex),
|
||||||
.zIndexBuffer = vertexBase + offsetof(mg_vertex, zIndex),
|
.zIndexBuffer = vertexBase + offsetof(mg_vertex, zIndex),
|
||||||
.zIndexStride = sizeof(mg_vertex),
|
.zIndexStride = sizeof(mg_vertex),
|
||||||
.clipsBuffer = vertexBase + offsetof(mg_vertex, clip),
|
.clipBuffer = vertexBase + offsetof(mg_vertex, clip),
|
||||||
.clipsStride = sizeof(mg_vertex),
|
.clipStride = sizeof(mg_vertex),
|
||||||
.indexBuffer = [backend->indexBuffer contents],
|
.indexBuffer = [backend->indexBuffer contents],
|
||||||
.indexStride = sizeof(int)};
|
.indexStride = sizeof(int)};
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
#include"win32_app.c"
|
#include"win32_app.c"
|
||||||
// #include"win32_gl_surface.c"
|
// #include"win32_gl_surface.c"
|
||||||
#include"win32_gles_surface.c"
|
#include"win32_gles_surface.c"
|
||||||
|
#include"gles_canvas.c"
|
||||||
#elif defined(OS_MACOS)
|
#elif defined(OS_MACOS)
|
||||||
//NOTE: macos application layer is defined in milepost.m
|
//NOTE: macos application layer is defined in milepost.m
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -40,7 +40,16 @@
|
||||||
#if defined(OS_WIN64) || defined(OS_WIN32)
|
#if defined(OS_WIN64) || defined(OS_WIN32)
|
||||||
#define WIN32_GL_LOADER_API
|
#define WIN32_GL_LOADER_API
|
||||||
// #include"win32_gl_loader.h"
|
// #include"win32_gl_loader.h"
|
||||||
|
|
||||||
|
#if MG_IMPLEMENTS_BACKEND_GLES
|
||||||
|
#include"win32_gles_surface.h"
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MG_IMPLEMENTS_BACKEND_METAL
|
||||||
|
#include"metal_surface.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
// graphics/ui layer
|
// graphics/ui layer
|
||||||
|
|
|
@ -141,8 +141,8 @@ typedef struct mp_app
|
||||||
|
|
||||||
mp_input_state inputState;
|
mp_input_state inputState;
|
||||||
|
|
||||||
mp_key_utf8 keyLabels[256];
|
mp_key_utf8 keyLabels[512];
|
||||||
int keyCodes[256];
|
int keyCodes[512];
|
||||||
int nativeKeys[MP_KEY_COUNT];
|
int nativeKeys[MP_KEY_COUNT];
|
||||||
|
|
||||||
MP_PLATFORM_APP_DATA
|
MP_PLATFORM_APP_DATA
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
//#include <Foundation/Foundation.h>
|
//#include <Foundation/Foundation.h>
|
||||||
#include <QuartzCore/QuartzCore.h>
|
#include <QuartzCore/QuartzCore.h>
|
||||||
|
|
||||||
#include<GLES3/gl32.h>
|
#include<GLES3/gl3.h>
|
||||||
#define EGL_EGLEXT_PROTOTYPES
|
#define EGL_EGLEXT_PROTOTYPES
|
||||||
#include<EGL/egl.h>
|
#include<EGL/egl.h>
|
||||||
#include<EGL/eglext.h>
|
#include<EGL/eglext.h>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
//#include <Foundation/Foundation.h>
|
//#include <Foundation/Foundation.h>
|
||||||
#include <QuartzCore/QuartzCore.h>
|
#include <QuartzCore/QuartzCore.h>
|
||||||
|
|
||||||
#include<GLES3/gl32.h>
|
#include<GLES3/gl3.h>
|
||||||
#define EGL_EGLEXT_PROTOTYPES
|
#define EGL_EGLEXT_PROTOTYPES
|
||||||
#include<EGL/egl.h>
|
#include<EGL/egl.h>
|
||||||
#include<EGL/eglext.h>
|
#include<EGL/eglext.h>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* @revision:
|
* @revision:
|
||||||
*
|
*
|
||||||
*****************************************************************/
|
*****************************************************************/
|
||||||
#include<GLES3/gl32.h>
|
#include<GLES3/gl31.h>
|
||||||
#define EGL_EGLEXT_PROTOTYPES
|
#define EGL_EGLEXT_PROTOTYPES
|
||||||
#include<EGL/egl.h>
|
#include<EGL/egl.h>
|
||||||
#include<EGL/eglext.h>
|
#include<EGL/eglext.h>
|
||||||
|
@ -108,7 +108,7 @@ mg_surface mg_gles_surface_create_for_window(mp_window window)
|
||||||
eglBindAPI(EGL_OPENGL_ES_API);
|
eglBindAPI(EGL_OPENGL_ES_API);
|
||||||
EGLint contextAttributes[] = {
|
EGLint contextAttributes[] = {
|
||||||
EGL_CONTEXT_MAJOR_VERSION_KHR, 3,
|
EGL_CONTEXT_MAJOR_VERSION_KHR, 3,
|
||||||
EGL_CONTEXT_MINOR_VERSION_KHR, 0, //NOTE: Angle can't create a GLES 3.1 context on macOS
|
EGL_CONTEXT_MINOR_VERSION_KHR, 1, //NOTE: Angle can't create a GLES 3.1 context on macOS
|
||||||
EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE,
|
EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE,
|
||||||
EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE,
|
EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE,
|
||||||
EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE, EGL_FALSE,
|
EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE, EGL_FALSE,
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
#ifndef __WIN32_GLES_SURFACE_H_
|
#ifndef __WIN32_GLES_SURFACE_H_
|
||||||
#define __WIN32_GLES_SURFACE_H_
|
#define __WIN32_GLES_SURFACE_H_
|
||||||
|
|
||||||
mg_surface mg_gles_surface_create_for_window(mg_window window);
|
#include"graphics.h"
|
||||||
|
#include"mp_app.h"
|
||||||
|
|
||||||
|
mg_surface mg_gles_surface_create_for_window(mp_window window);
|
||||||
|
|
||||||
#endif // __WIN32_GLES_SURFACE_H_
|
#endif // __WIN32_GLES_SURFACE_H_
|
||||||
|
|
Loading…
Reference in New Issue