15#include "nlua_shader.h"
46static int shader_compareUniform(
const void *a,
const void *b);
47static int shader_searchUniform(
const void *
id,
const void *u );
90 luaL_typerror(L, ind, SHADER_METATABLE);
104 luaL_getmetatable(L, SHADER_METATABLE);
105 lua_setmetatable(L, -2);
119 if (lua_getmetatable(L,ind)==0)
121 lua_getfield(L, LUA_REGISTRYINDEX, SHADER_METATABLE);
124 if (lua_rawequal(L, -1, -2))
140 if (shader->pp_id > 0)
141 render_postprocessRm( shader->pp_id );
142 glDeleteProgram( shader->program );
144 free(shader->uniforms);
161 lua_pushboolean( L, (memcmp( f1, f2,
sizeof(
LuaShader_t) )==0) );
168static int shader_compareUniform(
const void *a,
const void *b )
173 return strcmp(u1->name, u2->name);
176static int shader_searchUniform(
const void *
id,
const void *u )
178 return strcmp( (
const char*)
id, ((
LuaUniform_t*)u)->name );
183 return bsearch( name, ls->uniforms, ls->nuniforms,
sizeof(
LuaUniform_t), shader_searchUniform );
197 const char *pixelcode, *vertexcode;
202 pixelcode = luaL_checkstring(L,1);
203 vertexcode = luaL_checkstring(L,2);
206 memset( &shader, 0,
sizeof(shader) );
209 shader.program = gl_program_vert_frag_string( vertexcode, strlen(vertexcode), pixelcode, strlen(pixelcode) );
210 if (shader.program == 0)
211 return NLUA_ERROR(L,_(
"shader failed to compile!"));
214#define ATTRIB(name) \
215 shader.name = glGetAttribLocation( shader.program, #name )
216#define UNIFORM(name) \
217 shader.name = glGetUniformLocation( shader.program, #name )
218 UNIFORM( ViewSpaceFromLocal );
219 UNIFORM( ClipSpaceFromView );
220 UNIFORM( ClipSpaceFromLocal );
221 UNIFORM( ViewNormalFromLocal );
223 UNIFORM( ConstantColour );
224 UNIFORM( love_ScreenSize );
225 ATTRIB( VertexPosition );
226 ATTRIB( VertexTexCoord );
227 ATTRIB( VertexColour );
232 glGetProgramiv( shader.program, GL_ACTIVE_UNIFORMS, &shader.nuniforms );
233 shader.uniforms = calloc( shader.nuniforms,
sizeof(
LuaUniform_t) );
235 for (GLint i=0; i<shader.nuniforms; i++) {
237 glGetActiveUniform( shader.program, (GLuint)i, SHADER_NAME_MAXLEN, &length, &u->size, &u->type, u->name );
238 u->id = glGetUniformLocation( shader.program, u->name );
242 if ((u->type==GL_SAMPLER_2D) && (strcmp(u->name,
"MainTex")!=0)) {
243 if (shader.tex == NULL)
247 t->active = GL_TEXTURE0+ntex;
254 qsort( shader.uniforms, shader.nuniforms,
sizeof(
LuaUniform_t), shader_compareUniform );
269 if (lua_istable(L,idx)) {
270 for (
int j=0; j<n; j++) {
271 lua_pushnumber(L,j+1);
273 values[j] = luaL_checknumber(L,-1);
278 for (
int j=0; j<n; j++)
279 values[j] = luaL_checknumber(L,idx+j);
288 if (lua_istable(L,idx)) {
289 for (
int j=0; j<n; j++) {
290 lua_pushnumber(L,j+1);
292 values[j] = luaL_checkint(L,-1);
297 for (
int j=0; j<n; j++)
298 values[j] = luaL_checkint(L,idx+j);
340 name = luaL_checkstring(L,2);
342 u = shader_getUniform( ls, name );
346 return NLUA_ERROR(L,_(
"Shader does not have uniform '%s'!"), name);
351 glUseProgram( ls->program );
356 glUniform1f( u->id, values[0] );
360 glUniform2f( u->id, values[0], values[1] );
364 glUniform3f( u->id, values[0], values[1], values[2] );
368 glUniform4f( u->id, values[0], values[1], values[2], values[3] );
373 glUniform1i( u->id, ivalues[0] );
377 glUniform2i( u->id, ivalues[0], ivalues[1] );
381 glUniform3i( u->id, ivalues[0], ivalues[1], ivalues[2] );
385 glUniform4i( u->id, ivalues[0], ivalues[1], ivalues[2], ivalues[3] );
390 ls->tex[ u->tex ].texid = tex->
texture;
394 WARN(_(
"Unsupported shader uniform type '%d' for uniform '%s'. Ignoring."), u->type, u->name );
415 const char *name = luaL_checkstring(L,2);
418 lua_pushboolean(L, shader_getUniform(ls,name)!=NULL);
434 const char *str = luaL_optstring(L,2,
"final");
435 int priority = luaL_optinteger(L,3,0);
436 int layer = PP_LAYER_FINAL;
438 if (strcmp(str,
"final")==0)
439 layer = PP_LAYER_FINAL;
440 else if (strcmp(str,
"game")==0)
441 layer = PP_LAYER_GAME;
442 else if (strcmp(str,
"gui")==0)
443 layer = PP_LAYER_GUI;
444 else if (strcmp(str,
"core")==0)
445 layer = PP_LAYER_CORE;
447 return NLUA_ERROR(L,_(
"Layer was '%s', but must be one of 'final', 'game', 'gui', or 'core'."), str);
450 ls->
pp_id = render_postprocessAdd( ls, layer, priority, 0 );
451 lua_pushboolean(L, ls->
pp_id>0);
465 lua_pushboolean( L, render_postprocessRm( ls->
pp_id ) );
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
#define array_grow(ptr_array)
Increases the number of elements by one and returns the last element.
#define array_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
Header file with generic functions and naev-specifics.
LuaShader_t * lua_pushshader(lua_State *L, LuaShader_t shader)
Pushes a shader on the stack.
void shader_parseUniformArgsFloat(GLfloat values[4], lua_State *L, int idx, int n)
Helper to parse up float vector (or arguments).
static int shaderL_send(lua_State *L)
Allows setting values of uniforms for a shader. Errors out if the uniform is unknown or unused (as in...
static int shaderL_sendRaw(lua_State *L)
Allows setting values of uniforms for a shader, while ignoring unknown (or unused) uniforms.
void shader_parseUniformArgsInt(GLint values[4], lua_State *L, int idx, int n)
Helper to parse up integer vector (or arguments).
static const luaL_Reg shaderL_methods[]
static int shaderL_eq(lua_State *L)
Compares two shaders to see if they are the same.
static int shaderL_new(lua_State *L)
Creates a new shader.
static int shaderL_hasUniform(lua_State *L)
Checks to see if a shader has a uniform.
static int shaderL_addPostProcess(lua_State *L)
Sets a shader as a post-processing shader.
LuaShader_t * lua_toshader(lua_State *L, int ind)
Lua bindings to interact with shaders.
int nlua_loadShader(nlua_env env)
Loads the shader library.
LuaShader_t * luaL_checkshader(lua_State *L, int ind)
Gets shader at index or raises error if there is no shader at index.
static int shaderL_rmPostProcess(lua_State *L)
Removes a shader as a post-processing shader.
static int shaderL_sendHelper(lua_State *L, int ignore_missing)
Helper to set the uniform while handling unknown/inactive uniforms.
int lua_isshader(lua_State *L, int ind)
Checks to see if ind is a shader.
static int shaderL_gc(lua_State *L)
Frees a shader.
glTexture * luaL_checktex(lua_State *L, int ind)
Gets texture at index or raises error if there is no texture at index.
Abstraction for rendering sprite sheets.