ShaderBlock:getShaderCode;

This commit is contained in:
bjorn 2018-08-06 11:46:42 -07:00
parent f95685ba80
commit bdf130800e
3 changed files with 110 additions and 8 deletions

View File

@ -2,11 +2,9 @@
#include "graphics/shader.h"
#include "math/transform.h"
int l_lovrShaderBlockGetOffset(lua_State* L) {
int l_lovrShaderBlockIsWritable(lua_State* L) {
ShaderBlock* block = luax_checktype(L, 1, ShaderBlock);
const char* field = luaL_checkstring(L, 2);
const Uniform* uniform = lovrShaderBlockGetUniform(block, field);
lua_pushinteger(L, uniform->offset);
lua_pushboolean(L, lovrShaderBlockGetType(block) == BLOCK_STORAGE);
return 1;
}
@ -16,9 +14,11 @@ int l_lovrShaderBlockGetSize(lua_State* L) {
return 1;
}
int l_lovrShaderBlockIsWritable(lua_State* L) {
int l_lovrShaderBlockGetOffset(lua_State* L) {
ShaderBlock* block = luax_checktype(L, 1, ShaderBlock);
lua_pushboolean(L, lovrShaderBlockGetType(block) == BLOCK_STORAGE);
const char* field = luaL_checkstring(L, 2);
const Uniform* uniform = lovrShaderBlockGetUniform(block, field);
lua_pushinteger(L, uniform->offset);
return 1;
}
@ -42,10 +42,20 @@ int l_lovrShaderBlockSend(lua_State* L) {
}
}
int l_lovrShaderBlockGetShaderCode(lua_State* L) {
ShaderBlock* block = luax_checktype(L, 1, ShaderBlock);
const char* blockName = luaL_checkstring(L, 2);
size_t length;
char* code = lovrShaderBlockGetShaderCode(block, blockName, &length);
lua_pushlstring(L, code, length);
return 1;
}
const luaL_Reg lovrShaderBlock[] = {
{ "getOffset", l_lovrShaderBlockGetOffset },
{ "getSize", l_lovrShaderBlockGetSize },
{ "isWritable", l_lovrShaderBlockIsWritable },
{ "getSize", l_lovrShaderBlockGetSize },
{ "getOffset", l_lovrShaderBlockGetOffset },
{ "send", l_lovrShaderBlockSend },
{ "getShaderCode", l_lovrShaderBlockGetShaderCode },
{ NULL, NULL }
};

View File

@ -320,6 +320,58 @@ static int getUniformComponents(GLenum type) {
}
}
static size_t getUniformTypeLength(const Uniform* uniform) {
size_t size = 0;
if (uniform->count > 1) {
size += 2 + floor(log10(uniform->count)) + 1; // "[count]"
}
switch (uniform->type) {
case UNIFORM_MATRIX: size += 3; break;
case UNIFORM_FLOAT: size += uniform->components == 1 ? 5 : 4; break;
case UNIFORM_INT: size += uniform->components == 1 ? 3 : 5; break;
default: break;
}
return size;
}
static const char* getUniformTypeName(const Uniform* uniform) {
switch (uniform->type) {
case UNIFORM_FLOAT:
switch (uniform->components) {
case 1: return "float";
case 2: return "vec2";
case 3: return "vec3";
case 4: return "vec4";
}
break;
case UNIFORM_INT:
switch (uniform->components) {
case 1: return "int";
case 2: return "ivec2";
case 3: return "ivec3";
case 4: return "ivec4";
}
break;
case UNIFORM_MATRIX:
switch (uniform->components) {
case 2: return "mat2";
case 3: return "mat3";
case 4: return "mat4";
}
break;
default: break;
}
lovrThrow("Unreachable");
return "";
}
// GPU
static void lovrGpuBindFramebuffer(uint32_t framebuffer) {
@ -1704,6 +1756,45 @@ BlockType lovrShaderBlockGetType(ShaderBlock* block) {
return block->type;
}
char* lovrShaderBlockGetShaderCode(ShaderBlock* block, const char* blockName, size_t* length) {
// Calculate
size_t size = 0;
size_t tab = 2;
size += block->type == BLOCK_UNIFORM ? 7 : 6; // "uniform" || "buffer"
size += 1; // " "
size += strlen(blockName);
size += 3; // " {\n"
for (int i = 0; i < block->uniforms.length; i++) {
size += tab;
size += getUniformTypeLength(&block->uniforms.data[i]);
size += 1; // " "
size += strlen(block->uniforms.data[i].name);
size += 2; // ";\n"
}
size += 3; // "};\n"
// Allocate
char* code = malloc(size + 1);
// Concatenate
char* s = code;
s += sprintf(s, "%s %s {\n", block->type == BLOCK_UNIFORM ? "uniform" : "buffer", blockName);
for (int i = 0; i < block->uniforms.length; i++) {
const Uniform* uniform = &block->uniforms.data[i];
if (uniform->count > 1) {
s += sprintf(s, " %s %s[%d];\n", getUniformTypeName(uniform), uniform->name, uniform->count);
} else {
s += sprintf(s, " %s %s;\n", getUniformTypeName(uniform), uniform->name);
}
}
s += sprintf(s, "};\n");
*s = '\0';
*length = size;
return code;
}
const Uniform* lovrShaderBlockGetUniform(ShaderBlock* block, const char* name) {
int* index = map_get(&block->uniformMap, name);
if (!index) return NULL;

View File

@ -76,6 +76,7 @@ ShaderBlock* lovrShaderBlockCreate(vec_uniform_t* uniforms, BlockType type, Buff
void lovrShaderBlockDestroy(void* ref);
size_t lovrShaderBlockGetSize(ShaderBlock* block);
BlockType lovrShaderBlockGetType(ShaderBlock* block);
char* lovrShaderBlockGetShaderCode(ShaderBlock* block, const char* blockName, size_t* length);
const Uniform* lovrShaderBlockGetUniform(ShaderBlock* block, const char* name);
void* lovrShaderBlockMap(ShaderBlock* block);
void lovrShaderBlockUnmap(ShaderBlock* block);