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 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); } } } }
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); } }
void label_draw(const struct rich_text *rich, struct pack_label * l, struct srt *srt, const struct sprite_trans *arg) { shader_texture(Tex, 0); uint32_t color = label_get_color(l, arg); const char *str = rich->text; char utf8[7]; int i; int ch = 0, w = 0, cy = 0, pre = 0, char_cnt = 0, idx = 0; for (i=0; str && str[i];) { int unicode; int len = unicode_len(str[i]); unicode = copystr(utf8, str+i, len); i+=len; w += draw_size(unicode, utf8, l->size, l->edge) + l->space_w; if (ch == 0) { ch = draw_height(unicode, utf8, l->size, l->edge) + l->space_h; } float space_scale=1.0; uint32_t lf = get_rich_filed_lf(rich, idx, &space_scale); if((l->auto_scale == 0 && lf) || unicode == '\n') { draw_line(rich, l, srt, arg, color, cy, w, pre, i, &char_cnt, space_scale); cy += ch; pre = i; w = 0; ch = 0; } idx++; } draw_line(rich, l, srt, arg, color, cy, w, pre, i, &char_cnt, 1.0); }
const char * texture_load(int id, int pixel_format, int pixel_width, int pixel_height, void *data) { if (id >= MAX_TEXTURE) { return "Too many texture"; } struct texture * tex = &POOL.tex[id]; if (id >= POOL.count) { POOL.count = id + 1; } tex->width = pixel_width; tex->height = pixel_height; tex->invw = 1.0f / (float)pixel_width; tex->invh = 1.0f / (float)pixel_height; if (tex->id == 0) { glGenTextures(1, &tex->id); } if (data == NULL) { // empty texture return NULL; } if ((pixel_format == Texture2DPixelFormat_RGBA8888) || ( IS_POT(pixel_width) && IS_POT(pixel_height))) { glPixelStorei(GL_UNPACK_ALIGNMENT,4); } else { glPixelStorei(GL_UNPACK_ALIGNMENT,1); } glActiveTexture(GL_TEXTURE0); shader_texture(tex->id); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); switch(pixel_format) { case Texture2DPixelFormat_RGBA8888: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)pixel_width, (GLsizei)pixel_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); break; case Texture2DPixelFormat_RGB888: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (GLsizei)pixel_width, (GLsizei)pixel_height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); break; case Texture2DPixelFormat_RGBA4444: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)pixel_width, (GLsizei)pixel_height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data); break; case Texture2DPixelFormat_RGB565: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (GLsizei)pixel_width, (GLsizei)pixel_height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data); break; case Texture2DPixelFormat_A8: glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, (GLsizei)pixel_width, (GLsizei)pixel_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data); break; default: glDeleteTextures(1,&tex->id); tex->id = 0; return "Invalid pixel format"; } return NULL; }
void label_draw(const char *str, struct pack_label * l, struct srt *srt, const struct sprite_trans *arg) { shader_texture(Tex); uint32_t color; if (arg->color == 0xffffffff) { color = l->color; } else if (l->color == 0xffffffff){ color = arg->color; } else { color = color_mul(l->color, arg->color); } char utf8[7]; int i; int ch = 0, w = 0, cy = 0, pre = 0; for (i=0; str[i];) { int unicode; uint8_t c = (uint8_t)str[i]; if ((c&0x80) == 0) { unicode = copystr(utf8,str+i,1); i+=1; } else if ((c&0xe0) == 0xc0) { unicode = copystr(utf8,str+i,2); i+=2; } else if ((c&0xf0) == 0xe0) { unicode = copystr(utf8,str+i,3); i+=3; } else if ((c&0xf8) == 0xf0) { unicode = copystr(utf8,str+i,4); i+=4; } else if ((c&0xfc) == 0xf8) { unicode = copystr(utf8,str+i,5); i+=5; } else { unicode = copystr(utf8,str+i,6); i+=6; } w += draw_size(unicode, utf8, l->size); if (ch == 0) { ch = draw_height(unicode, utf8, l->size); } if(w > l->width || unicode == '\n') { draw_line(str, l, srt, arg, color, cy, w, pre, i); cy += ch; pre = i; w = 0; ch = 0; } } draw_line(str, l, srt, arg, color, cy, w, pre, i); }
/* 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); }
void label_rawdraw(const char * str, float fx, float y, struct pack_label * l) { shader_texture(Tex, 0); uint32_t color = l->color; int edge = l->edge; int size = l->size; int width = raw_width(str, l); int x = (int)fx; switch (l->align) { case LABEL_ALIGN_LEFT: break; case LABEL_ALIGN_RIGHT: x += l->width - width; break; case LABEL_ALIGN_CENTER: x += (l->width - width)/2; break; } char utf8[7]; int i; struct matrix mat = {{ 1024,0,0,1024,0,y * SCREEN_SCALE}}; for (i=0; str[i];) { int len = unicode_len(str[i]); int unicode = copystr(utf8, str+i, len); i+=len; const struct dfont_rect * rect = dfont_lookup(Dfont, unicode, FONT_SIZE, edge); if (rect == NULL) { rect = gen_char(unicode,utf8,FONT_SIZE,edge); if (rect == NULL) continue; } mat.m[4]=x*SCREEN_SCALE; draw_rect(rect,size,&mat,color,0); x += (rect->w-1) * size / FONT_SIZE + l->space_w; } }