Start newShaderBlock;

This commit is contained in:
bjorn 2018-07-19 16:58:59 -07:00
parent 0b70285e30
commit 823886f03f
3 changed files with 91 additions and 32 deletions

View File

@ -852,6 +852,67 @@ int l_lovrGraphicsNewAnimator(lua_State* L) {
return 1;
}
int l_lovrGraphicsNewShaderBlock(lua_State* L) {
vec_uniform_t uniforms;
vec_init(&uniforms);
luaL_checktype(L, 1, LUA_TTABLE);
lua_pushnil(L);
while (lua_next(L, 1) != 0) {
lovrAssert(lua_type(L, -2) == LUA_TSTRING, "Uniform names must be strings");
// Handle type shorthand
if (lua_type(L, -1) == LUA_TSTRING) {
lua_newtable(L);
lua_insert(L, -2);
lua_setfield(L, -2, "type");
}
luaL_checktype(L, -1, LUA_TTABLE);
// Name
Uniform uniform;
strncpy(uniform.name, lua_tostring(L, -2), LOVR_MAX_UNIFORM_LENGTH - 1);
// Count
lua_getfield(L, -1, "count");
uniform.count = lua_type(L, -1) == LUA_TNUMBER ? lua_tonumber(L, -1) : 1;
lua_pop(L, 1);
// Type
size_t length;
lua_getfield(L, -1, "type");
const char* type = lua_tolstring(L, -1, &length);
uniform.components = 1;
if (strcmp(type, "float")) {
uniform.type = UNIFORM_FLOAT;
} else if (strcmp(type, "int")) {
uniform.type = UNIFORM_INT;
} else {
uniform.components = type[length - 1] - '0';
lovrAssert(uniform.components >= 2 && uniform.components <= 4, "Unknown uniform type '%s'", type);
if (!strncmp(type, "vec", 3 * sizeof(char)) && length == 4) {
uniform.type = UNIFORM_FLOAT;
} else if (!strncmp(type, "ivec", 4 * sizeof(char)) && length == 5) {
uniform.type = UNIFORM_INT;
} else if (!strncmp(type, "mat", 3 * sizeof(char)) && length == 4) {
uniform.type = UNIFORM_MATRIX;
} else {
lovrThrow("Unknown uniform type '%s'", type);
}
}
lua_pop(L, 1);
// TODO value
vec_push(&uniforms, uniform);
lua_pop(L, 1);
}
vec_deinit(&uniforms);
lua_pushnil(L);
return 1;
}
int l_lovrGraphicsNewCanvas(lua_State* L) {
int width = luaL_checkinteger(L, 1);
int height = luaL_checkinteger(L, 2);
@ -1195,6 +1256,7 @@ const luaL_Reg lovrGraphics[] = {
{ "newMesh", l_lovrGraphicsNewMesh },
{ "newModel", l_lovrGraphicsNewModel },
{ "newShader", l_lovrGraphicsNewShader },
{ "newShaderBlock", l_lovrGraphicsNewShaderBlock },
{ "newTexture", l_lovrGraphicsNewTexture },
{ NULL, NULL }

View File

@ -31,8 +31,6 @@
#define LOVR_SHADER_TANGENT 4
#define LOVR_SHADER_BONES 5
#define LOVR_SHADER_BONE_WEIGHTS 6
#define LOVR_MAX_UNIFORM_LENGTH 64
#define LOVR_MAX_ATTRIBUTE_LENGTH 64
static struct {
Texture* defaultTexture;
@ -64,26 +62,6 @@ static struct {
GraphicsStats stats;
} state;
typedef struct {
GLchar name[LOVR_MAX_UNIFORM_LENGTH];
GLenum glType;
int location;
int count;
int components;
size_t size;
UniformType type;
union {
void* data;
int* ints;
float* floats;
Texture** textures;
} value;
int baseTextureSlot;
bool dirty;
} Uniform;
typedef map_t(Uniform) map_uniform_t;
struct Shader {
Ref ref;
uint32_t program;
@ -1242,7 +1220,8 @@ Shader* lovrShaderCreate(const char* vertexSource, const char* fragmentSource) {
glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &uniformCount);
for (int i = 0; i < uniformCount; i++) {
Uniform uniform;
glGetActiveUniform(program, i, LOVR_MAX_UNIFORM_LENGTH, NULL, &uniform.count, &uniform.glType, uniform.name);
GLenum glType;
glGetActiveUniform(program, i, LOVR_MAX_UNIFORM_LENGTH, NULL, &uniform.count, &glType, uniform.name);
char* subscript = strchr(uniform.name, '[');
if (subscript) {
@ -1250,8 +1229,8 @@ Shader* lovrShaderCreate(const char* vertexSource, const char* fragmentSource) {
}
uniform.location = glGetUniformLocation(program, uniform.name);
uniform.type = getUniformType(uniform.glType, uniform.name);
uniform.components = getUniformComponents(uniform.glType);
uniform.type = getUniformType(glType, uniform.name);
uniform.components = getUniformComponents(glType);
uniform.baseTextureSlot = (uniform.type == UNIFORM_SAMPLER) ? textureSlot : -1;
if (uniform.location == -1) {
@ -1404,13 +1383,6 @@ void lovrShaderBind(Shader* shader) {
case UNIFORM_SAMPLER:
for (int i = 0; i < count; i++) {
GLenum uniformTextureType;
switch (uniform->glType) {
case GL_SAMPLER_2D: uniformTextureType = GL_TEXTURE_2D; break;
case GL_SAMPLER_3D: uniformTextureType = GL_TEXTURE_3D; break;
case GL_SAMPLER_CUBE: uniformTextureType = GL_TEXTURE_CUBE_MAP; break;
case GL_SAMPLER_2D_ARRAY: uniformTextureType = GL_TEXTURE_2D_ARRAY; break;
}
lovrGpuBindTexture(uniform->value.textures[i], uniform->baseTextureSlot + i);
}
break;

View File

@ -1,8 +1,13 @@
#include "graphics/texture.h"
#include "lib/map/map.h"
#include "lib/vec/vec.h"
#include <stdbool.h>
#pragma once
#define LOVR_MAX_UNIFORM_LENGTH 64
#define LOVR_MAX_ATTRIBUTE_LENGTH 64
typedef enum {
UNIFORM_FLOAT,
UNIFORM_MATRIX,
@ -19,6 +24,26 @@ typedef enum {
MAX_DEFAULT_SHADERS
} DefaultShader;
typedef struct {
char name[LOVR_MAX_UNIFORM_LENGTH];
int location;
int count;
int components;
size_t size;
UniformType type;
union {
void* data;
int* ints;
float* floats;
Texture** textures;
} value;
int baseTextureSlot;
bool dirty;
} Uniform;
typedef map_t(Uniform) map_uniform_t;
typedef vec_t(Uniform) vec_uniform_t;
typedef struct Shader Shader;
Shader* lovrShaderCreate(const char* vertexSource, const char* fragmentSource);