working on gles 3.1 canvas on windows
This commit is contained in:
parent
c5ae556f22
commit
8e87837fcc
|
@ -0,0 +1,43 @@
|
|||
import os
|
||||
from datetime import datetime
|
||||
from argparse import ArgumentParser
|
||||
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument("inputFiles", nargs="+")
|
||||
parser.add_argument("-o", "--output")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
output = open(args.output, "w")
|
||||
output.write("/*********************************************************************\n")
|
||||
output.write("*\n")
|
||||
output.write("*\tfile: %s\n" % os.path.basename(args.output))
|
||||
output.write("*\tnote: string literals auto-generated by embed_text.py\n")
|
||||
output.write("*\tdate: %s\n" % datetime.now().strftime("%d/%m%Y"))
|
||||
output.write("*\n")
|
||||
output.write("**********************************************************************/\n")
|
||||
|
||||
outSymbol = (os.path.splitext(os.path.basename(args.output))[0]).upper()
|
||||
|
||||
output.write("#ifndef __%s_H__\n" % outSymbol)
|
||||
output.write("#define __%s_H__\n" % outSymbol)
|
||||
output.write("\n\n")
|
||||
|
||||
for fileName in args.inputFiles:
|
||||
f = open(fileName, "r")
|
||||
lines = f.read().splitlines()
|
||||
|
||||
output.write("//NOTE: string imported from %s\n" % fileName)
|
||||
|
||||
stringName = os.path.splitext(os.path.basename(fileName))[0]
|
||||
output.write("const char* %s = " % stringName)
|
||||
|
||||
for line in lines:
|
||||
output.write("\n\"%s\\n\"" % line)
|
||||
|
||||
output.write(";\n\n")
|
||||
f.close()
|
||||
|
||||
output.write("#endif // __%s_H__\n" % outSymbol)
|
||||
|
||||
output.close()
|
|
@ -0,0 +1,238 @@
|
|||
/************************************************************//**
|
||||
*
|
||||
* @file: gles_canvas.c
|
||||
* @author: Martin Fouilleul
|
||||
* @date: 29/01/2023
|
||||
* @revision:
|
||||
*
|
||||
*****************************************************************/
|
||||
#include"graphics_internal.h"
|
||||
#include"macro_helpers.h"
|
||||
#include"gles_canvas_shaders.h"
|
||||
|
||||
#define LOG_SUBSYSTEM "Graphics"
|
||||
|
||||
typedef struct mg_gles_canvas_backend
|
||||
{
|
||||
mg_canvas_backend interface;
|
||||
mg_surface surface;
|
||||
|
||||
GLint dummyVertexBuffer;
|
||||
GLint vertexBuffer;
|
||||
GLint indexBuffer;
|
||||
GLint program;
|
||||
|
||||
char* indexMapping;
|
||||
char* vertexMapping;
|
||||
|
||||
} mg_gles_canvas_backend;
|
||||
|
||||
mg_gles_surface* mg_gles_canvas_get_surface(mg_gles_canvas_backend* canvas)
|
||||
{
|
||||
mg_gles_surface* res = 0;
|
||||
mg_surface_data* data = mg_surface_data_from_handle(canvas->surface);
|
||||
if(data && data->backend == MG_BACKEND_GLES)
|
||||
{
|
||||
res = (mg_gles_surface*)data;
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
//WARN: dummy test code
|
||||
|
||||
indexCount = 3;
|
||||
*(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) \
|
||||
AlignUpOnPow2(_cat3_(LAYOUT_, prevName, _OFFSET)+_cat3_(LAYOUT_, prevType, _SIZE), _cat3_(LAYOUT_, nextType, _ALIGN))
|
||||
|
||||
enum {
|
||||
LAYOUT_VEC2_SIZE = 8,
|
||||
LAYOUT_VEC2_ALIGN = 8,
|
||||
LAYOUT_VEC4_SIZE = 16,
|
||||
LAYOUT_VEC4_ALIGN = 16,
|
||||
LAYOUT_INT_SIZE = 4,
|
||||
LAYOUT_INT_ALIGN = 4,
|
||||
|
||||
LAYOUT_POS_OFFSET = 0,
|
||||
LAYOUT_CUBIC_OFFSET = LayoutNext(POS, VEC2, VEC4),
|
||||
LAYOUT_UV_OFFSET = LayoutNext(CUBIC, VEC4, VEC2),
|
||||
LAYOUT_COLOR_OFFSET = LayoutNext(UV, VEC2, VEC4),
|
||||
LAYOUT_CLIP_OFFSET = LayoutNext(COLOR, VEC4, VEC4),
|
||||
LAYOUT_ZINDEX_OFFSET = LayoutNext(CLIP, VEC4, INT),
|
||||
|
||||
LAYOUT_VERTEX_ALIGN = 16,
|
||||
LAYOUT_VERTEX_SIZE = LayoutNext(ZINDEX, INT, VERTEX),
|
||||
};
|
||||
|
||||
enum {
|
||||
MG_GLES_CANVAS_DEFAULT_BUFFER_LENGTH = 1<<20,
|
||||
MG_GLES_CANVAS_VERTEX_BUFFER_SIZE = MG_GLES_CANVAS_DEFAULT_BUFFER_LENGTH * LAYOUT_VERTEX_SIZE,
|
||||
MG_GLES_CANVAS_INDEX_BUFFER_SIZE = MG_GLES_CANVAS_DEFAULT_BUFFER_LENGTH * LAYOUT_INT_SIZE,
|
||||
};
|
||||
|
||||
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);
|
||||
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);
|
||||
backend->indexMapping = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, MG_GLES_CANVAS_INDEX_BUFFER_SIZE, GL_MAP_WRITE_BIT);
|
||||
|
||||
backend->interface.vertexLayout = (mg_vertex_layout){
|
||||
.maxVertexCount = MG_GLES_CANVAS_DEFAULT_BUFFER_LENGTH,
|
||||
.maxIndexCount = MG_GLES_CANVAS_DEFAULT_BUFFER_LENGTH,
|
||||
.posBuffer = backend->vertexMapping + LAYOUT_POS_OFFSET,
|
||||
.posStride = LAYOUT_VERTEX_SIZE,
|
||||
.cubicBuffer = backend->vertexMapping + LAYOUT_CUBIC_OFFSET,
|
||||
.cubicStride = LAYOUT_VERTEX_SIZE,
|
||||
.uvBuffer = backend->vertexMapping + LAYOUT_UV_OFFSET,
|
||||
.uvStride = LAYOUT_VERTEX_SIZE,
|
||||
.colorBuffer = backend->vertexMapping + LAYOUT_COLOR_OFFSET,
|
||||
.colorStride = LAYOUT_VERTEX_SIZE,
|
||||
.clipBuffer = backend->vertexMapping + LAYOUT_CLIP_OFFSET,
|
||||
.clipStride = LAYOUT_VERTEX_SIZE,
|
||||
.zIndexBuffer = backend->vertexMapping + LAYOUT_ZINDEX_OFFSET,
|
||||
.zIndexStride = LAYOUT_VERTEX_SIZE,
|
||||
.indexBuffer = backend->indexMapping,
|
||||
.indexStride = LAYOUT_INT_SIZE};
|
||||
}
|
||||
|
||||
void mg_gles_canvas_destroy(mg_canvas_backend* interface)
|
||||
{
|
||||
mg_gles_canvas_backend* backend = (mg_gles_canvas_backend*)interface;
|
||||
|
||||
//TODO
|
||||
}
|
||||
|
||||
void mg_gles_canvas_atlas_upload(mg_canvas_backend* interface, mp_rect rect, u8* bytes)
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
void compile_shader(GLuint shader, const char* source)
|
||||
{
|
||||
glShaderSource(shader, 1, &source, 0);
|
||||
glCompileShader(shader);
|
||||
|
||||
int err = glGetError();
|
||||
if(err)
|
||||
{
|
||||
printf("gl error: %i\n", err);
|
||||
}
|
||||
|
||||
int status = 0;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
||||
if(!status)
|
||||
{
|
||||
char buffer[256];
|
||||
int size = 0;
|
||||
glGetShaderInfoLog(shader, 256, &size, buffer);
|
||||
printf("shader error: %.*s\n", size, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
mg_canvas_backend* mg_gles_canvas_create(mg_surface surface)
|
||||
{
|
||||
mg_gles_canvas_backend* backend = 0;
|
||||
mg_surface_data* surfaceData = mg_surface_data_from_handle(surface);
|
||||
if(surfaceData && surfaceData->backend == MG_BACKEND_GLES)
|
||||
{
|
||||
mg_gles_surface* glesSurface = (mg_gles_surface*)surfaceData;
|
||||
|
||||
backend = malloc_type(mg_gles_canvas_backend);
|
||||
memset(backend, 0, sizeof(mg_gles_canvas_backend));
|
||||
backend->surface = surface;
|
||||
|
||||
//NOTE(martin): setup interface functions
|
||||
backend->interface.destroy = mg_gles_canvas_destroy;
|
||||
backend->interface.drawBuffers = mg_gles_canvas_draw_buffers;
|
||||
backend->interface.atlasUpload = mg_gles_canvas_atlas_upload;
|
||||
|
||||
mg_surface_prepare(surface);
|
||||
|
||||
GLuint vao;
|
||||
glGenVertexArrays(1, &vao);
|
||||
glBindVertexArray(vao);
|
||||
|
||||
glGenBuffers(1, &backend->vertexBuffer);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->vertexBuffer);
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, MG_GLES_CANVAS_VERTEX_BUFFER_SIZE, 0, GL_DYNAMIC_DRAW);
|
||||
|
||||
glGenBuffers(1, &backend->indexBuffer);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->indexBuffer);
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, MG_GLES_CANVAS_INDEX_BUFFER_SIZE, 0, GL_DYNAMIC_DRAW);
|
||||
|
||||
glGenBuffers(1, &backend->dummyVertexBuffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, backend->dummyVertexBuffer);
|
||||
|
||||
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||
unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
backend->program = glCreateProgram();
|
||||
|
||||
compile_shader(vertexShader, gles_canvas_vertex);
|
||||
compile_shader(fragmentShader, gles_canvas_fragment);
|
||||
|
||||
glAttachShader(backend->program, vertexShader);
|
||||
glAttachShader(backend->program, fragmentShader);
|
||||
glLinkProgram(backend->program);
|
||||
|
||||
int status = 0;
|
||||
glGetProgramiv(backend->program, GL_LINK_STATUS, &status);
|
||||
if(!status)
|
||||
{
|
||||
char buffer[256];
|
||||
int size = 0;
|
||||
glGetProgramInfoLog(backend->program, 256, &size, buffer);
|
||||
printf("link error: %.*s\n", size, buffer);
|
||||
}
|
||||
|
||||
glUseProgram(backend->program);
|
||||
|
||||
mg_gles_canvas_update_vertex_layout(backend);
|
||||
}
|
||||
|
||||
return((mg_canvas_backend*)backend);
|
||||
}
|
||||
|
||||
|
||||
#undef LOG_SUBSYSTEM
|
|
@ -0,0 +1,58 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* file: gles_canvas_shaders.h
|
||||
* note: string literals auto-generated by embed_text.py
|
||||
* date: 31/012023
|
||||
*
|
||||
**********************************************************************/
|
||||
#ifndef __GLES_CANVAS_SHADERS_H__
|
||||
#define __GLES_CANVAS_SHADERS_H__
|
||||
|
||||
|
||||
//NOTE: string imported from src\gles_canvas_shaders\gles_canvas_fragment.glsl
|
||||
const char* gles_canvas_fragment =
|
||||
"#version 310 es\n"
|
||||
"\n"
|
||||
"precision mediump float;\n"
|
||||
"layout(std430) buffer;\n"
|
||||
"\n"
|
||||
"struct vertex {\n"
|
||||
" vec2 pos;\n"
|
||||
" vec4 cubic;\n"
|
||||
" vec2 uv;\n"
|
||||
" vec4 color;\n"
|
||||
" vec4 clip;\n"
|
||||
" int zIndex;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"layout(binding = 0) buffer vertexBufferSSBO {\n"
|
||||
" vertex elements[];\n"
|
||||
"} vertexBuffer ;\n"
|
||||
"\n"
|
||||
"layout(binding = 1) buffer indexBufferSSBO {\n"
|
||||
" vec2 elements[];\n"
|
||||
"} indexBuffer ;\n"
|
||||
"\n"
|
||||
"layout(location = 0) uniform int indexCount;\n"
|
||||
"layout(location = 0) out vec4 fragColor;\n"
|
||||
"\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" fragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
//NOTE: string imported from src\gles_canvas_shaders\gles_canvas_vertex.glsl
|
||||
const char* gles_canvas_vertex =
|
||||
"#version 310 es\n"
|
||||
"\n"
|
||||
"precision mediump float;\n"
|
||||
"\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" float x = float(((uint(gl_VertexID) + 2u) / 3u)%2u);\n"
|
||||
" float y = float(((uint(gl_VertexID) + 1u) / 3u)%2u);\n"
|
||||
"\n"
|
||||
" gl_Position = vec4(-1.0f + x*2.0f, -1.0f+y*2.0f, 0.0f, 1.0f);\n"
|
||||
"}\n";
|
||||
|
||||
#endif // __GLES_CANVAS_SHADERS_H__
|
|
@ -0,0 +1,29 @@
|
|||
#version 310 es
|
||||
|
||||
precision mediump float;
|
||||
layout(std430) buffer;
|
||||
|
||||
struct vertex {
|
||||
vec2 pos;
|
||||
vec4 cubic;
|
||||
vec2 uv;
|
||||
vec4 color;
|
||||
vec4 clip;
|
||||
int zIndex;
|
||||
};
|
||||
|
||||
layout(binding = 0) buffer vertexBufferSSBO {
|
||||
vertex elements[];
|
||||
} vertexBuffer ;
|
||||
|
||||
layout(binding = 1) buffer indexBufferSSBO {
|
||||
vec2 elements[];
|
||||
} indexBuffer ;
|
||||
|
||||
layout(location = 0) uniform int indexCount;
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
fragColor = vec4(0.0, 1.0, 0.0, 1.0);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
#version 310 es
|
||||
|
||||
precision mediump float;
|
||||
|
||||
void main()
|
||||
{
|
||||
float x = float(((uint(gl_VertexID) + 2u) / 3u)%2u);
|
||||
float y = float(((uint(gl_VertexID) + 1u) / 3u)%2u);
|
||||
|
||||
gl_Position = vec4(-1.0f + x*2.0f, -1.0f+y*2.0f, 0.0f, 1.0f);
|
||||
}
|
Loading…
Reference in New Issue