mirror of https://github.com/bjornbytes/lovr.git
ShaderBlock:getShaderCode;
This commit is contained in:
parent
f95685ba80
commit
bdf130800e
|
@ -2,11 +2,9 @@
|
||||||
#include "graphics/shader.h"
|
#include "graphics/shader.h"
|
||||||
#include "math/transform.h"
|
#include "math/transform.h"
|
||||||
|
|
||||||
int l_lovrShaderBlockGetOffset(lua_State* L) {
|
int l_lovrShaderBlockIsWritable(lua_State* L) {
|
||||||
ShaderBlock* block = luax_checktype(L, 1, ShaderBlock);
|
ShaderBlock* block = luax_checktype(L, 1, ShaderBlock);
|
||||||
const char* field = luaL_checkstring(L, 2);
|
lua_pushboolean(L, lovrShaderBlockGetType(block) == BLOCK_STORAGE);
|
||||||
const Uniform* uniform = lovrShaderBlockGetUniform(block, field);
|
|
||||||
lua_pushinteger(L, uniform->offset);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,9 +14,11 @@ int l_lovrShaderBlockGetSize(lua_State* L) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int l_lovrShaderBlockIsWritable(lua_State* L) {
|
int l_lovrShaderBlockGetOffset(lua_State* L) {
|
||||||
ShaderBlock* block = luax_checktype(L, 1, ShaderBlock);
|
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;
|
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[] = {
|
const luaL_Reg lovrShaderBlock[] = {
|
||||||
{ "getOffset", l_lovrShaderBlockGetOffset },
|
|
||||||
{ "getSize", l_lovrShaderBlockGetSize },
|
|
||||||
{ "isWritable", l_lovrShaderBlockIsWritable },
|
{ "isWritable", l_lovrShaderBlockIsWritable },
|
||||||
|
{ "getSize", l_lovrShaderBlockGetSize },
|
||||||
|
{ "getOffset", l_lovrShaderBlockGetOffset },
|
||||||
{ "send", l_lovrShaderBlockSend },
|
{ "send", l_lovrShaderBlockSend },
|
||||||
|
{ "getShaderCode", l_lovrShaderBlockGetShaderCode },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
// GPU
|
||||||
|
|
||||||
static void lovrGpuBindFramebuffer(uint32_t framebuffer) {
|
static void lovrGpuBindFramebuffer(uint32_t framebuffer) {
|
||||||
|
@ -1704,6 +1756,45 @@ BlockType lovrShaderBlockGetType(ShaderBlock* block) {
|
||||||
return block->type;
|
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) {
|
const Uniform* lovrShaderBlockGetUniform(ShaderBlock* block, const char* name) {
|
||||||
int* index = map_get(&block->uniformMap, name);
|
int* index = map_get(&block->uniformMap, name);
|
||||||
if (!index) return NULL;
|
if (!index) return NULL;
|
||||||
|
|
|
@ -76,6 +76,7 @@ ShaderBlock* lovrShaderBlockCreate(vec_uniform_t* uniforms, BlockType type, Buff
|
||||||
void lovrShaderBlockDestroy(void* ref);
|
void lovrShaderBlockDestroy(void* ref);
|
||||||
size_t lovrShaderBlockGetSize(ShaderBlock* block);
|
size_t lovrShaderBlockGetSize(ShaderBlock* block);
|
||||||
BlockType lovrShaderBlockGetType(ShaderBlock* block);
|
BlockType lovrShaderBlockGetType(ShaderBlock* block);
|
||||||
|
char* lovrShaderBlockGetShaderCode(ShaderBlock* block, const char* blockName, size_t* length);
|
||||||
const Uniform* lovrShaderBlockGetUniform(ShaderBlock* block, const char* name);
|
const Uniform* lovrShaderBlockGetUniform(ShaderBlock* block, const char* name);
|
||||||
void* lovrShaderBlockMap(ShaderBlock* block);
|
void* lovrShaderBlockMap(ShaderBlock* block);
|
||||||
void lovrShaderBlockUnmap(ShaderBlock* block);
|
void lovrShaderBlockUnmap(ShaderBlock* block);
|
||||||
|
|
Loading…
Reference in New Issue