static int ShaderProgram_allocate(lua_State* L) { struct _kl_effect* effect = NULL; GLuint gl_program; /* Hacky */ struct _kl_shader* shaders[3] = {NULL, NULL, NULL}; int num_shaders = 3; /* TODO: Arg type checking */ shaders[0] = lua_touserdata(L, 1); shaders[1] = lua_touserdata(L, 2); shaders[2] = lua_touserdata(L, 3); if(program_link(shaders, num_shaders, &gl_program) == KL_SUCCESS) { effect = (struct _kl_effect*)lua_newuserdata(L, sizeof(struct _kl_effect)); effect->program = gl_program; luaL_getmetatable(L, SHADER_PROGRAM_LUA_LIB); lua_setmetatable(L, -2); } else { lua_pushstring(L, "error linking shader program"); lua_error(L); } return 1; }
static int ShaderProgram_update(lua_State* L) { struct _kl_effect* effect = (struct _kl_effect*)lua_touserdata(L, 1); GLuint gl_program; /* Hacky */ struct _kl_shader* shaders[3] = {NULL, NULL, NULL}; int num_shaders = 3; /* TODO: Arg type checking */ shaders[0] = lua_touserdata(L, 2); shaders[1] = lua_touserdata(L, 3); shaders[2] = lua_touserdata(L, 4); if(program_link(shaders, num_shaders, &gl_program) == KL_SUCCESS) { GLuint old_program = effect->program; effect->program = gl_program; glDeleteProgram(old_program); } else { lua_pushstring(L, "error linking shader program"); lua_error(L); } return 1; }
bool lprogram_set_shaders(lua_State *L, const char *vs_text, const char *fs_text) { struct program *program = lua_touserdata(L, -1); if ((vs_text && fs_text) && (strcmp(program->vertex_text, vs_text) || strcmp(program->fragment_text, fs_text))) { program->linked = false; program->vertex_text = strdup(vs_text); program->fragment_text = strdup(fs_text); if (!program_compile(program)) { return false; } glBindAttribLocation(program->program, ATTRIBUTE_VERTEX, "vertex"); glBindAttribLocation(program->program, ATTRIBUTE_NORMAL, "normal"); glBindAttribLocation(program->program, ATTRIBUTE_UV, "uv"); glBindAttribLocation(program->program, ATTRIBUTE_TANGENT, "tangent"); glBindAttribLocation(program->program, ATTRIBUTE_WEIGHT0, "weights[0]"); glBindAttribLocation(program->program, ATTRIBUTE_WEIGHT1, "weights[1]"); glBindAttribLocation(program->program, ATTRIBUTE_WEIGHT2, "weights[2]"); glBindAttribLocation(program->program, ATTRIBUTE_WEIGHT3, "weights[3]"); glBindAttribLocation(program->program, ATTRIBUTE_WEIGHT4, "weights[4]"); glBindAttribLocation(program->program, ATTRIBUTE_WEIGHT5, "weights[5]"); program_link(program); } return program->linked; }