From 724e0dd6eb7be4776cf9bf9d2f8cdd16ba14b2f7 Mon Sep 17 00:00:00 2001 From: bjorn Date: Fri, 30 Dec 2016 11:57:15 -0800 Subject: [PATCH] Shader arrays; --- src/graphics/shader.c | 19 +++++---- src/graphics/shader.h | 6 +-- src/lovr/types/shader.c | 87 +++++++++++++++++++++++++++++++++++------ 3 files changed, 90 insertions(+), 22 deletions(-) diff --git a/src/graphics/shader.c b/src/graphics/shader.c index 8a047f93..a88da939 100644 --- a/src/graphics/shader.c +++ b/src/graphics/shader.c @@ -17,6 +17,7 @@ const char* lovrShaderFragmentPrefix = "" "uniform vec4 lovrColor; \n" "uniform sampler2D lovrTexture; \n" "in vec2 texCoord; \n" +"in vec4 gl_FragCoord; \n" "out vec4 lovrFragColor; \n" ""; @@ -144,6 +145,10 @@ Shader* lovrShaderCreate(const char* vertexSource, const char* fragmentSource) { for (int i = 0; i < uniformCount; i++) { Uniform uniform; glGetActiveUniform(id, i, bufferSize, NULL, &uniform.count, &uniform.type, uniform.name); + char* subscript = strchr(uniform.name, '['); + if (subscript) { + *subscript = '\0'; + } uniform.location = glGetUniformLocation(id, uniform.name); uniform.index = i; map_set(&shader->uniforms, uniform.name, uniform); @@ -202,7 +207,7 @@ void lovrShaderBind(Shader* shader, mat4 transform, mat4 projection, unsigned in LOVR_COLOR_B(color) / 255.f, LOVR_COLOR_A(color) / 255.f }; - lovrShaderSendFloatVec4(shader, uniformId, c); + lovrShaderSendFloatVec4(shader, uniformId, 1, c); shader->color = color; } } @@ -240,16 +245,16 @@ void lovrShaderSendFloat(Shader* shader, int id, float value) { glUniform1f(id, value); } -void lovrShaderSendFloatVec2(Shader* shader, int id, float* vector) { - glUniform2fv(id, 1, vector); +void lovrShaderSendFloatVec2(Shader* shader, int id, int count, float* vector) { + glUniform2fv(id, count, vector); } -void lovrShaderSendFloatVec3(Shader* shader, int id, float* vector) { - glUniform3fv(id, 1, vector); +void lovrShaderSendFloatVec3(Shader* shader, int id, int count, float* vector) { + glUniform3fv(id, count, vector); } -void lovrShaderSendFloatVec4(Shader* shader, int id, float* vector) { - glUniform4fv(id, 1, vector); +void lovrShaderSendFloatVec4(Shader* shader, int id, int count, float* vector) { + glUniform4fv(id, count, vector); } void lovrShaderSendFloatMat2(Shader* shader, int id, float* matrix) { diff --git a/src/graphics/shader.h b/src/graphics/shader.h index 16018d74..f2e4d021 100644 --- a/src/graphics/shader.h +++ b/src/graphics/shader.h @@ -50,9 +50,9 @@ int lovrShaderGetUniformId(Shader* shader, const char* name); int lovrShaderGetUniformType(Shader* shader, const char* name, GLenum* type, int* count); void lovrShaderSendInt(Shader* shader, int id, int value); void lovrShaderSendFloat(Shader* shader, int id, float value); -void lovrShaderSendFloatVec2(Shader* shader, int id, float* vector); -void lovrShaderSendFloatVec3(Shader* shader, int id, float* vector); -void lovrShaderSendFloatVec4(Shader* shader, int id, float* vector); +void lovrShaderSendFloatVec2(Shader* shader, int id, int count, float* vector); +void lovrShaderSendFloatVec3(Shader* shader, int id, int count,float* vector); +void lovrShaderSendFloatVec4(Shader* shader, int id, int count, float* vector); void lovrShaderSendFloatMat2(Shader* shader, int id, float* matrix); void lovrShaderSendFloatMat3(Shader* shader, int id, float* matrix); void lovrShaderSendFloatMat4(Shader* shader, int id, float* matrix); diff --git a/src/lovr/types/shader.c b/src/lovr/types/shader.c index 59a44942..6846696f 100644 --- a/src/lovr/types/shader.c +++ b/src/lovr/types/shader.c @@ -8,6 +8,7 @@ const luaL_Reg lovrShader[] = { int l_lovrShaderSend(lua_State* L) { Shader* shader = luax_checktype(L, 1, Shader); const char* name = luaL_checkstring(L, 2); + lua_settop(L, 3); int id = lovrShaderGetUniformId(shader, name); if (id == -1) { @@ -19,6 +20,9 @@ int l_lovrShaderSend(lua_State* L) { lovrShaderGetUniformType(shader, name, &type, &size); lovrShaderBind(shader, shader->transform, shader->projection, shader->color, 0); // Hmm float data[16]; + int n; + vec_float_t values; + vec_init(&values); switch (type) { case GL_INT: @@ -31,32 +35,89 @@ int l_lovrShaderSend(lua_State* L) { case GL_FLOAT_VEC2: luaL_checktype(L, 3, LUA_TTABLE); - for (int i = 0; i < 2; i++) { - lua_rawgeti(L, 3, i + 1); - data[i] = lua_tonumber(L, -1); + lua_rawgeti(L, 3, 1); + if (!lua_istable(L, -1)) { + lua_newtable(L); + lua_pushvalue(L, 3); + lua_rawseti(L, -2, 1); + } else { lua_pop(L, 1); } - lovrShaderSendFloatVec2(shader, id, data); + + n = lua_objlen(L, -1); + if (n < size) { + return luaL_error(L, "Expected %d vec3s, got %d", size, n); + } + + for (int i = 0; i < size; i++) { + lua_rawgeti(L, -1, i + 1); + for (int j = 0; j < 2; j++) { + lua_rawgeti(L, -1, j + 1); + vec_push(&values, lua_tonumber(L, -1)); + lua_pop(L, 1); + } + lua_pop(L, 1); + } + + lovrShaderSendFloatVec2(shader, id, size, values.data); break; case GL_FLOAT_VEC3: luaL_checktype(L, 3, LUA_TTABLE); - for (int i = 0; i < 3; i++) { - lua_rawgeti(L, 3, i + 1); - data[i] = lua_tonumber(L, -1); + lua_rawgeti(L, 3, 1); + if (!lua_istable(L, -1)) { + lua_newtable(L); + lua_pushvalue(L, 3); + lua_rawseti(L, -2, 1); + } else { lua_pop(L, 1); } - lovrShaderSendFloatVec3(shader, id, data); + + n = lua_objlen(L, -1); + if (n < size) { + return luaL_error(L, "Expected %d vec3s, got %d", size, n); + } + + for (int i = 0; i < size; i++) { + lua_rawgeti(L, -1, i + 1); + for (int j = 0; j < 3; j++) { + lua_rawgeti(L, -1, j + 1); + vec_push(&values, lua_tonumber(L, -1)); + lua_pop(L, 1); + } + lua_pop(L, 1); + } + + lovrShaderSendFloatVec3(shader, id, size, values.data); break; case GL_FLOAT_VEC4: luaL_checktype(L, 3, LUA_TTABLE); - for (int i = 0; i < 4; i++) { - lua_rawgeti(L, 3, i + 1); - data[i] = lua_tonumber(L, -1); + lua_rawgeti(L, 3, 1); + if (!lua_istable(L, -1)) { + lua_newtable(L); + lua_pushvalue(L, 3); + lua_rawseti(L, -2, 1); + } else { lua_pop(L, 1); } - lovrShaderSendFloatVec4(shader, id, data); + + n = lua_objlen(L, -1); + if (n < size) { + return luaL_error(L, "Expected %d vec3s, got %d", size, n); + } + + for (int i = 0; i < size; i++) { + lua_rawgeti(L, -1, i + 1); + for (int j = 0; j < 4; j++) { + lua_rawgeti(L, -1, j + 1); + vec_push(&values, lua_tonumber(L, -1)); + lua_pop(L, 1); + } + lua_pop(L, 1); + } + + lovrShaderSendFloatVec4(shader, id, size, values.data); break; case GL_FLOAT_MAT2: @@ -93,5 +154,7 @@ int l_lovrShaderSend(lua_State* L) { return luaL_error(L, "Unknown uniform type %d", type); } + vec_deinit(&values); + return 0; }