diff --git a/src/k3.h b/src/k3.h index 9e4cfb3..381a835 100644 --- a/src/k3.h +++ b/src/k3.h @@ -6,8 +6,13 @@ #include #include +#ifdef k3_MULTITHREAD +#include +#endif + void k3Init(); void k3Resize(uint16_t width, uint16_t height); +void k3Update(); enum k3TexType { k3_DIFFUSE, k3_NORMAL, k3_DISPLACEMENT, k3_EMISSION, k3_ROUGHNESS, k3_ALPHA, diff --git a/src/k3batch.c b/src/k3batch.c index c2fa228..f3cdd5d 100644 --- a/src/k3batch.c +++ b/src/k3batch.c @@ -12,6 +12,8 @@ struct S { }; static struct k3Tex *activeTex; +static float activeBorderRadius; + static size_t SCount, SCapacity; static struct S *S; @@ -25,21 +27,33 @@ void k3BatchInit() { "in vec2 a_pos;\n" "in vec2 a_uv;\n" "in vec4 a_color;\n" + "in vec2 a_size;\n" "out vec2 v_uv;\n" "out vec4 v_color;\n" + "out vec2 v_size;\n" "void main() {\n" " v_uv = a_uv;\n" " v_color = a_color;\n" + " v_size = a_size;\n" " gl_Position = vec4(vec2(a_pos.x / 3600.0, a_pos.y / 2025.0) * 2.0 - 1.0, 0.0, 1.0);\n" "}\n" , NULL), k3ShaderGLSLF( "#version 330\n" "uniform sampler2D u_tex;\n" "uniform float u_texuse;\n" + "uniform float u_borderradius;\n" "in vec2 v_uv;\n" "in vec4 v_color;\n" + "in vec2 v_size;\n" "out vec4 fragcolor;\n" "void main() {\n" + " vec2 sz = v_size / 2.0;\n" + " vec2 c = abs(v_uv * 2.0 - 1.0);\n" + " c = c * (sz + u_borderradius);\n" + " c = max(c - sz, 0.0);\n" + " if(length(c) > u_borderradius) {\n" + " discard;\n" + " }\n" " fragcolor = mix(vec4(1, 1, 1, 1), texture2D(u_tex, v_uv), u_texuse) * v_color;\n" "}\n" , NULL), NULL); @@ -48,10 +62,11 @@ void k3BatchInit() { } } -void k3BatchAdd(struct k3Tex *tex, struct k3RectF src, struct k3RectF dst, float rot, vec4 color) { - if(activeTex != tex) { +void k3BatchAdd(struct k3Tex *tex, struct k3RectF src, struct k3RectF dst, float rot, vec4 color, float borderRadius) { + if(activeTex != tex || borderRadius != activeBorderRadius) { k3BatchFlush(); activeTex = tex; + activeBorderRadius = borderRadius; } if(SCount == SCapacity) { @@ -73,6 +88,8 @@ void k3BatchAdd(struct k3Tex *tex, struct k3RectF src, struct k3RectF dst, float } void k3BatchFlush() { + if(!S) return; + if(!k3IsCore) { glDisable(GL_NORMALIZE); @@ -108,89 +125,107 @@ void k3BatchFlush() { if(k3IsCore) { glUseProgram((GLuint) coreProg); - float *farr = alloca(SCount * 48 * sizeof(*farr)); + float *farr = alloca(SCount * 60 * sizeof(*farr)); struct S *s = S; for(size_t i = 0; i < SCount; i++) { - farr[i * 48 + 0] = s->dst.x; - farr[i * 48 + 1] = s->dst.y; - farr[i * 48 + 2] = s->src.x; - farr[i * 48 + 3] = s->src.y + s->src.h; - farr[i * 48 + 4] = s->color[0]; - farr[i * 48 + 5] = s->color[1]; - farr[i * 48 + 6] = s->color[2]; - farr[i * 48 + 7] = s->color[3]; + farr[i * 60 + 0] = s->dst.x; + farr[i * 60 + 1] = s->dst.y; + farr[i * 60 + 2] = s->src.x; + farr[i * 60 + 3] = s->src.y + s->src.h; + farr[i * 60 + 4] = s->color[0]; + farr[i * 60 + 5] = s->color[1]; + farr[i * 60 + 6] = s->color[2]; + farr[i * 60 + 7] = s->color[3]; + farr[i * 60 + 8] = s->dst.w; + farr[i * 60 + 9] = s->dst.h; - farr[i * 48 + 8] = s->dst.x + s->dst.w; - farr[i * 48 + 9] = s->dst.y; - farr[i * 48 + 10] = s->src.x + s->src.w; - farr[i * 48 + 11] = s->src.y + s->src.h; - farr[i * 48 + 12] = s->color[0]; - farr[i * 48 + 13] = s->color[1]; - farr[i * 48 + 14] = s->color[2]; - farr[i * 48 + 15] = s->color[3]; + farr[i * 60 + 10] = s->dst.x + s->dst.w; + farr[i * 60 + 11] = s->dst.y; + farr[i * 60 + 12] = s->src.x + s->src.w; + farr[i * 60 + 13] = s->src.y + s->src.h; + farr[i * 60 + 14] = s->color[0]; + farr[i * 60 + 15] = s->color[1]; + farr[i * 60 + 16] = s->color[2]; + farr[i * 60 + 17] = s->color[3]; + farr[i * 60 + 18] = s->dst.w; + farr[i * 60 + 19] = s->dst.h; - farr[i * 48 + 16] = s->dst.x + s->dst.w; - farr[i * 48 + 17] = s->dst.y + s->dst.h; - farr[i * 48 + 18] = s->src.x + s->src.w; - farr[i * 48 + 19] = s->src.y; - farr[i * 48 + 20] = s->color[0]; - farr[i * 48 + 21] = s->color[1]; - farr[i * 48 + 22] = s->color[2]; - farr[i * 48 + 23] = s->color[3]; + farr[i * 60 + 20] = s->dst.x + s->dst.w; + farr[i * 60 + 21] = s->dst.y + s->dst.h; + farr[i * 60 + 22] = s->src.x + s->src.w; + farr[i * 60 + 23] = s->src.y; + farr[i * 60 + 24] = s->color[0]; + farr[i * 60 + 25] = s->color[1]; + farr[i * 60 + 26] = s->color[2]; + farr[i * 60 + 27] = s->color[3]; + farr[i * 60 + 28] = s->dst.w; + farr[i * 60 + 29] = s->dst.h; - farr[i * 48 + 24] = s->dst.x; - farr[i * 48 + 25] = s->dst.y; - farr[i * 48 + 26] = s->src.x; - farr[i * 48 + 27] = s->src.y + s->src.h; - farr[i * 48 + 28] = s->color[0]; - farr[i * 48 + 29] = s->color[1]; - farr[i * 48 + 30] = s->color[2]; - farr[i * 48 + 31] = s->color[3]; + farr[i * 60 + 30] = s->dst.x; + farr[i * 60 + 31] = s->dst.y; + farr[i * 60 + 32] = s->src.x; + farr[i * 60 + 33] = s->src.y + s->src.h; + farr[i * 60 + 34] = s->color[0]; + farr[i * 60 + 35] = s->color[1]; + farr[i * 60 + 36] = s->color[2]; + farr[i * 60 + 37] = s->color[3]; + farr[i * 60 + 38] = s->dst.w; + farr[i * 60 + 39] = s->dst.h; - farr[i * 48 + 32] = s->dst.x + s->dst.w; - farr[i * 48 + 33] = s->dst.y + s->dst.h; - farr[i * 48 + 34] = s->src.x + s->src.w; - farr[i * 48 + 35] = s->src.y; - farr[i * 48 + 36] = s->color[0]; - farr[i * 48 + 37] = s->color[1]; - farr[i * 48 + 38] = s->color[2]; - farr[i * 48 + 39] = s->color[3]; + farr[i * 60 + 40] = s->dst.x + s->dst.w; + farr[i * 60 + 41] = s->dst.y + s->dst.h; + farr[i * 60 + 42] = s->src.x + s->src.w; + farr[i * 60 + 43] = s->src.y; + farr[i * 60 + 44] = s->color[0]; + farr[i * 60 + 45] = s->color[1]; + farr[i * 60 + 46] = s->color[2]; + farr[i * 60 + 47] = s->color[3]; + farr[i * 60 + 48] = s->dst.w; + farr[i * 60 + 49] = s->dst.h; - farr[i * 48 + 40] = s->dst.x; - farr[i * 48 + 41] = s->dst.y + s->dst.h; - farr[i * 48 + 42] = s->src.x; - farr[i * 48 + 43] = s->src.y; - farr[i * 48 + 44] = s->color[0]; - farr[i * 48 + 45] = s->color[1]; - farr[i * 48 + 46] = s->color[2]; - farr[i * 48 + 47] = s->color[3]; + farr[i * 60 + 50] = s->dst.x; + farr[i * 60 + 51] = s->dst.y + s->dst.h; + farr[i * 60 + 52] = s->src.x; + farr[i * 60 + 53] = s->src.y; + farr[i * 60 + 54] = s->color[0]; + farr[i * 60 + 55] = s->color[1]; + farr[i * 60 + 56] = s->color[2]; + farr[i * 60 + 57] = s->color[3]; + farr[i * 60 + 58] = s->dst.w; + farr[i * 60 + 59] = s->dst.h; s++; } glBindBufferARB(GL_ARRAY_BUFFER_ARB, coreVBO); - glBufferDataARB(GL_ARRAY_BUFFER_ARB, SCount * 48 * sizeof(*farr), farr, GL_DYNAMIC_DRAW); + glBufferDataARB(GL_ARRAY_BUFFER_ARB, SCount * 60 * sizeof(*farr), farr, GL_DYNAMIC_DRAW); glUniform1f(glGetUniformLocation((GLuint) coreProg, "u_texuse"), !!activeTex); + glUniform1f(glGetUniformLocation((GLuint) coreProg, "u_borderradius"), activeBorderRadius); + GLint aPos = glGetAttribLocation((GLuint) coreProg, "a_pos"); GLint aUv = glGetAttribLocation((GLuint) coreProg, "a_uv"); GLint aColor = glGetAttribLocation((GLuint) coreProg, "a_color"); + GLint aSize = glGetAttribLocation((GLuint) coreProg, "a_size"); glEnableVertexAttribArray(aPos); glEnableVertexAttribArray(aUv); glEnableVertexAttribArray(aColor); + glEnableVertexAttribArray(aSize); - glVertexAttribPointer(aPos, 2, GL_FLOAT, GL_FALSE, 32, (void*) 0); - glVertexAttribPointer(aUv, 2, GL_FLOAT, GL_FALSE, 32, (void*) 8); - glVertexAttribPointer(aColor, 4, GL_FLOAT, GL_FALSE, 32, (void*) 16); + glVertexAttribPointer(aPos, 2, GL_FLOAT, GL_FALSE, 40, (void*) 0); + glVertexAttribPointer(aUv, 2, GL_FLOAT, GL_FALSE, 40, (void*) 8); + glVertexAttribPointer(aColor, 4, GL_FLOAT, GL_FALSE, 40, (void*) 16); + glVertexAttribPointer(aSize, 2, GL_FLOAT, GL_FALSE, 40, (void*) 32); glDrawArrays(GL_TRIANGLES, 0, SCount * 6); glDisableVertexAttribArray(aPos); glDisableVertexAttribArray(aUv); glDisableVertexAttribArray(aColor); + glDisableVertexAttribArray(aSize); } else { if(GLAD_GL_ARB_shading_language_100) { glUseProgramObjectARB(0); diff --git a/src/k3batch.h b/src/k3batch.h index f668772..91b4030 100644 --- a/src/k3batch.h +++ b/src/k3batch.h @@ -10,5 +10,5 @@ struct k3RectF { float h; }; -void k3BatchAdd(struct k3Tex *tex, struct k3RectF src, struct k3RectF dst, float rot, vec4 color); -void k3BatchFlush(); \ No newline at end of file +void k3BatchAdd(struct k3Tex *tex, struct k3RectF src, struct k3RectF dst, float rot, vec4 color, float borderRadius); +void k3BatchFlush();