From 5c4c8ce50516904f506f8f10fe0b17883f2e8fff Mon Sep 17 00:00:00 2001 From: martinfouilleul Date: Tue, 4 Jul 2023 15:59:45 +0200 Subject: [PATCH] [wip, win32, canvas] adding back textures --- examples/image/main.c | 7 +++- examples/perf_text/main.c | 5 +++ src/gl_canvas.c | 71 +++++++++++++++++------------------- src/glsl_shaders/raster.glsl | 23 ++++++++++-- 4 files changed, 64 insertions(+), 42 deletions(-) diff --git a/examples/image/main.c b/examples/image/main.c index e54af88..6452a92 100644 --- a/examples/image/main.c +++ b/examples/image/main.c @@ -6,6 +6,7 @@ * @revision: * *****************************************************************/ +#include #include #include #include @@ -27,6 +28,11 @@ int main() //NOTE: create surface mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS); + if(mg_surface_is_nil(surface)) + { + log_error("couldn't create surface\n"); + return(-1); + } mg_surface_swap_interval(surface, 0); //NOTE: create canvas @@ -78,7 +84,6 @@ int main() mg_matrix_push((mg_mat2x3){0.707, -0.707, 200, 0.707, 0.707, 100}); - mg_set_image(image); mg_set_image_source_region((mp_rect){500, 500, 2000, 1400}); diff --git a/examples/perf_text/main.c b/examples/perf_text/main.c index af63a14..52328eb 100644 --- a/examples/perf_text/main.c +++ b/examples/perf_text/main.c @@ -107,6 +107,11 @@ int main() //NOTE: create surface, canvas and font mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS); + if(mg_surface_is_nil(surface)) + { + log_error("couldn't create surface\n"); + return(-1); + } mg_surface_swap_interval(surface, 0); mg_canvas canvas = mg_canvas_create(); diff --git a/src/gl_canvas.c b/src/gl_canvas.c index 045c64d..a23c327 100644 --- a/src/gl_canvas.c +++ b/src/gl_canvas.c @@ -97,6 +97,8 @@ typedef struct mg_gl_tile_queue } mg_gl_tile_queue; +//////////////////////////////////////////////////////////// + typedef struct mg_gl_encoding_context { int glEltCount; @@ -109,8 +111,6 @@ typedef struct mg_gl_encoding_context vec4 pathUserExtents; } mg_gl_encoding_context; -//////////////////////////////////////////////////////////// - enum { // MG_GL_INPUT_BUFFERS_COUNT = 3, @@ -134,8 +134,6 @@ typedef struct mg_gl_canvas_backend GLuint outTexture; - int pathBufferOffset; - int elementBufferOffset; int bufferIndex; //TODO buffer semaphore... @@ -876,12 +874,18 @@ void mg_gl_render_batch(mg_gl_canvas_backend* backend, f32 scale) { //NOTE: send the buffers + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // this is wrong, we should send the part we just wrote, which doesn't necessarily start at the begining of the buffer + // or, alternatively, we should always write at the beginning of our data buffer and send from there... + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->pathBuffer); glBufferData(GL_SHADER_STORAGE_BUFFER, LAYOUT_PATH_SIZE*pathCount, backend->pathBufferData, GL_STREAM_DRAW); glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->elementBuffer); glBufferData(GL_SHADER_STORAGE_BUFFER, LAYOUT_PATH_ELT_SIZE*eltCount, backend->elementBufferData, GL_STREAM_DRAW); + // --> this always bind the begining of the buffer, with the wrong pathCount/eltCount... + //NOTE: clear counters int zero = 0; glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->segmentCountBuffer); @@ -912,7 +916,7 @@ void mg_gl_render_batch(mg_gl_canvas_backend* backend, for(int i=0; ipathBufferOffset + i*sizeof(mg_gl_path); + int pathOffset = i*sizeof(mg_gl_path); int pathQueueOffset = i*sizeof(mg_gl_path_queue); int count = minimum(maxWorkGroupCount, pathCount-i); @@ -938,7 +942,7 @@ void mg_gl_render_batch(mg_gl_canvas_backend* backend, for(int i=0; ielementBufferOffset + i*sizeof(mg_gl_path_elt); + int offset = i*sizeof(mg_gl_path_elt); int count = minimum(maxWorkGroupCount, eltCount-i); glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, backend->elementBuffer, offset, count*sizeof(mg_gl_path_elt)); @@ -966,7 +970,7 @@ void mg_gl_render_batch(mg_gl_canvas_backend* backend, //NOTE: merge pass glUseProgram(backend->merge); - glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, backend->pathBuffer, backend->pathBufferOffset, pathCount*sizeof(mg_gl_path)); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, backend->pathBuffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, backend->pathQueueBuffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, backend->tileQueueBuffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, backend->tileOpCountBuffer); @@ -983,7 +987,7 @@ void mg_gl_render_batch(mg_gl_canvas_backend* backend, //NOTE: raster pass glUseProgram(backend->raster); - glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, backend->pathBuffer, backend->pathBufferOffset, pathCount*sizeof(mg_gl_path)); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, backend->pathBuffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, backend->segmentCountBuffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, backend->segmentBuffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, backend->tileOpBuffer); @@ -992,32 +996,19 @@ void mg_gl_render_batch(mg_gl_canvas_backend* backend, glUniform1f(0, scale); glUniform1i(1, backend->msaaCount); - int err = glGetError(); - if(err) - { - log_error("gl error %i\n", err); - } - log_info("eltCount = %i\n", eltCount); - - ASSERT(eltCount != 0); - glBindImageTexture(0, backend->outTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8); - /* if(image) { - //TODO: make sure this image belongs to that context mg_gl_image* glImage = (mg_gl_image*)image; glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, glImage->texture); - glUniform1ui(3, 1); + glUniform1ui(2, 1); } else { - glUniform1ui(3, 0); + glUniform1ui(2, 0); } - */ - glDispatchCompute(nTilesX, nTilesY, 1); //NOTE: blit pass @@ -1028,6 +1019,12 @@ void mg_gl_render_batch(mg_gl_canvas_backend* backend, glUniform1i(0, 0); glDrawArrays(GL_TRIANGLES, 0, 6); + + int err = glGetError(); + if(err) + { + log_error("gl error %i\n", err); + } } ///////////////////////////////////////////////////////////////////////// @@ -1044,8 +1041,6 @@ void mg_gl_canvas_render(mg_canvas_backend* interface, { mg_gl_canvas_backend* backend = (mg_gl_canvas_backend*)interface; - //TODO rolling buffer - //TODO update screen tiles buffer size mg_wgl_surface* surface = backend->surface; mp_rect frame = surface->interface.getFrame((mg_surface_data*)surface); @@ -1064,12 +1059,12 @@ void mg_gl_canvas_render(mg_canvas_backend* interface, } //NOTE: clear screen and reset input buffer offsets + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a); glClear(GL_COLOR_BUFFER_BIT); - backend->pathBufferOffset = 0; - backend->elementBufferOffset = 0; - //NOTE: encode and render batches int pathCount = 0; vec2 currentPos = {0}; @@ -1098,12 +1093,8 @@ void mg_gl_canvas_render(mg_canvas_backend* interface, viewportSize, scale); - backend->pathBufferOffset += pathCount * sizeof(mg_gl_path); - backend->elementBufferOffset += context.glEltCount * sizeof(mg_gl_path_elt); pathCount = 0; context.glEltCount = 0; - context.elementBufferData = (mg_gl_path_elt*)((char*)backend->elementBufferData + backend->elementBufferOffset); - context.pathBufferData = (mg_gl_path*)((char*)backend->pathBufferData + backend->pathBufferOffset); } currentImage = primitive->attributes.image; @@ -1203,15 +1194,19 @@ void mg_gl_canvas_render(mg_canvas_backend* interface, uvTransform = mg_mat2x3_mul_m(uvTransform, userToDestRegion); uvTransform = mg_mat2x3_mul_m(uvTransform, screenToUser); + //NOTE: mat3 std430 layout is an array of vec3, which are padded to _vec4_ alignment path->uvTransform[0] = uvTransform.m[0]/scale; path->uvTransform[1] = uvTransform.m[3]/scale; path->uvTransform[2] = 0; - path->uvTransform[3] = uvTransform.m[1]/scale; - path->uvTransform[4] = uvTransform.m[4]/scale; - path->uvTransform[5] = 0; - path->uvTransform[6] = uvTransform.m[2]; - path->uvTransform[7] = uvTransform.m[5]; - path->uvTransform[8] = 1; + path->uvTransform[3] = 0; + path->uvTransform[4] = uvTransform.m[1]/scale; + path->uvTransform[5] = uvTransform.m[4]/scale; + path->uvTransform[6] = 0; + path->uvTransform[7] = 0; + path->uvTransform[8] = uvTransform.m[2]; + path->uvTransform[9] = uvTransform.m[5]; + path->uvTransform[10] = 1; + path->uvTransform[11] = 0; } } } diff --git a/src/glsl_shaders/raster.glsl b/src/glsl_shaders/raster.glsl index 8344821..a137db9 100644 --- a/src/glsl_shaders/raster.glsl +++ b/src/glsl_shaders/raster.glsl @@ -31,9 +31,10 @@ layout(binding = 4) restrict readonly buffer screenTilesBufferSSBO layout(location = 0) uniform float scale; layout(location = 1) uniform int msaaSampleCount; +layout(location = 2) uniform uint useTexture; layout(rgba8, binding = 0) uniform restrict writeonly image2D outTexture; - +layout(binding = 1) uniform sampler2D srcTexture; void main() { @@ -44,13 +45,13 @@ void main() ivec2 pixelCoord = ivec2(gl_WorkGroupID.xy*uvec2(16, 16) + gl_LocalInvocationID.xy); vec2 centerCoord = vec2(pixelCoord) + vec2(0.5, 0.5); - /* +/* if((pixelCoord.x % 16) == 0 || (pixelCoord.y % 16) == 0) { imageStore(outTexture, pixelCoord, vec4(0, 0, 0, 1)); return; } - */ +*/ vec2 sampleCoords[MG_GL_MAX_SAMPLE_COUNT] = { centerCoord + vec2(1, 3)/16, @@ -107,6 +108,14 @@ void main() if(filled) { vec4 nextColor = pathColor; + if(useTexture != 0) + { + vec3 ph = vec3(sampleCoord.xy, 1); + vec2 uv = (pathBuffer.elements[pathIndex].uvTransform * ph).xy; + vec4 texColor = texture(srcTexture, uv); + texColor.rgb *= texColor.a; + nextColor *= texColor; + } color[sampleIndex] = color[sampleIndex]*(1-nextColor.a) + nextColor; } } @@ -167,6 +176,14 @@ void main() if(filled) { vec4 nextColor = pathColor; + if(useTexture != 0) + { + vec3 ph = vec3(sampleCoord.xy, 1); + vec2 uv = (pathBuffer.elements[pathIndex].uvTransform * ph).xy; + vec4 texColor = texture(srcTexture, uv); + texColor.rgb *= texColor.a; + nextColor *= texColor; + } color[sampleIndex] = color[sampleIndex]*(1-nextColor.a) + nextColor; } }