void material_apply(int prog, struct material *m) { struct program * p = m->p; if (p != &RS->program[prog]) return; if (p->material == m && !m->reset) { return; } m->reset = false; p->material = m; p->reset_uniform = true; int i; for (i=0;i<p->uniform_number;i++) { if (m->uniform_enable[i]) { struct uniform * u = &p->uniform[i]; if (u->loc >=0) { render_shader_setuniform(RS->R, u->loc, u->type, m->uniform + u->offset); } } } for (i=0;i<p->texture_number;i++) { int tex = m->texture[i]; if (tex >= 0) { RID glid = texture_glid(tex); if (glid) { shader_texture(glid, i); } } } }
static int lnewdfont(lua_State *L) { int width = luaL_checkinteger(L, 1); int height = luaL_checkinteger(L, 2); int format = luaL_checkinteger(L, 3); int id = luaL_checkinteger(L, 4); lua_createtable(L, 0, 1); size_t size = dfont_data_size(width, height); void * d = lua_newuserdata(L, size); dfont_init(d, width, height); lua_setfield(L, -2, "__obj"); const char* err = texture_load(id, (enum TEXTURE_FORMAT)format, width, height, NULL, 0); if (err) { return luaL_error(L, err); } RID tex = texture_glid(id); render_texture_update(R, tex, width, height, NULL, 0, 0); lua_pushinteger(L, id); lua_setfield(L, -2, "texture"); return 1; }
void shader_drawbuffer(struct render_buffer * rb, float tx, float ty, float scale) { rs_commit(); RID glid = texture_glid(rb->texid); if (glid == 0) return; shader_texture(glid, 0); render_set(RS->R, VERTEXBUFFER, rb->vbid, 0); float sx = scale; float sy = scale; screen_trans(&sx, &sy); screen_trans(&tx, &ty); float v[4] = { sx, sy, tx, ty }; // we should call shader_adduniform to add "st" uniform first shader_setuniform(PROGRAM_RENDERBUFFER, 0, UNIFORM_FLOAT4, v); shader_program(PROGRAM_RENDERBUFFER, NULL); RS->drawcall++; renderbuffer_commit(rb); render_set(RS->R, VERTEXBUFFER, RS->vertex_buffer, 0); }
void sprite_drawquad(struct pack_picture *picture, const struct srt *srt, const struct sprite_trans *arg) { struct matrix tmp; struct vertex_pack vb[4]; int i,j; if (arg->mat == NULL) { matrix_identity(&tmp); } else { tmp = *arg->mat; } matrix_srt(&tmp, srt); int *m = tmp.m; for (i=0;i<picture->n;i++) { struct pack_quad *q = &picture->rect[i]; int glid = texture_glid(q->texid); if (glid == 0) continue; shader_texture(glid, 0); for (j=0;j<4;j++) { int xx = q->screen_coord[j*2+0]; int yy = q->screen_coord[j*2+1]; float vx = (xx * m[0] + yy * m[2]) / 1024 + m[4]; float vy = (xx * m[1] + yy * m[3]) / 1024 + m[5]; float tx = q->texture_coord[j*2+0]; float ty = q->texture_coord[j*2+1]; screen_trans(&vx,&vy); vb[j].vx = vx; vb[j].vy = vy; vb[j].tx = tx; vb[j].ty = ty; } shader_draw(vb, arg->color, arg->additive); } }
/* int texture table float[16] uint32_t color uint32_t additive */ static int ldraw(lua_State *L) { int tex = (int)luaL_checkinteger(L,1); int texid = texture_glid(tex); if (texid == 0) { lua_pushboolean(L,0); return 1; } luaL_checktype(L, 2, LUA_TTABLE); uint32_t color = 0xffffffff; if (!lua_isnoneornil(L,3)) { color = (uint32_t)lua_tounsigned(L,3); } uint32_t additive = (uint32_t)luaL_optunsigned(L,4,0); shader_program(PROGRAM_PICTURE,additive); shader_texture(texid); int n = lua_rawlen(L, 2); int point = n/4; if (point * 4 != n) { return luaL_error(L, "Invalid polygon"); } #if !defined(_MSC_VER) float vb[n]; #else msvc::dynarray<float> vb(n); #endif int i; for (i=0;i<point;i++) { lua_rawgeti(L, 2, i*2+1); lua_rawgeti(L, 2, i*2+2); lua_rawgeti(L, 2, point*2+i*2+1); lua_rawgeti(L, 2, point*2+i*2+2); float tx = lua_tonumber(L, -4); float ty = lua_tonumber(L, -3); float vx = lua_tonumber(L, -2); float vy = lua_tonumber(L, -1); lua_pop(L,4); screen_trans(&vx,&vy); texture_coord(tex, &tx, &ty); vb[i*4+0] = vx + 1.0f; vb[i*4+1] = vy - 1.0f; vb[i*4+2] = tx; vb[i*4+3] = ty; } if (point == 4) { shader_draw(vb, color); } else { shader_drawpolygon(point, vb, color); } return 0; }
/* int texture table float[16] uint32_t color uint32_t additive */ static int ldraw(lua_State *L) { int tex = (int)luaL_checkinteger(L,1); int texid = texture_glid(tex); if (texid == 0) { lua_pushboolean(L,0); return 1; } luaL_checktype(L, 2, LUA_TTABLE); uint32_t color = 0xffffffff; if (!lua_isnoneornil(L,3)) { color = (uint32_t)lua_tounsigned(L,3); } uint32_t additive = (uint32_t)luaL_optunsigned(L,4,0); shader_program(PROGRAM_PICTURE); shader_texture(texid); int n = lua_rawlen(L, 2); int point = n/4; if (point * 4 != n) { return luaL_error(L, "Invalid polygon"); } ARRAY(struct vertex_pack, vb, point); int i; for (i=0;i<point;i++) { lua_rawgeti(L, 2, i*2+1); lua_rawgeti(L, 2, i*2+2); lua_rawgeti(L, 2, point*2+i*2+1); lua_rawgeti(L, 2, point*2+i*2+2); float tx = lua_tonumber(L, -4); float ty = lua_tonumber(L, -3); float vx = lua_tonumber(L, -2); float vy = lua_tonumber(L, -1); uint16_t u,v; lua_pop(L,4); screen_trans(&vx,&vy); texture_coord(tex, tx, ty, &u, &v); vb[i].vx = vx + 1.0f; vb[i].vy = vy - 1.0f; vb[i].tx = u; vb[i].ty = v; } if (point == 4) { shader_draw(vb, color, additive); } else { shader_drawpolygon(point, vb, color, additive); } return 0; }
void sprite_drawquad(struct pack_picture *picture, struct pack_picture *mask, const struct srt *srt, const struct sprite_trans *arg) { struct matrix tmp; float vb[16]; int i,j; if (arg->mat == NULL) { matrix_identity(&tmp); } else { tmp = *arg->mat; } matrix_srt(&tmp, srt); int *m = tmp.m; for (i=0;i<picture->n;i++) { struct pack_quad *q = &picture->rect[i]; int glid = texture_glid(q->texid); if (glid == 0) continue; shader_texture(glid); for (j=0;j<4;j++) { int xx = q->screen_coord[j*2+0]; int yy = q->screen_coord[j*2+1]; float vx = (xx * m[0] + yy * m[2]) / 1024 + m[4]; float vy = (xx * m[1] + yy * m[3]) / 1024 + m[5]; float tx = q->texture_coord[j*2+0]; float ty = q->texture_coord[j*2+1]; screen_trans(&vx,&vy); texture_coord(q->texid, &tx, &ty); vb[j*4+0] = vx; vb[j*4+1] = vy; vb[j*4+2] = tx; vb[j*4+3] = ty; } if(!enable_visible_test || !screen_is_poly_invisible(vb,4,4)) { if (mask != NULL) { float tx = mask->rect[0].texture_coord[0]; float ty = mask->rect[0].texture_coord[1]; texture_coord(mask->rect[0].texid, &tx, &ty); float delta_tx = tx - vb[2]; float delta_ty = ty - vb[3]; shader_mask(delta_tx, delta_ty); } shader_draw(vb, arg->color); } } }
void sprite_drawpolygon(struct pack_polygon *poly, const struct srt *srt, const struct sprite_trans *arg) { struct matrix tmp; int i,j; if (arg->mat == NULL) { matrix_identity(&tmp); } else { tmp = *arg->mat; } matrix_srt(&tmp, srt); int *m = tmp.m; for (i=0;i<poly->n;i++) { struct pack_poly *p = &poly->poly[i]; int glid = texture_glid(p->texid); if (glid == 0) continue; shader_texture(glid); int pn = p->n; ARRAY(float, vb, 4 * pn); for (j=0;j<pn;j++) { int xx = p->screen_coord[j*2+0]; int yy = p->screen_coord[j*2+1]; float vx = (xx * m[0] + yy * m[2]) / 1024 + m[4]; float vy = (xx * m[1] + yy * m[3]) / 1024 + m[5]; float tx = p->texture_coord[j*2+0]; float ty = p->texture_coord[j*2+1]; screen_trans(&vx,&vy); texture_coord(p->texid, &tx, &ty); vb[j*4+0] = vx; vb[j*4+1] = vy; vb[j*4+2] = tx; vb[j*4+3] = ty; } shader_drawpolygon(pn, vb, arg->color); } }
void shader_drawbuffer(struct render_buffer * rb, float tx, float ty, float scale) { rs_commit(); int glid = texture_glid(rb->texid); if (glid == 0) return; shader_texture(glid); shader_program(PROGRAM_RENDERBUFFER); RS->drawcall++; glBindBuffer(GL_ARRAY_BUFFER, rb->vbid); float sx = scale; float sy = scale; screen_trans(&sx, &sy); screen_trans(&tx, &ty); struct program *p = &RS->program[RS->current_program]; glUniform4f(p->st, sx, sy, tx, ty); renderbuffer_commit(rb); }
static int ldfont_insert(lua_State *L) { struct dfont *df = get_dfont(L); if (!df) { return luaL_error(L, "invalid dfont table"); } lua_getfield(L, 1, "texture"); int tid = luaL_checkinteger(L, -1); lua_pop(L, 1); RID tex = texture_glid(tid); int id = luaL_checkinteger(L, 2); int rect_size = luaL_checkinteger(L, 3); int w = luaL_checkinteger(L, 4); int h = luaL_checkinteger(L, 5); void* buff = lua_touserdata(L, 6); const struct dfont_rect * rect = dfont_lookup(df, id, rect_size, 0); if (rect==NULL) { rect = dfont_insert(df, id, rect_size, w, h, 0); if (rect) { render_texture_subupdate(R, tex, buff, rect->x, rect->y, rect->w, rect->h); } } if (rect) { lua_pushinteger(L, rect->x); lua_pushinteger(L, rect->y); lua_pushinteger(L, rect->w); lua_pushinteger(L, rect->h); return 4; } else { return 0; } }