mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-05-31 14:29:14 +08:00
Add software renderer implementation
This commit is contained in:
@@ -33,6 +33,7 @@
|
|||||||
#include "SDL_drawline.h"
|
#include "SDL_drawline.h"
|
||||||
#include "SDL_drawpoint.h"
|
#include "SDL_drawpoint.h"
|
||||||
#include "SDL_rotate.h"
|
#include "SDL_rotate.h"
|
||||||
|
#include "SDL_triangle.h"
|
||||||
|
|
||||||
/* SDL surface based renderer implementation */
|
/* SDL surface based renderer implementation */
|
||||||
|
|
||||||
@@ -560,6 +561,71 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex
|
|||||||
return retval;
|
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
|
static void
|
||||||
PrepTextureForCopy(const SDL_RenderCommand *cmd)
|
PrepTextureForCopy(const SDL_RenderCommand *cmd)
|
||||||
{
|
{
|
||||||
@@ -734,6 +800,39 @@ SW_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
|
|||||||
break;
|
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:
|
case SDL_RENDERCMD_NO_OP:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -843,6 +942,7 @@ SW_CreateRendererForSurface(SDL_Surface * surface)
|
|||||||
renderer->QueueFillRects = SW_QueueFillRects;
|
renderer->QueueFillRects = SW_QueueFillRects;
|
||||||
renderer->QueueCopy = SW_QueueCopy;
|
renderer->QueueCopy = SW_QueueCopy;
|
||||||
renderer->QueueCopyEx = SW_QueueCopyEx;
|
renderer->QueueCopyEx = SW_QueueCopyEx;
|
||||||
|
renderer->QueueGeometry = SW_QueueGeometry;
|
||||||
renderer->RunCommandQueue = SW_RunCommandQueue;
|
renderer->RunCommandQueue = SW_RunCommandQueue;
|
||||||
renderer->RenderReadPixels = SW_RenderReadPixels;
|
renderer->RenderReadPixels = SW_RenderReadPixels;
|
||||||
renderer->RenderPresent = SW_RenderPresent;
|
renderer->RenderPresent = SW_RenderPresent;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -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: */
|
||||||
Reference in New Issue
Block a user