Add software renderer implementation

This commit is contained in:
Sylvain
2021-03-16 15:14:58 +01:00
committed by Sylvain Becker
parent 37f78fc1cc
commit 3ee511d71c
3 changed files with 969 additions and 0 deletions
+100
View File
@@ -33,6 +33,7 @@
#include "SDL_drawline.h"
#include "SDL_drawpoint.h"
#include "SDL_rotate.h"
#include "SDL_triangle.h"
/* SDL surface based renderer implementation */
@@ -560,6 +561,71 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex
return retval;
}
typedef struct GeometryFillData
{
SDL_Point dst;
SDL_Color color;
} GeometryFillData;
typedef struct GeometryCopyData
{
SDL_Point src;
SDL_Point dst;
SDL_Color color;
} GeometryCopyData;
static int
SW_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
SDL_Vertex *vertices, int num_vertices, int *indices, int num_indices, float scale_x, float scale_y)
{
int i;
int count = indices ? num_indices : num_vertices;
void *verts;
int sz = texture ? sizeof (GeometryCopyData) : sizeof (GeometryFillData);
verts = (void *) SDL_AllocateRenderVertices(renderer, count * sz, 0, &cmd->data.draw.first);
if (!verts) {
return -1;
}
cmd->data.draw.count = count;
if (texture) {
GeometryCopyData *ptr = (GeometryCopyData *) verts;
for (i = 0; i < count; i++) {
SDL_Vertex *v = &vertices[indices ? indices[i] : i];
ptr->src.x = v->tex_coord.x;
ptr->src.y = v->tex_coord.y;
ptr->dst.x = v->position.x * scale_x + renderer->viewport.x;
ptr->dst.y = v->position.y * scale_y + renderer->viewport.y;
trianglepoint_2_fixedpoint(&ptr->dst);
ptr->color = v->color;
ptr++;
}
} else {
GeometryFillData *ptr = (GeometryFillData *) verts;
for (i = 0; i < count; i++) {
SDL_Vertex *v = &vertices[indices ? indices[i] : i];
ptr->dst.x = v->position.x * scale_x + renderer->viewport.x;
ptr->dst.y = v->position.y * scale_y + renderer->viewport.y;
trianglepoint_2_fixedpoint(&ptr->dst);
ptr->color = v->color;
ptr++;
}
}
return 0;
}
static void
PrepTextureForCopy(const SDL_RenderCommand *cmd)
{
@@ -734,6 +800,39 @@ SW_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
break;
}
case SDL_RENDERCMD_GEOMETRY: {
int i;
SDL_Rect *verts = (SDL_Rect *) (((Uint8 *) vertices) + cmd->data.draw.first);
const int count = (int) cmd->data.draw.count;
SDL_Texture *texture = cmd->data.draw.texture;
const SDL_BlendMode blend = cmd->data.draw.blend;
SetDrawState(surface, &drawstate);
if (texture) {
SDL_Surface *src = (SDL_Surface *) texture->driverdata;
GeometryCopyData *ptr = (GeometryCopyData *) verts;
PrepTextureForCopy(cmd);
for (i = 0; i < count; i += 3, ptr += 3) {
SDL_SW_BlitTriangle(
src,
&(ptr[0].src), &(ptr[1].src), &(ptr[2].src),
surface,
&(ptr[0].dst), &(ptr[1].dst), &(ptr[2].dst),
ptr[0].color, ptr[1].color, ptr[2].color);
}
} else {
GeometryFillData *ptr = (GeometryFillData *) verts;
for (i = 0; i < count; i += 3, ptr += 3) {
SDL_SW_FillTriangle(surface, &(ptr[0].dst), &(ptr[1].dst), &(ptr[2].dst), blend, ptr[0].color, ptr[1].color, ptr[2].color);
}
}
break;
}
case SDL_RENDERCMD_NO_OP:
break;
}
@@ -843,6 +942,7 @@ SW_CreateRendererForSurface(SDL_Surface * surface)
renderer->QueueFillRects = SW_QueueFillRects;
renderer->QueueCopy = SW_QueueCopy;
renderer->QueueCopyEx = SW_QueueCopyEx;
renderer->QueueGeometry = SW_QueueGeometry;
renderer->RunCommandQueue = SW_RunCommandQueue;
renderer->RenderReadPixels = SW_RenderReadPixels;
renderer->RenderPresent = SW_RenderPresent;
File diff suppressed because it is too large Load Diff
+42
View File
@@ -0,0 +1,42 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_triangle_h_
#define SDL_triangle_h_
#include "../../SDL_internal.h"
extern int SDL_SW_FillTriangle(SDL_Surface *dst,
SDL_Point *d0, SDL_Point *d1, SDL_Point *d2,
SDL_BlendMode blend, SDL_Color c0, SDL_Color c1, SDL_Color c2);
extern int SDL_SW_BlitTriangle(
SDL_Surface *src,
SDL_Point *s0, SDL_Point *s1, SDL_Point *s2,
SDL_Surface *dst,
SDL_Point *d0, SDL_Point *d1, SDL_Point *d2,
SDL_Color c0, SDL_Color c1, SDL_Color c2);
extern void trianglepoint_2_fixedpoint(SDL_Point *a);
#endif /* SDL_triangle_h_ */
/* vi: set ts=4 sw=4 expandtab: */