Sending things to shaders basically works;

This commit is contained in:
bjorn 2016-08-28 13:36:54 -07:00
parent 604c5bcbab
commit 6b0f97e7f5
5 changed files with 156 additions and 2 deletions

View File

@ -72,8 +72,14 @@ Model* lovrGraphicsNewModel(const char* path) {
}
Shader* lovrGraphicsNewShader(const char* vertexSource, const char* fragmentSource) {
GLuint vertexShader = compileShader(GL_VERTEX_SHADER, vertexSource);
GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, fragmentSource);
char fullVertexSource[1024];
snprintf(fullVertexSource, sizeof(fullVertexSource), "%s\n%s", lovrShaderVertexPrefix, vertexSource);
GLuint vertexShader = compileShader(GL_VERTEX_SHADER, fullVertexSource);
char fullFragmentSource[1024];
snprintf(fullFragmentSource, sizeof(fullFragmentSource), "%s\n%s", lovrShaderFragmentPrefix, fragmentSource);
GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, fullFragmentSource);
GLuint id = linkShaders(vertexShader, fragmentShader);
Shader* shader = (Shader*) malloc(sizeof(Shader));
shader->id = id;

View File

@ -2,6 +2,16 @@
#include "../util.h"
#include <stdlib.h>
const char* lovrShaderVertexPrefix = ""
"#version 150 \n"
"in vec3 position;"
"";
const char* lovrShaderFragmentPrefix = ""
"#version 150 \n"
"out vec4 color;"
"";
GLuint compileShader(GLenum type, const char* source) {
GLuint shader = glCreateShader(type);
@ -58,3 +68,39 @@ void lovrShaderDestroy(Shader* shader) {
glDeleteProgram(shader->id);
free(shader);
}
int lovrShaderGetUniformId(Shader* shader, const char* name) {
return glGetUniformLocation(shader->id, name);
}
void lovrShaderGetUniformType(Shader* shader, int id, GLenum* type, int* length) {
glGetActiveUniform(shader->id, id, 0, NULL, NULL, type, NULL);
}
void lovrShaderSendFloat(Shader* shader, int id, float value) {
glUniform1f(id, value);
}
void lovrShaderSendFloatVec2(Shader* shader, int id, float* vector) {
glUniform2fv(id, 1, vector);
}
void lovrShaderSendFloatVec3(Shader* shader, int id, float* vector) {
glUniform3fv(id, 1, vector);
}
void lovrShaderSendFloatVec4(Shader* shader, int id, float* vector) {
glUniform4fv(id, 1, vector);
}
void lovrShaderSendFloatMat2(Shader* shader, int id, float* matrix) {
glUniformMatrix2fv(id, 1, GL_FALSE, matrix);
}
void lovrShaderSendFloatMat3(Shader* shader, int id, float* matrix) {
glUniformMatrix3fv(id, 1, GL_FALSE, matrix);
}
void lovrShaderSendFloatMat4(Shader* shader, int id, float* matrix) {
glUniformMatrix4fv(id, 1, GL_FALSE, matrix);
}

View File

@ -7,7 +7,19 @@ typedef struct {
} Shader;
#endif
extern const char* lovrShaderVertexPrefix;
extern const char* lovrShaderFragmentPrefix;
GLuint compileShader(GLuint type, const char* filename);
GLuint linkShaders(GLuint vertexShader, GLuint fragmentShader);
void lovrShaderDestroy(Shader* shader);
int lovrShaderGetUniformId(Shader* shader, const char* name);
void lovrShaderGetUniformType(Shader* shader, int id, GLenum* type, int* size);
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 lovrShaderSendFloatMat2(Shader* shader, int id, float* matrix);
void lovrShaderSendFloatMat3(Shader* shader, int id, float* matrix);
void lovrShaderSendFloatMat4(Shader* shader, int id, float* matrix);

View File

@ -22,5 +22,93 @@ int luax_destroyshader(lua_State* L) {
}
const luaL_Reg lovrShader[] = {
{ "send", l_lovrShaderSend },
{ NULL, NULL }
};
int l_lovrShaderSend(lua_State* L) {
Shader* shader = luax_checkshader(L, 1);
const char* name = luaL_checkstring(L, 2);
int id = lovrShaderGetUniformId(shader, name);
if (id == -1) {
return luaL_error(L, "Unknown shader variable '%s'", name);
}
GLenum type;
int size;
lovrShaderGetUniformType(shader, id, &type, &size);
float data[16];
switch (type) {
case GL_FLOAT:
lovrShaderSendFloat(shader, id, luaL_checknumber(L, 3));
break;
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_pop(L, 1);
}
lovrShaderSendFloatVec2(shader, id, 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_pop(L, 1);
}
lovrShaderSendFloatVec3(shader, id, 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_pop(L, 1);
}
lovrShaderSendFloatVec4(shader, id, data);
break;
case GL_FLOAT_MAT2:
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_pop(L, 1);
}
lovrShaderSendFloatMat2(shader, id, data);
break;
case GL_FLOAT_MAT3:
luaL_checktype(L, 3, LUA_TTABLE);
for (int i = 0; i < 9; i++) {
lua_rawgeti(L, 3, i + 1);
data[i] = lua_tonumber(L, -1);
lua_pop(L, 1);
}
lovrShaderSendFloatMat3(shader, id, data);
break;
case GL_FLOAT_MAT4:
luaL_checktype(L, 3, LUA_TTABLE);
for (int i = 0; i < 16; i++) {
lua_rawgeti(L, 3, i + 1);
data[i] = lua_tonumber(L, -1);
lua_pop(L, 1);
}
lovrShaderSendFloatMat4(shader, id, data);
break;
default:
return luaL_error(L, "Unknown uniform type %d", type);
}
return 0;
}

View File

@ -7,3 +7,5 @@ void luax_pushshader(lua_State* L, Shader* shader);
Shader* luax_checkshader(lua_State* L, int index);
int luax_destroyshader(lua_State* L);
extern const luaL_Reg lovrShader[];
int l_lovrShaderSend(lua_State* L);