DirectFB: add partial support for RenderGeometry

allow to fill triangles with color or texture
but only uniform vertex color is handled (not per vertex color)
This commit is contained in:
Sylvain 2021-09-30 23:47:37 +02:00
parent 7def81cf42
commit 83d600904b
No known key found for this signature in database
GPG Key ID: 5F87E02E5BC0939E
1 changed files with 197 additions and 0 deletions

View File

@ -615,6 +615,64 @@ DirectFB_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const
return 0;
}
static int
DirectFB_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
const float *xy, int xy_stride, const int *color, int color_stride, const float *uv, int uv_stride,
int num_vertices, const void *indices, int num_indices, int size_indices,
float scale_x, float scale_y)
{
DirectFB_TextureData *texturedata = NULL;
int i;
int count = indices ? num_indices : num_vertices;
float *verts;
int sz = 2 + 4 + (texture ? 2 : 0);
verts = (float *) SDL_AllocateRenderVertices(renderer, count * sz * sizeof (float), 0, &cmd->data.draw.first);
if (!verts) {
return -1;
}
if (texture) {
texturedata = (DirectFB_TextureData *) texture->driverdata;
}
cmd->data.draw.count = count;
size_indices = indices ? size_indices : 0;
for (i = 0; i < count; i++) {
int j;
float *xy_;
SDL_Color col_;
if (size_indices == 4) {
j = ((const Uint32 *)indices)[i];
} else if (size_indices == 2) {
j = ((const Uint16 *)indices)[i];
} else if (size_indices == 1) {
j = ((const Uint8 *)indices)[i];
} else {
j = i;
}
xy_ = (float *)((char*)xy + j * xy_stride);
col_ = *(SDL_Color *)((char*)color + j * color_stride);
*(verts++) = xy_[0] * scale_x;
*(verts++) = xy_[1] * scale_y;
*(verts++) = col_.r;
*(verts++) = col_.g;
*(verts++) = col_.b;
*(verts++) = col_.a;
if (texture) {
float *uv_ = (float *)((char*)uv + j * uv_stride);
*(verts++) = uv_[0];
*(verts++) = uv_[1];
}
}
return 0;
}
static int
DirectFB_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count)
{
@ -814,6 +872,144 @@ DirectFB_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *
break;
}
case SDL_RENDERCMD_GEOMETRY: {
const float *verts = (float *) (((Uint8 *) vertices) + cmd->data.draw.first);
SDL_Texture *texture = cmd->data.draw.texture;
const size_t count = cmd->data.draw.count;
Uint8 save_r = cmd->data.draw.r;
Uint8 save_g = cmd->data.draw.g;
Uint8 save_b = cmd->data.draw.b;
Uint8 save_a = cmd->data.draw.a;
int j;
for (j = 0; j < count; j += 3)
{
float x1, y1, r1, g1, b1, a1, u1, v1;
float x2, y2, r2, g2, b2, a2, u2, v2;
float x3, y3, r3, g3, b3, a3, u3, v3;
x1 = *(verts++);
y1 = *(verts++);
r1 = *(verts++);
g1 = *(verts++);
b1 = *(verts++);
a1 = *(verts++);
if (texture) {
u1 = *(verts++);
v1 = *(verts++);
}
x2 = *(verts++);
y2 = *(verts++);
r2 = *(verts++);
g2 = *(verts++);
b2 = *(verts++);
a2 = *(verts++);
if (texture) {
u2 = *(verts++);
v2 = *(verts++);
}
x3 = *(verts++);
y3 = *(verts++);
r3 = *(verts++);
g3 = *(verts++);
b3 = *(verts++);
a3 = *(verts++);
if (texture) {
u3 = *(verts++);
v3 = *(verts++);
}
if (texture) {
DFBVertex vertices[3];
DirectFB_TextureData *texturedata = (DirectFB_TextureData *) texture->driverdata;
DFBSurfaceBlittingFlags flags = 0;
int r = (r1 + r2 + r3) / 3;
int g = (g1 + g2 + g3) / 3;
int b = (b1 + b2 + b3) / 3;
int a = (a1 + a2 + a3) / 3;
if (texturedata->isDirty) {
const SDL_Rect rect = { 0, 0, texture->w, texture->h };
DirectFB_UpdateTexture(renderer, texture, &rect, texturedata->pixels, texturedata->pitch);
}
if (a != 0xFF) {
flags |= DSBLIT_BLEND_COLORALPHA;
}
if ((r & g & b) != 0xFF) {
flags |= DSBLIT_COLORIZE;
}
destsurf->SetColor(destsurf, r, g, b, a);
/* ???? flags |= DSBLIT_SRC_PREMULTCOLOR; */
SetBlendMode(data, texture->blendMode, texturedata);
destsurf->SetBlittingFlags(destsurf, data->blitFlags | flags);
#if (DFB_VERSION_ATLEAST(1,2,0))
destsurf->SetRenderOptions(destsurf, texturedata->render_options);
#endif
vertices[0].x = x1;
vertices[0].y = y1;
vertices[0].z = 0;
vertices[0].w = 0;
vertices[0].s = u1;
vertices[0].t = v1;
vertices[1].x = x2;
vertices[1].y = y2;
vertices[1].z = 0;
vertices[1].w = 0;
vertices[1].s = u2;
vertices[1].t = v2;
vertices[2].x = x3;
vertices[2].y = y3;
vertices[2].z = 0;
vertices[2].w = 0;
vertices[2].s = u3;
vertices[2].t = v3;
destsurf->TextureTriangles(destsurf, texturedata->surface, vertices, NULL, 3, DTTF_LIST);
} else {
DFBTriangle tris;
tris.x1 = x1;
tris.y1 = y1;
tris.x2 = x2;
tris.y2 = y2;
tris.x3 = x3;
tris.y3 = y3;
cmd->data.draw.r = (r1 + r2 + r3) / 3;
cmd->data.draw.g = (g1 + g2 + g3) / 3;
cmd->data.draw.b = (b1 + b2 + b3) / 3;
cmd->data.draw.a = (a1 + a2 + a3) / 3;
PrepareDraw(renderer, cmd);
destsurf->FillTriangles(destsurf, &tris, 1);
}
}
cmd->data.draw.r = save_r;
cmd->data.draw.g = save_g;
cmd->data.draw.b = save_b;
cmd->data.draw.a = save_a;
break;
}
case SDL_RENDERCMD_COPY_EX:
break; /* unsupported */
@ -984,6 +1180,7 @@ DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->QueueSetDrawColor = DirectFB_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */
renderer->QueueDrawPoints = DirectFB_QueueDrawPoints;
renderer->QueueDrawLines = DirectFB_QueueDrawPoints; /* lines and points queue vertices the same way. */
renderer->QueueGeometry = DirectFB_QueueGeometry;
renderer->QueueFillRects = DirectFB_QueueFillRects;
renderer->QueueCopy = DirectFB_QueueCopy;
renderer->QueueCopyEx = DirectFB_QueueCopyEx;