static int program_set_uniform_number4(lua_State *L) { shader_type *p = (shader_type*)lua_touserdata(L, 1); const char *var = luaL_checkstring(L, 2); bool change = gl_c_shader != p->shader; if (change) tglUseProgramObject(p->shader); // Uniform array if (lua_istable(L, 3)) { int nb = lua_objlen(L, 3); int i; GLfloat is[4*nb]; for (i = 0; i < nb; i++) { lua_rawgeti(L, 3, i + 1); lua_rawgeti(L, -1, 1); is[i*4+0] = lua_tonumber(L, -1); lua_pop(L, 1); lua_rawgeti(L, -1, 2); is[i*4+1] = lua_tonumber(L, -1); lua_pop(L, 1); lua_rawgeti(L, -1, 3); is[i*4+2] = lua_tonumber(L, -1); lua_pop(L, 1); lua_rawgeti(L, -1, 4); is[i*4+3] = lua_tonumber(L, -1); lua_pop(L, 1); lua_pop(L, 1); } glUniform4fvARB(glGetUniformLocationARB(p->shader, var), nb, is); } else { GLfloat i[4]; i[0] = luaL_checknumber(L, 3); i[1] = luaL_checknumber(L, 4); i[2] = luaL_checknumber(L, 5); i[3] = luaL_checknumber(L, 6); glUniform4fvARB(glGetUniformLocationARB(p->shader, var), 1, i); } if (change) tglUseProgramObject(0); return 0; }
static int program_set_uniform_number_fast(lua_State *L) { shader_type *p = (shader_type*)lua_touserdata(L, 1); GLfloat i = luaL_checknumber(L, 2); bool change = gl_c_shader != p->shader; GLint pos = lua_tonumber(L, lua_upvalueindex(1)); if (change) tglUseProgramObject(p->shader); glUniform1fvARB(pos, 1, &i); if (change) tglUseProgramObject(0); return 0; }
static int program_set_uniform_texture(lua_State *L) { shader_type *p = (shader_type*)lua_touserdata(L, 1); const char *var = luaL_checkstring(L, 2); GLint i = luaL_checknumber(L, 3); bool change = gl_c_shader != p->shader; if (change) tglUseProgramObject(p->shader); glUniform1ivARB(glGetUniformLocationARB(p->shader, var), 1, &i); if (change) tglUseProgramObject(0); return 0; }
static int program_use(lua_State *L) { shader_type *p = (shader_type*)lua_touserdata(L, 1); bool active = lua_toboolean(L, 2); if (active) { tglUseProgramObject(p->shader); // GLfloat t = SDL_GetTicks(); GLfloat t = cur_frame_tick; glUniform1fvARB(p->p_tick, 1, &t); } else { tglUseProgramObject(0); } return 0; }
// Runs into main thread static void particles_draw(particles_type *ps, float x, float y, float zoom) { if (!ps->alive || !ps->vertices || !ps->colors || !ps->texcoords) return; GLfloat *vertices = ps->vertices; GLfloat *colors = ps->colors; GLshort *texcoords = ps->texcoords; if (x < -10000) x = -10000; if (x > 10000) x = 10000; if (y < -10000) y = -10000; if (y > 10000) y = 10000; SDL_mutexP(ps->lock); if (ps->blend_mode == BLEND_ADDITIVE) glBlendFunc(GL_SRC_ALPHA,GL_ONE); if (multitexture_active) tglActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, ps->texture); if (multitexture_active && main_fbo) { tglActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, main_fbo->texture); } glTexCoordPointer(2, GL_SHORT, 0, texcoords); glColorPointer(4, GL_FLOAT, 0, colors); glVertexPointer(2, GL_FLOAT, 0, vertices); glTranslatef(x, y, 0); glPushMatrix(); glScalef(ps->zoom * zoom, ps->zoom * zoom, ps->zoom * zoom); glRotatef(ps->rotate, 0, 0, 1); if (ps->shader) useShader(ps->shader, 1, 1, main_fbo ? main_fbo->w : 1, main_fbo ? main_fbo->h : 1, 1, 1, 1, 1); int remaining = ps->batch_nb; while (remaining >= PARTICLES_PER_ARRAY) { glDrawArrays(GL_QUADS, remaining - PARTICLES_PER_ARRAY, PARTICLES_PER_ARRAY); remaining -= PARTICLES_PER_ARRAY; } if (remaining) glDrawArrays(GL_QUADS, 0, remaining); if (ps->shader) tglUseProgramObject(0); glPopMatrix(); glTranslatef(-x, -y, 0); if (ps->blend_mode) glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); if (multitexture_active && main_fbo) { tglActiveTexture(GL_TEXTURE0); } SDL_mutexV(ps->lock); }
void useShader(shader_type *p, int x, int y, int w, int h, float tx, float ty, float tw, float th, float r, float g, float b, float a) { tglUseProgramObject(p->shader); GLfloat t = cur_frame_tick; glUniform1fvARB(p->p_tick, 1, &t); GLfloat d[4]; d[0] = r; d[1] = g; d[2] = b; d[3] = a; glUniform4fvARB(p->p_color, 1, d); GLfloat c[2]; c[0] = x; c[1] = y; glUniform2fvARB(p->p_mapcoord, 1, c); c[0] = w; c[1] = h; glUniform2fvARB(p->p_texsize, 1, c); d[0] = tx; d[1] = ty; d[2] = tw; d[3] = th; glUniform4fvARB(p->p_texcoord, 1, d); shader_reset_uniform *ru = p->reset_uniforms; while (ru) { switch (ru->kind) { case UNIFORM_NUMBER: glUniform1fvARB(ru->p, 1, &ru->data.number); break; case UNIFORM_VEC2: glUniform2fvARB(ru->p, 1, ru->data.vec2); break; case UNIFORM_VEC3: glUniform3fvARB(ru->p, 1, ru->data.vec3); break; case UNIFORM_VEC4: glUniform4fvARB(ru->p, 1, ru->data.vec4); break; } ru = ru->next; } }