early-access version 2281
This commit is contained in:
1001
externals/SDL/src/render/SDL_render.c
vendored
1001
externals/SDL/src/render/SDL_render.c
vendored
File diff suppressed because it is too large
Load Diff
15
externals/SDL/src/render/SDL_sysrender.h
vendored
15
externals/SDL/src/render/SDL_sysrender.h
vendored
@@ -43,7 +43,7 @@ struct SDL_Texture
|
||||
int modMode; /**< The texture modulation mode */
|
||||
SDL_BlendMode blendMode; /**< The texture blend mode */
|
||||
SDL_ScaleMode scaleMode; /**< The texture scale mode */
|
||||
Uint8 r, g, b, a; /**< Texture modulation values */
|
||||
SDL_Color color; /**< Texture modulation values */
|
||||
|
||||
SDL_Renderer *renderer;
|
||||
|
||||
@@ -58,6 +58,7 @@ struct SDL_Texture
|
||||
Uint32 last_command_generation; /* last command queue generation this texture was in. */
|
||||
|
||||
void *driverdata; /**< Driver specific texture representation */
|
||||
void *userdata;
|
||||
|
||||
SDL_Texture *prev;
|
||||
SDL_Texture *next;
|
||||
@@ -74,7 +75,8 @@ typedef enum
|
||||
SDL_RENDERCMD_DRAW_LINES,
|
||||
SDL_RENDERCMD_FILL_RECTS,
|
||||
SDL_RENDERCMD_COPY,
|
||||
SDL_RENDERCMD_COPY_EX
|
||||
SDL_RENDERCMD_COPY_EX,
|
||||
SDL_RENDERCMD_GEOMETRY
|
||||
} SDL_RenderCommandType;
|
||||
|
||||
typedef struct SDL_RenderCommand
|
||||
@@ -127,6 +129,11 @@ struct SDL_Renderer
|
||||
int (*QueueCopyEx) (SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
|
||||
const SDL_Rect * srcquad, const SDL_FRect * dstrect,
|
||||
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip);
|
||||
int (*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);
|
||||
|
||||
int (*RunCommandQueue) (SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize);
|
||||
int (*UpdateTexture) (SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
const SDL_Rect * rect, const void *pixels,
|
||||
@@ -154,6 +161,8 @@ struct SDL_Renderer
|
||||
|
||||
void (*DestroyRenderer) (SDL_Renderer * renderer);
|
||||
|
||||
int (*SetVSync) (SDL_Renderer * renderer, int vsync);
|
||||
|
||||
int (*GL_BindTexture) (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh);
|
||||
int (*GL_UnbindTexture) (SDL_Renderer * renderer, SDL_Texture *texture);
|
||||
|
||||
@@ -207,7 +216,7 @@ struct SDL_Renderer
|
||||
SDL_Texture *target;
|
||||
SDL_mutex *target_mutex;
|
||||
|
||||
Uint8 r, g, b, a; /**< Color for drawing operations values */
|
||||
SDL_Color color; /**< Color for drawing operations values */
|
||||
SDL_BlendMode blendMode; /**< The drawing blend mode */
|
||||
|
||||
SDL_bool always_batch;
|
||||
|
308
externals/SDL/src/render/direct3d/SDL_render_d3d.c
vendored
308
externals/SDL/src/render/direct3d/SDL_render_d3d.c
vendored
@@ -51,7 +51,6 @@ typedef struct
|
||||
SDL_bool cliprect_enabled_dirty;
|
||||
SDL_Rect cliprect;
|
||||
SDL_bool cliprect_dirty;
|
||||
SDL_bool is_copy_ex;
|
||||
LPDIRECT3DPIXELSHADER9 shader;
|
||||
} D3D_DrawStateCache;
|
||||
|
||||
@@ -833,190 +832,55 @@ D3D_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_F
|
||||
}
|
||||
|
||||
static int
|
||||
D3D_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count)
|
||||
D3D_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)
|
||||
{
|
||||
const DWORD color = D3DCOLOR_ARGB(cmd->data.draw.a, cmd->data.draw.r, cmd->data.draw.g, cmd->data.draw.b);
|
||||
const size_t vertslen = count * sizeof (Vertex) * 4;
|
||||
Vertex *verts = (Vertex *) SDL_AllocateRenderVertices(renderer, vertslen, 0, &cmd->data.draw.first);
|
||||
int i;
|
||||
int count = indices ? num_indices : num_vertices;
|
||||
Vertex *verts = (Vertex *) SDL_AllocateRenderVertices(renderer, count * sizeof (Vertex), 0, &cmd->data.draw.first);
|
||||
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_memset(verts, '\0', vertslen);
|
||||
cmd->data.draw.count = count;
|
||||
size_indices = indices ? size_indices : 0;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
const SDL_FRect *rect = &rects[i];
|
||||
const float minx = rect->x;
|
||||
const float maxx = rect->x + rect->w;
|
||||
const float miny = rect->y;
|
||||
const float maxy = rect->y + rect->h;
|
||||
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;
|
||||
}
|
||||
|
||||
verts->x = minx;
|
||||
verts->y = miny;
|
||||
verts->color = color;
|
||||
verts++;
|
||||
xy_ = (float *)((char*)xy + j * xy_stride);
|
||||
col_ = *(SDL_Color *)((char*)color + j * color_stride);
|
||||
|
||||
verts->x = maxx;
|
||||
verts->y = miny;
|
||||
verts->color = color;
|
||||
verts++;
|
||||
verts->x = xy_[0] * scale_x - 0.5f;
|
||||
verts->y = xy_[1] * scale_y - 0.5f;
|
||||
verts->z = 0.0f;
|
||||
verts->color = D3DCOLOR_ARGB(col_.a, col_.r, col_.g, col_.b);
|
||||
|
||||
verts->x = maxx;
|
||||
verts->y = maxy;
|
||||
verts->color = color;
|
||||
verts++;
|
||||
if (texture) {
|
||||
float *uv_ = (float *)((char*)uv + j * uv_stride);
|
||||
verts->u = uv_[0];
|
||||
verts->v = uv_[1];
|
||||
} else {
|
||||
verts->u = 0.0f;
|
||||
verts->v = 0.0f;
|
||||
}
|
||||
|
||||
verts->x = minx;
|
||||
verts->y = maxy;
|
||||
verts->color = color;
|
||||
verts++;
|
||||
verts += 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
D3D_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
|
||||
const SDL_Rect * srcrect, const SDL_FRect * dstrect)
|
||||
{
|
||||
const DWORD color = D3DCOLOR_ARGB(cmd->data.draw.a, cmd->data.draw.r, cmd->data.draw.g, cmd->data.draw.b);
|
||||
float minx, miny, maxx, maxy;
|
||||
float minu, maxu, minv, maxv;
|
||||
const size_t vertslen = sizeof (Vertex) * 4;
|
||||
Vertex *verts = (Vertex *) SDL_AllocateRenderVertices(renderer, vertslen, 0, &cmd->data.draw.first);
|
||||
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd->data.draw.count = 1;
|
||||
|
||||
minx = dstrect->x - 0.5f;
|
||||
miny = dstrect->y - 0.5f;
|
||||
maxx = dstrect->x + dstrect->w - 0.5f;
|
||||
maxy = dstrect->y + dstrect->h - 0.5f;
|
||||
|
||||
minu = (float) srcrect->x / texture->w;
|
||||
maxu = (float) (srcrect->x + srcrect->w) / texture->w;
|
||||
minv = (float) srcrect->y / texture->h;
|
||||
maxv = (float) (srcrect->y + srcrect->h) / texture->h;
|
||||
|
||||
verts->x = minx;
|
||||
verts->y = miny;
|
||||
verts->z = 0.0f;
|
||||
verts->color = color;
|
||||
verts->u = minu;
|
||||
verts->v = minv;
|
||||
verts++;
|
||||
|
||||
verts->x = maxx;
|
||||
verts->y = miny;
|
||||
verts->z = 0.0f;
|
||||
verts->color = color;
|
||||
verts->u = maxu;
|
||||
verts->v = minv;
|
||||
verts++;
|
||||
|
||||
verts->x = maxx;
|
||||
verts->y = maxy;
|
||||
verts->z = 0.0f;
|
||||
verts->color = color;
|
||||
verts->u = maxu;
|
||||
verts->v = maxv;
|
||||
verts++;
|
||||
|
||||
verts->x = minx;
|
||||
verts->y = maxy;
|
||||
verts->z = 0.0f;
|
||||
verts->color = color;
|
||||
verts->u = minu;
|
||||
verts->v = maxv;
|
||||
verts++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
D3D_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
|
||||
const SDL_Rect * srcquad, const SDL_FRect * dstrect,
|
||||
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
|
||||
{
|
||||
const DWORD color = D3DCOLOR_ARGB(cmd->data.draw.a, cmd->data.draw.r, cmd->data.draw.g, cmd->data.draw.b);
|
||||
float minx, miny, maxx, maxy;
|
||||
float minu, maxu, minv, maxv;
|
||||
const size_t vertslen = sizeof (Vertex) * 5;
|
||||
Vertex *verts = (Vertex *) SDL_AllocateRenderVertices(renderer, vertslen, 0, &cmd->data.draw.first);
|
||||
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd->data.draw.count = 1;
|
||||
|
||||
minx = -center->x;
|
||||
maxx = dstrect->w - center->x;
|
||||
miny = -center->y;
|
||||
maxy = dstrect->h - center->y;
|
||||
|
||||
if (flip & SDL_FLIP_HORIZONTAL) {
|
||||
minu = (float) (srcquad->x + srcquad->w) / texture->w;
|
||||
maxu = (float) srcquad->x / texture->w;
|
||||
} else {
|
||||
minu = (float) srcquad->x / texture->w;
|
||||
maxu = (float) (srcquad->x + srcquad->w) / texture->w;
|
||||
}
|
||||
|
||||
if (flip & SDL_FLIP_VERTICAL) {
|
||||
minv = (float) (srcquad->y + srcquad->h) / texture->h;
|
||||
maxv = (float) srcquad->y / texture->h;
|
||||
} else {
|
||||
minv = (float) srcquad->y / texture->h;
|
||||
maxv = (float) (srcquad->y + srcquad->h) / texture->h;
|
||||
}
|
||||
|
||||
verts->x = minx;
|
||||
verts->y = miny;
|
||||
verts->z = 0.0f;
|
||||
verts->color = color;
|
||||
verts->u = minu;
|
||||
verts->v = minv;
|
||||
verts++;
|
||||
|
||||
verts->x = maxx;
|
||||
verts->y = miny;
|
||||
verts->z = 0.0f;
|
||||
verts->color = color;
|
||||
verts->u = maxu;
|
||||
verts->v = minv;
|
||||
verts++;
|
||||
|
||||
verts->x = maxx;
|
||||
verts->y = maxy;
|
||||
verts->z = 0.0f;
|
||||
verts->color = color;
|
||||
verts->u = maxu;
|
||||
verts->v = maxv;
|
||||
verts++;
|
||||
|
||||
verts->x = minx;
|
||||
verts->y = maxy;
|
||||
verts->z = 0.0f;
|
||||
verts->color = color;
|
||||
verts->u = minu;
|
||||
verts->v = maxv;
|
||||
verts++;
|
||||
|
||||
verts->x = dstrect->x + center->x - 0.5f; /* X translation */
|
||||
verts->y = dstrect->y + center->y - 0.5f; /* Y translation */
|
||||
verts->z = (float)(M_PI * (float) angle / 180.0f); /* rotation */
|
||||
verts->color = 0;
|
||||
verts->u = 0.0f;
|
||||
verts->v = 0.0f;
|
||||
verts++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1119,8 +983,6 @@ SetupTextureState(D3D_RenderData *data, SDL_Texture * texture, LPDIRECT3DPIXELSH
|
||||
static int
|
||||
SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd)
|
||||
{
|
||||
const SDL_bool was_copy_ex = data->drawstate.is_copy_ex;
|
||||
const SDL_bool is_copy_ex = (cmd->command == SDL_RENDERCMD_COPY_EX);
|
||||
SDL_Texture *texture = cmd->data.draw.texture;
|
||||
const SDL_BlendMode blend = cmd->data.draw.blend;
|
||||
|
||||
@@ -1179,14 +1041,6 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd)
|
||||
data->drawstate.blend = blend;
|
||||
}
|
||||
|
||||
if (is_copy_ex != was_copy_ex) {
|
||||
if (!is_copy_ex) { /* SDL_RENDERCMD_COPY_EX will set this, we only want to reset it here if necessary. */
|
||||
const Float4X4 d3dmatrix = MatrixIdentity();
|
||||
IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, (D3DMATRIX*) &d3dmatrix);
|
||||
}
|
||||
data->drawstate.is_copy_ex = is_copy_ex;
|
||||
}
|
||||
|
||||
if (data->drawstate.viewport_dirty) {
|
||||
const SDL_Rect *viewport = &data->drawstate.viewport;
|
||||
const D3DVIEWPORT9 d3dviewport = { viewport->x, viewport->y, viewport->w, viewport->h, 0.0f, 1.0f };
|
||||
@@ -1231,7 +1085,6 @@ D3D_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti
|
||||
const int vboidx = data->currentVertexBuffer;
|
||||
IDirect3DVertexBuffer9 *vbo = NULL;
|
||||
const SDL_bool istarget = renderer->target != NULL;
|
||||
size_t i;
|
||||
|
||||
if (D3D_ActivateRenderer(renderer) < 0) {
|
||||
return -1;
|
||||
@@ -1377,58 +1230,24 @@ D3D_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_FILL_RECTS: {
|
||||
case SDL_RENDERCMD_FILL_RECTS: /* unused */
|
||||
break;
|
||||
|
||||
case SDL_RENDERCMD_COPY: /* unused */
|
||||
break;
|
||||
|
||||
case SDL_RENDERCMD_COPY_EX: /* unused */
|
||||
break;
|
||||
|
||||
case SDL_RENDERCMD_GEOMETRY: {
|
||||
const size_t count = cmd->data.draw.count;
|
||||
const size_t first = cmd->data.draw.first;
|
||||
SetDrawState(data, cmd);
|
||||
if (vbo) {
|
||||
size_t offset = 0;
|
||||
for (i = 0; i < count; ++i, offset += 4) {
|
||||
IDirect3DDevice9_DrawPrimitive(data->device, D3DPT_TRIANGLEFAN, (UINT) ((first / sizeof (Vertex)) + offset), 2);
|
||||
}
|
||||
IDirect3DDevice9_DrawPrimitive(data->device, D3DPT_TRIANGLELIST, (UINT) (first / sizeof (Vertex)), (UINT) count / 3);
|
||||
} else {
|
||||
const Vertex *verts = (Vertex *) (((Uint8 *) vertices) + first);
|
||||
for (i = 0; i < count; ++i, verts += 4) {
|
||||
IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2, verts, sizeof (Vertex));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_COPY: {
|
||||
const size_t count = cmd->data.draw.count;
|
||||
const size_t first = cmd->data.draw.first;
|
||||
SetDrawState(data, cmd);
|
||||
if (vbo) {
|
||||
size_t offset = 0;
|
||||
for (i = 0; i < count; ++i, offset += 4) {
|
||||
IDirect3DDevice9_DrawPrimitive(data->device, D3DPT_TRIANGLEFAN, (UINT) ((first / sizeof (Vertex)) + offset), 2);
|
||||
}
|
||||
} else {
|
||||
const Vertex *verts = (Vertex *) (((Uint8 *) vertices) + first);
|
||||
for (i = 0; i < count; ++i, verts += 4) {
|
||||
IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2, verts, sizeof (Vertex));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_COPY_EX: {
|
||||
const size_t first = cmd->data.draw.first;
|
||||
const Vertex *verts = (Vertex *) (((Uint8 *) vertices) + first);
|
||||
const Vertex *transvert = verts + 4;
|
||||
const float translatex = transvert->x;
|
||||
const float translatey = transvert->y;
|
||||
const float rotation = transvert->z;
|
||||
const Float4X4 d3dmatrix = MatrixMultiply(MatrixRotationZ(rotation), MatrixTranslation(translatex, translatey, 0));
|
||||
SetDrawState(data, cmd);
|
||||
|
||||
IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, (D3DMATRIX*)&d3dmatrix);
|
||||
|
||||
if (vbo) {
|
||||
IDirect3DDevice9_DrawPrimitive(data->device, D3DPT_TRIANGLEFAN, (UINT) (first / sizeof (Vertex)), 2);
|
||||
} else {
|
||||
IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2, verts, sizeof (Vertex));
|
||||
const Vertex* verts = (Vertex*)(((Uint8*)vertices) + first);
|
||||
IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLELIST, (UINT) count / 3, verts, sizeof(Vertex));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1606,6 +1425,12 @@ D3D_Reset(SDL_Renderer * renderer)
|
||||
SDL_Texture *texture;
|
||||
int i;
|
||||
|
||||
/* Cancel any scene that we've started */
|
||||
if (!data->beginScene) {
|
||||
IDirect3DDevice9_EndScene(data->device);
|
||||
data->beginScene = SDL_TRUE;
|
||||
}
|
||||
|
||||
/* Release the default render target before reset */
|
||||
if (data->defaultRenderTarget) {
|
||||
IDirect3DSurface9_Release(data->defaultRenderTarget);
|
||||
@@ -1660,7 +1485,6 @@ D3D_Reset(SDL_Renderer * renderer)
|
||||
data->drawstate.texture = NULL;
|
||||
data->drawstate.shader = NULL;
|
||||
data->drawstate.blend = SDL_BLENDMODE_INVALID;
|
||||
data->drawstate.is_copy_ex = SDL_FALSE;
|
||||
IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, (D3DMATRIX*)&d3dmatrix);
|
||||
|
||||
/* Let the application know that render targets were reset */
|
||||
@@ -1673,6 +1497,24 @@ D3D_Reset(SDL_Renderer * renderer)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
D3D_SetVSync(SDL_Renderer * renderer, const int vsync)
|
||||
{
|
||||
D3D_RenderData *data = renderer->driverdata;
|
||||
if (vsync) {
|
||||
data->pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
|
||||
renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
|
||||
} else {
|
||||
data->pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||
renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC;
|
||||
}
|
||||
if (D3D_Reset(renderer) < 0) {
|
||||
/* D3D_Reset will call SDL_SetError() */
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_Renderer *
|
||||
D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
{
|
||||
@@ -1724,14 +1566,13 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
renderer->QueueSetDrawColor = D3D_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */
|
||||
renderer->QueueDrawPoints = D3D_QueueDrawPoints;
|
||||
renderer->QueueDrawLines = D3D_QueueDrawPoints; /* lines and points queue vertices the same way. */
|
||||
renderer->QueueFillRects = D3D_QueueFillRects;
|
||||
renderer->QueueCopy = D3D_QueueCopy;
|
||||
renderer->QueueCopyEx = D3D_QueueCopyEx;
|
||||
renderer->QueueGeometry = D3D_QueueGeometry;
|
||||
renderer->RunCommandQueue = D3D_RunCommandQueue;
|
||||
renderer->RenderReadPixels = D3D_RenderReadPixels;
|
||||
renderer->RenderPresent = D3D_RenderPresent;
|
||||
renderer->DestroyTexture = D3D_DestroyTexture;
|
||||
renderer->DestroyRenderer = D3D_DestroyRenderer;
|
||||
renderer->SetVSync = D3D_SetVSync;
|
||||
renderer->info = D3D_RenderDriver.info;
|
||||
renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
|
||||
renderer->driverdata = data;
|
||||
@@ -1816,9 +1657,6 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
IDirect3DDevice9_GetDeviceCaps(data->device, &caps);
|
||||
renderer->info.max_texture_width = caps.MaxTextureWidth;
|
||||
renderer->info.max_texture_height = caps.MaxTextureHeight;
|
||||
if (caps.NumSimultaneousRTs >= 2) {
|
||||
renderer->info.flags |= SDL_RENDERER_TARGETTEXTURE;
|
||||
}
|
||||
|
||||
if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND) {
|
||||
data->enableSeparateAlphaBlend = SDL_TRUE;
|
||||
|
@@ -770,7 +770,11 @@ D3D11_CreateSwapChain(SDL_Renderer * renderer, int w, int h)
|
||||
if (usingXAML) {
|
||||
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
|
||||
} else {
|
||||
swapChainDesc.Scaling = DXGI_SCALING_NONE;
|
||||
if (WIN_IsWindows8OrGreater()) {
|
||||
swapChainDesc.Scaling = DXGI_SCALING_NONE;
|
||||
} else {
|
||||
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
|
||||
}
|
||||
}
|
||||
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; /* All Windows Store apps must use this SwapEffect. */
|
||||
#endif
|
||||
@@ -953,11 +957,13 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
|
||||
*
|
||||
* TODO, WinRT: reexamine the docs for IDXGISwapChain1::SetRotation, see if might be available, usable, and prudent-to-call on WinPhone 8.1
|
||||
*/
|
||||
if (data->swapEffect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL) {
|
||||
result = IDXGISwapChain1_SetRotation(data->swapChain, data->rotation);
|
||||
if (FAILED(result)) {
|
||||
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain1::SetRotation"), result);
|
||||
goto done;
|
||||
if (WIN_IsWindows8OrGreater()) {
|
||||
if (data->swapEffect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL) {
|
||||
result = IDXGISwapChain1_SetRotation(data->swapChain, data->rotation);
|
||||
if (FAILED(result)) {
|
||||
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain1::SetRotation"), result);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1634,238 +1640,61 @@ D3D11_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL
|
||||
}
|
||||
|
||||
static int
|
||||
D3D11_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count)
|
||||
D3D11_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)
|
||||
{
|
||||
VertexPositionColor *verts = (VertexPositionColor *) SDL_AllocateRenderVertices(renderer, count * 4 * sizeof (VertexPositionColor), 0, &cmd->data.draw.first);
|
||||
const float r = (float)(cmd->data.draw.r / 255.0f);
|
||||
const float g = (float)(cmd->data.draw.g / 255.0f);
|
||||
const float b = (float)(cmd->data.draw.b / 255.0f);
|
||||
const float a = (float)(cmd->data.draw.a / 255.0f);
|
||||
int i;
|
||||
int count = indices ? num_indices : num_vertices;
|
||||
VertexPositionColor *verts = (VertexPositionColor *) SDL_AllocateRenderVertices(renderer, count * sizeof (VertexPositionColor), 0, &cmd->data.draw.first);
|
||||
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd->data.draw.count = count;
|
||||
size_indices = indices ? size_indices : 0;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
verts->pos.x = rects[i].x;
|
||||
verts->pos.y = rects[i].y;
|
||||
verts->pos.z = 0.0f;
|
||||
verts->tex.x = 0.0f;
|
||||
verts->tex.y = 0.0f;
|
||||
verts->color.x = r;
|
||||
verts->color.y = g;
|
||||
verts->color.z = b;
|
||||
verts->color.w = a;
|
||||
verts++;
|
||||
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;
|
||||
}
|
||||
|
||||
verts->pos.x = rects[i].x;
|
||||
verts->pos.y = rects[i].y + rects[i].h;
|
||||
verts->pos.z = 0.0f;
|
||||
verts->tex.x = 0.0f;
|
||||
verts->tex.y = 0.0f;
|
||||
verts->color.x = r;
|
||||
verts->color.y = g;
|
||||
verts->color.z = b;
|
||||
verts->color.w = a;
|
||||
verts++;
|
||||
xy_ = (float *)((char*)xy + j * xy_stride);
|
||||
col_ = *(SDL_Color *)((char*)color + j * color_stride);
|
||||
|
||||
verts->pos.x = rects[i].x + rects[i].w;
|
||||
verts->pos.y = rects[i].y;
|
||||
verts->pos.x = xy_[0] * scale_x;
|
||||
verts->pos.y = xy_[1] * scale_y;
|
||||
verts->pos.z = 0.0f;
|
||||
verts->tex.x = 0.0f;
|
||||
verts->tex.y = 0.0f;
|
||||
verts->color.x = r;
|
||||
verts->color.y = g;
|
||||
verts->color.z = b;
|
||||
verts->color.w = a;
|
||||
verts++;
|
||||
verts->color.x = col_.r / 255.0f;
|
||||
verts->color.y = col_.g / 255.0f;
|
||||
verts->color.z = col_.b / 255.0f;
|
||||
verts->color.w = col_.a / 255.0f;
|
||||
|
||||
verts->pos.x = rects[i].x + rects[i].w;
|
||||
verts->pos.y = rects[i].y + rects[i].h;
|
||||
verts->pos.z = 0.0f;
|
||||
verts->tex.x = 0.0f;
|
||||
verts->tex.y = 0.0f;
|
||||
verts->color.x = r;
|
||||
verts->color.y = g;
|
||||
verts->color.z = b;
|
||||
verts->color.w = a;
|
||||
verts++;
|
||||
if (texture) {
|
||||
float *uv_ = (float *)((char*)uv + j * uv_stride);
|
||||
verts->tex.x = uv_[0];
|
||||
verts->tex.y = uv_[1];
|
||||
} else {
|
||||
verts->tex.x = 0.0f;
|
||||
verts->tex.y = 0.0f;
|
||||
}
|
||||
|
||||
verts += 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
D3D11_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
|
||||
const SDL_Rect * srcrect, const SDL_FRect * dstrect)
|
||||
{
|
||||
VertexPositionColor *verts = (VertexPositionColor *) SDL_AllocateRenderVertices(renderer, 4 * sizeof (VertexPositionColor), 0, &cmd->data.draw.first);
|
||||
const float r = (float)(cmd->data.draw.r / 255.0f);
|
||||
const float g = (float)(cmd->data.draw.g / 255.0f);
|
||||
const float b = (float)(cmd->data.draw.b / 255.0f);
|
||||
const float a = (float)(cmd->data.draw.a / 255.0f);
|
||||
const float minu = (float) srcrect->x / texture->w;
|
||||
const float maxu = (float) (srcrect->x + srcrect->w) / texture->w;
|
||||
const float minv = (float) srcrect->y / texture->h;
|
||||
const float maxv = (float) (srcrect->y + srcrect->h) / texture->h;
|
||||
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd->data.draw.count = 1;
|
||||
|
||||
verts->pos.x = dstrect->x;
|
||||
verts->pos.y = dstrect->y;
|
||||
verts->pos.z = 0.0f;
|
||||
verts->tex.x = minu;
|
||||
verts->tex.y = minv;
|
||||
verts->color.x = r;
|
||||
verts->color.y = g;
|
||||
verts->color.z = b;
|
||||
verts->color.w = a;
|
||||
verts++;
|
||||
|
||||
verts->pos.x = dstrect->x;
|
||||
verts->pos.y = dstrect->y + dstrect->h;
|
||||
verts->pos.z = 0.0f;
|
||||
verts->tex.x = minu;
|
||||
verts->tex.y = maxv;
|
||||
verts->color.x = r;
|
||||
verts->color.y = g;
|
||||
verts->color.z = b;
|
||||
verts->color.w = a;
|
||||
verts++;
|
||||
|
||||
verts->pos.x = dstrect->x + dstrect->w;
|
||||
verts->pos.y = dstrect->y;
|
||||
verts->pos.z = 0.0f;
|
||||
verts->tex.x = maxu;
|
||||
verts->tex.y = minv;
|
||||
verts->color.x = r;
|
||||
verts->color.y = g;
|
||||
verts->color.z = b;
|
||||
verts->color.w = a;
|
||||
verts++;
|
||||
|
||||
verts->pos.x = dstrect->x + dstrect->w;
|
||||
verts->pos.y = dstrect->y + dstrect->h;
|
||||
verts->pos.z = 0.0f;
|
||||
verts->tex.x = maxu;
|
||||
verts->tex.y = maxv;
|
||||
verts->color.x = r;
|
||||
verts->color.y = g;
|
||||
verts->color.z = b;
|
||||
verts->color.w = a;
|
||||
verts++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
D3D11_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
|
||||
const SDL_Rect * srcrect, const SDL_FRect * dstrect,
|
||||
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
|
||||
{
|
||||
VertexPositionColor *verts = (VertexPositionColor *) SDL_AllocateRenderVertices(renderer, 5 * sizeof (VertexPositionColor), 0, &cmd->data.draw.first);
|
||||
const float r = (float)(cmd->data.draw.r / 255.0f);
|
||||
const float g = (float)(cmd->data.draw.g / 255.0f);
|
||||
const float b = (float)(cmd->data.draw.b / 255.0f);
|
||||
const float a = (float)(cmd->data.draw.a / 255.0f);
|
||||
float minx, miny, maxx, maxy;
|
||||
float minu, maxu, minv, maxv;
|
||||
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd->data.draw.count = 1;
|
||||
|
||||
minx = -center->x;
|
||||
maxx = dstrect->w - center->x;
|
||||
miny = -center->y;
|
||||
maxy = dstrect->h - center->y;
|
||||
|
||||
if (flip & SDL_FLIP_HORIZONTAL) {
|
||||
minu = (float) (srcrect->x + srcrect->w) / texture->w;
|
||||
maxu = (float) srcrect->x / texture->w;
|
||||
} else {
|
||||
minu = (float) srcrect->x / texture->w;
|
||||
maxu = (float) (srcrect->x + srcrect->w) / texture->w;
|
||||
}
|
||||
|
||||
if (flip & SDL_FLIP_VERTICAL) {
|
||||
minv = (float) (srcrect->y + srcrect->h) / texture->h;
|
||||
maxv = (float) srcrect->y / texture->h;
|
||||
} else {
|
||||
minv = (float) srcrect->y / texture->h;
|
||||
maxv = (float) (srcrect->y + srcrect->h) / texture->h;
|
||||
}
|
||||
|
||||
|
||||
|
||||
verts->pos.x = minx;
|
||||
verts->pos.y = miny;
|
||||
verts->pos.z = 0.0f;
|
||||
verts->color.x = r;
|
||||
verts->color.y = g;
|
||||
verts->color.z = b;
|
||||
verts->color.w = a;
|
||||
verts->tex.x = minu;
|
||||
verts->tex.y = minv;
|
||||
verts++;
|
||||
|
||||
verts->pos.x = minx;
|
||||
verts->pos.y = maxy;
|
||||
verts->pos.z = 0.0f;
|
||||
verts->color.x = r;
|
||||
verts->color.y = g;
|
||||
verts->color.z = b;
|
||||
verts->color.w = a;
|
||||
verts->tex.x = minu;
|
||||
verts->tex.y = maxv;
|
||||
verts++;
|
||||
|
||||
verts->pos.x = maxx;
|
||||
verts->pos.y = miny;
|
||||
verts->pos.z = 0.0f;
|
||||
verts->color.x = r;
|
||||
verts->color.y = g;
|
||||
verts->color.z = b;
|
||||
verts->color.w = a;
|
||||
verts->tex.x = maxu;
|
||||
verts->tex.y = minv;
|
||||
verts++;
|
||||
|
||||
verts->pos.x = maxx;
|
||||
verts->pos.y = maxy;
|
||||
verts->pos.z = 0.0f;
|
||||
verts->color.x = r;
|
||||
verts->color.y = g;
|
||||
verts->color.z = b;
|
||||
verts->color.w = a;
|
||||
verts->tex.x = maxu;
|
||||
verts->tex.y = maxv;
|
||||
verts++;
|
||||
|
||||
verts->pos.x = dstrect->x + center->x; /* X translation */
|
||||
verts->pos.y = dstrect->y + center->y; /* Y translation */
|
||||
verts->pos.z = (float)(M_PI * (float) angle / 180.0f); /* rotation */
|
||||
verts->color.x = 0;
|
||||
verts->color.y = 0;
|
||||
verts->color.z = 0;
|
||||
verts->color.w = 0;
|
||||
verts->tex.x = 0.0f;
|
||||
verts->tex.y = 0.0f;
|
||||
verts++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
D3D11_UpdateVertexBuffer(SDL_Renderer *renderer,
|
||||
const void * vertexData, size_t dataSizeInBytes)
|
||||
@@ -2241,7 +2070,6 @@ D3D11_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
|
||||
{
|
||||
D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
|
||||
const int viewportRotation = D3D11_GetRotationForCurrentRenderTarget(renderer);
|
||||
size_t i;
|
||||
|
||||
if (rendererData->currentViewportRotation != viewportRotation) {
|
||||
rendererData->currentViewportRotation = viewportRotation;
|
||||
@@ -2313,37 +2141,28 @@ D3D11_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_FILL_RECTS: {
|
||||
case SDL_RENDERCMD_FILL_RECTS: /* unused */
|
||||
break;
|
||||
|
||||
case SDL_RENDERCMD_COPY: /* unused */
|
||||
break;
|
||||
|
||||
case SDL_RENDERCMD_COPY_EX: /* unused */
|
||||
break;
|
||||
|
||||
case SDL_RENDERCMD_GEOMETRY: {
|
||||
SDL_Texture *texture = cmd->data.draw.texture;
|
||||
const size_t count = cmd->data.draw.count;
|
||||
const size_t first = cmd->data.draw.first;
|
||||
const size_t start = first / sizeof (VertexPositionColor);
|
||||
size_t offset = 0;
|
||||
D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[SHADER_SOLID], 0, NULL, NULL, NULL);
|
||||
for (i = 0; i < count; i++, offset += 4) {
|
||||
D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, start + offset, 4);
|
||||
|
||||
if (texture) {
|
||||
D3D11_SetCopyState(renderer, cmd, NULL);
|
||||
} else {
|
||||
D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[SHADER_SOLID], 0, NULL, NULL, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_COPY: {
|
||||
const size_t first = cmd->data.draw.first;
|
||||
const size_t start = first / sizeof (VertexPositionColor);
|
||||
D3D11_SetCopyState(renderer, cmd, NULL);
|
||||
D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, start, 4);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_COPY_EX: {
|
||||
const size_t first = cmd->data.draw.first;
|
||||
const size_t start = first / sizeof (VertexPositionColor);
|
||||
const VertexPositionColor *verts = (VertexPositionColor *) (((Uint8 *) vertices) + first);
|
||||
const VertexPositionColor *transvert = verts + 4;
|
||||
const float translatex = transvert->pos.x;
|
||||
const float translatey = transvert->pos.y;
|
||||
const float rotation = transvert->pos.z;
|
||||
const Float4X4 matrix = MatrixMultiply(MatrixRotationZ(rotation), MatrixTranslation(translatex, translatey, 0));
|
||||
D3D11_SetCopyState(renderer, cmd, &matrix);
|
||||
D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, start, 4);
|
||||
D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, start, count);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2523,6 +2342,21 @@ D3D11_RenderPresent(SDL_Renderer * renderer)
|
||||
}
|
||||
}
|
||||
|
||||
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
|
||||
/* no-op. */
|
||||
#else
|
||||
static int
|
||||
D3D11_SetVSync(SDL_Renderer * renderer, const int vsync)
|
||||
{
|
||||
if (vsync) {
|
||||
renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
|
||||
} else {
|
||||
renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_Renderer *
|
||||
D3D11_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
{
|
||||
@@ -2559,9 +2393,7 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
renderer->QueueSetDrawColor = D3D11_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */
|
||||
renderer->QueueDrawPoints = D3D11_QueueDrawPoints;
|
||||
renderer->QueueDrawLines = D3D11_QueueDrawPoints; /* lines and points queue vertices the same way. */
|
||||
renderer->QueueFillRects = D3D11_QueueFillRects;
|
||||
renderer->QueueCopy = D3D11_QueueCopy;
|
||||
renderer->QueueCopyEx = D3D11_QueueCopyEx;
|
||||
renderer->QueueGeometry = D3D11_QueueGeometry;
|
||||
renderer->RunCommandQueue = D3D11_RunCommandQueue;
|
||||
renderer->RenderReadPixels = D3D11_RenderReadPixels;
|
||||
renderer->RenderPresent = D3D11_RenderPresent;
|
||||
@@ -2588,6 +2420,7 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
if ((flags & SDL_RENDERER_PRESENTVSYNC)) {
|
||||
renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
|
||||
}
|
||||
renderer->SetVSync = D3D11_SetVSync;
|
||||
#endif
|
||||
|
||||
/* HACK: make sure the SDL_Renderer references the SDL_Window data now, in
|
||||
|
357
externals/SDL/src/render/metal/SDL_render_metal.m
vendored
357
externals/SDL/src/render/metal/SDL_render_metal.m
vendored
@@ -279,26 +279,35 @@ MakePipelineState(METAL_RenderData *data, METAL_PipelineCache *cache,
|
||||
|
||||
switch (cache->vertexFunction) {
|
||||
case SDL_METAL_VERTEX_SOLID:
|
||||
/* position (float2) */
|
||||
vertdesc.layouts[0].stride = sizeof(float) * 2;
|
||||
/* position (float2), color (uchar4normalized) */
|
||||
vertdesc.layouts[0].stride = sizeof(float) * 2 + sizeof (int);
|
||||
vertdesc.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex;
|
||||
|
||||
vertdesc.attributes[0].format = MTLVertexFormatFloat2;
|
||||
vertdesc.attributes[0].offset = 0;
|
||||
vertdesc.attributes[0].bufferIndex = 0;
|
||||
|
||||
vertdesc.attributes[1].format = MTLVertexFormatUChar4Normalized;
|
||||
vertdesc.attributes[1].offset = sizeof (float) * 2;
|
||||
vertdesc.attributes[1].bufferIndex = 0;
|
||||
|
||||
break;
|
||||
case SDL_METAL_VERTEX_COPY:
|
||||
/* position (float2), texcoord (float2) */
|
||||
vertdesc.layouts[0].stride = sizeof(float) * 4;
|
||||
/* position (float2), color (uchar4normalized), texcoord (float2) */
|
||||
vertdesc.layouts[0].stride = sizeof(float) * 2 + sizeof (int) + sizeof (float) * 2;
|
||||
vertdesc.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex;
|
||||
|
||||
vertdesc.attributes[0].format = MTLVertexFormatFloat2;
|
||||
vertdesc.attributes[0].offset = 0;
|
||||
vertdesc.attributes[0].bufferIndex = 0;
|
||||
|
||||
vertdesc.attributes[1].format = MTLVertexFormatFloat2;
|
||||
vertdesc.attributes[1].offset = sizeof(float) * 2;
|
||||
vertdesc.attributes[1].format = MTLVertexFormatUChar4Normalized;
|
||||
vertdesc.attributes[1].offset = sizeof (float) * 2;
|
||||
vertdesc.attributes[1].bufferIndex = 0;
|
||||
|
||||
vertdesc.attributes[2].format = MTLVertexFormatFloat2;
|
||||
vertdesc.attributes[2].offset = sizeof(float) * 2 + sizeof (int);
|
||||
vertdesc.attributes[2].bufferIndex = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -450,7 +459,7 @@ ChoosePipelineState(METAL_RenderData *data, METAL_ShaderPipelines *pipelines, SD
|
||||
return MakePipelineState(data, cache, [NSString stringWithFormat:@" (blend=custom 0x%x)", blendmode], blendmode);
|
||||
}
|
||||
|
||||
static void
|
||||
static SDL_bool
|
||||
METAL_ActivateRenderCommandEncoder(SDL_Renderer * renderer, MTLLoadAction load, MTLClearColor *clear_color, id<MTLBuffer> vertex_buffer)
|
||||
{
|
||||
METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata;
|
||||
@@ -472,10 +481,16 @@ METAL_ActivateRenderCommandEncoder(SDL_Renderer * renderer, MTLLoadAction load,
|
||||
load = MTLLoadActionDontCare;
|
||||
}
|
||||
}
|
||||
mtltexture = data.mtlbackbuffer.texture;
|
||||
if (data.mtlbackbuffer != nil) {
|
||||
mtltexture = data.mtlbackbuffer.texture;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_assert(mtltexture);
|
||||
/* mtltexture can be nil here if macOS refused to give us a drawable,
|
||||
which apparently can happen for minimized windows, etc. */
|
||||
if (mtltexture == nil) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (load == MTLLoadActionClear) {
|
||||
SDL_assert(clear_color != NULL);
|
||||
@@ -508,6 +523,8 @@ METAL_ActivateRenderCommandEncoder(SDL_Renderer * renderer, MTLLoadAction load,
|
||||
// or whatever. This means we can _always_ batch rendering commands!
|
||||
[data.mtlcmdbuffer enqueue];
|
||||
}
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1020,13 +1037,6 @@ METAL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
}}
|
||||
|
||||
|
||||
// normalize a value from 0.0f to len into 0.0f to 1.0f.
|
||||
static inline float
|
||||
normtex(const float _val, const float len)
|
||||
{
|
||||
return _val / len;
|
||||
}
|
||||
|
||||
static int
|
||||
METAL_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd)
|
||||
{
|
||||
@@ -1060,38 +1070,56 @@ METAL_QueueSetDrawColor(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* FIXME: not needed anymore, some cleanup to do
|
||||
*
|
||||
*(verts++) = ((float)cmd->data.color.r) / 255.0f;
|
||||
*(verts++) = ((float)cmd->data.color.g) / 255.0f;
|
||||
*(verts++) = ((float)cmd->data.color.b) / 255.0f;
|
||||
*(verts++) = ((float)cmd->data.color.a) / 255.0f;
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
METAL_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
|
||||
{
|
||||
const size_t vertlen = (sizeof (float) * 2) * count;
|
||||
const int color = (cmd->data.draw.r << 0) | (cmd->data.draw.g << 8) | (cmd->data.draw.b << 16) | ((Uint32)cmd->data.draw.a << 24);
|
||||
const size_t vertlen = (2 * sizeof (float) + sizeof (int)) * count;
|
||||
float *verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first);
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
cmd->data.draw.count = count;
|
||||
SDL_memcpy(verts, points, vertlen);
|
||||
|
||||
for (int i = 0; i < count; i++, points++) {
|
||||
*(verts++) = points->x;
|
||||
*(verts++) = points->y;
|
||||
*((int *)verts++) = color;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
METAL_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
|
||||
{
|
||||
|
||||
const int color = (cmd->data.draw.r << 0) | (cmd->data.draw.g << 8) | (cmd->data.draw.b << 16) | ((Uint32)cmd->data.draw.a << 24);
|
||||
|
||||
SDL_assert(count >= 2); /* should have been checked at the higher level. */
|
||||
|
||||
const size_t vertlen = (sizeof (float) * 2) * count;
|
||||
const size_t vertlen = (2 * sizeof (float) + sizeof (int)) * count;
|
||||
float *verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first);
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
cmd->data.draw.count = count;
|
||||
SDL_memcpy(verts, points, vertlen);
|
||||
|
||||
for (int i = 0; i < count; i++, points++) {
|
||||
*(verts++) = points->x;
|
||||
*(verts++) = points->y;
|
||||
*((int *)verts++) = color;
|
||||
}
|
||||
|
||||
/* If the line segment is completely horizontal or vertical,
|
||||
make it one pixel longer, to satisfy the diamond-exit rule.
|
||||
@@ -1101,8 +1129,8 @@ METAL_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_
|
||||
that are missing a pixel that frames something and not arbitrary
|
||||
angles. Maybe !!! FIXME for later, though. */
|
||||
|
||||
points += count - 2; /* update the last line. */
|
||||
verts += (count * 2) - 2;
|
||||
points -= 2; /* update the last line. */
|
||||
verts -= 2 + 1;
|
||||
|
||||
const float xstart = points[0].x;
|
||||
const float ystart = points[0].y;
|
||||
@@ -1119,161 +1147,51 @@ METAL_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_
|
||||
}
|
||||
|
||||
static int
|
||||
METAL_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count)
|
||||
METAL_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)
|
||||
{
|
||||
const size_t vertlen = (sizeof (float) * 8) * count;
|
||||
int count = indices ? num_indices : num_vertices;
|
||||
const size_t vertlen = (2 * sizeof (float) + sizeof (int) + (texture ? 2 : 0) * sizeof (float)) * count;
|
||||
float *verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first);
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd->data.draw.count = count;
|
||||
size_indices = indices ? size_indices : 0;
|
||||
|
||||
/* Quads in the following vertex order (matches the quad index buffer):
|
||||
* 1---3
|
||||
* | \ |
|
||||
* 0---2
|
||||
*/
|
||||
for (int i = 0; i < count; i++, rects++) {
|
||||
if ((rects->w <= 0.0f) || (rects->h <= 0.0f)) {
|
||||
cmd->data.draw.count--;
|
||||
for (int i = 0; i < count; i++) {
|
||||
int j;
|
||||
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 {
|
||||
*(verts++) = rects->x;
|
||||
*(verts++) = rects->y + rects->h;
|
||||
*(verts++) = rects->x;
|
||||
*(verts++) = rects->y;
|
||||
*(verts++) = rects->x + rects->w;
|
||||
*(verts++) = rects->y + rects->h;
|
||||
*(verts++) = rects->x + rects->w;
|
||||
*(verts++) = rects->y;
|
||||
j = i;
|
||||
}
|
||||
|
||||
float *xy_ = (float *)((char*)xy + j * xy_stride);
|
||||
int col_ = *(int *)((char*)color + j * color_stride);
|
||||
|
||||
*(verts++) = xy_[0] * scale_x;
|
||||
*(verts++) = xy_[1] * scale_y;
|
||||
|
||||
*((int *)verts++) = col_;
|
||||
|
||||
if (texture) {
|
||||
float *uv_ = (float *)((char*)uv + j * uv_stride);
|
||||
*(verts++) = uv_[0];
|
||||
*(verts++) = uv_[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd->data.draw.count == 0) {
|
||||
cmd->command = SDL_RENDERCMD_NO_OP; // nothing to do, just skip this one later.
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
METAL_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
|
||||
const SDL_Rect * srcrect, const SDL_FRect * dstrect)
|
||||
{
|
||||
const float texw = (float) texture->w;
|
||||
const float texh = (float) texture->h;
|
||||
// !!! FIXME: use an index buffer
|
||||
const size_t vertlen = (sizeof (float) * 16);
|
||||
float *verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first);
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd->data.draw.count = 1;
|
||||
|
||||
/* Interleaved positions and texture coordinates */
|
||||
*(verts++) = dstrect->x;
|
||||
*(verts++) = dstrect->y + dstrect->h;
|
||||
*(verts++) = normtex(srcrect->x, texw);
|
||||
*(verts++) = normtex(srcrect->y + srcrect->h, texh);
|
||||
|
||||
*(verts++) = dstrect->x;
|
||||
*(verts++) = dstrect->y;
|
||||
*(verts++) = normtex(srcrect->x, texw);
|
||||
*(verts++) = normtex(srcrect->y, texh);
|
||||
|
||||
*(verts++) = dstrect->x + dstrect->w;
|
||||
*(verts++) = dstrect->y + dstrect->h;
|
||||
*(verts++) = normtex(srcrect->x + srcrect->w, texw);
|
||||
*(verts++) = normtex(srcrect->y + srcrect->h, texh);
|
||||
|
||||
*(verts++) = dstrect->x + dstrect->w;
|
||||
*(verts++) = dstrect->y;
|
||||
*(verts++) = normtex(srcrect->x + srcrect->w, texw);
|
||||
*(verts++) = normtex(srcrect->y, texh);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
METAL_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
|
||||
const SDL_Rect * srcquad, const SDL_FRect * dstrect,
|
||||
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
|
||||
{
|
||||
const float texw = (float) texture->w;
|
||||
const float texh = (float) texture->h;
|
||||
const float rads = (float)(M_PI * (float) angle / 180.0f);
|
||||
const float c = cosf(rads), s = sinf(rads);
|
||||
float minu, maxu, minv, maxv;
|
||||
const size_t vertlen = (sizeof (float) * 32);
|
||||
float *verts;
|
||||
|
||||
// cheat and store this offset in (count) because it needs to be aligned in ways other fields don't and we aren't using count otherwise.
|
||||
verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, CONSTANT_ALIGN(16), &cmd->data.draw.count);
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// transform matrix
|
||||
SDL_memset(verts, '\0', sizeof (*verts) * 16);
|
||||
verts[10] = verts[15] = 1.0f;
|
||||
// rotation
|
||||
verts[0] = c;
|
||||
verts[1] = s;
|
||||
verts[4] = -s;
|
||||
verts[5] = c;
|
||||
|
||||
// translation
|
||||
verts[12] = dstrect->x + center->x;
|
||||
verts[13] = dstrect->y + center->y;
|
||||
|
||||
// rest of the vertices don't need the aggressive alignment. Pack them in.
|
||||
verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first);
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
minu = normtex(srcquad->x, texw);
|
||||
maxu = normtex(srcquad->x + srcquad->w, texw);
|
||||
minv = normtex(srcquad->y, texh);
|
||||
maxv = normtex(srcquad->y + srcquad->h, texh);
|
||||
|
||||
if (flip & SDL_FLIP_HORIZONTAL) {
|
||||
float tmp = maxu;
|
||||
maxu = minu;
|
||||
minu = tmp;
|
||||
}
|
||||
if (flip & SDL_FLIP_VERTICAL) {
|
||||
float tmp = maxv;
|
||||
maxv = minv;
|
||||
minv = tmp;
|
||||
}
|
||||
|
||||
/* Interleaved positions and texture coordinates */
|
||||
*(verts++) = -center->x;
|
||||
*(verts++) = dstrect->h - center->y;
|
||||
*(verts++) = minu;
|
||||
*(verts++) = maxv;
|
||||
|
||||
*(verts++) = -center->x;
|
||||
*(verts++) = -center->y;
|
||||
*(verts++) = minu;
|
||||
*(verts++) = minv;
|
||||
|
||||
*(verts++) = dstrect->w - center->x;
|
||||
*(verts++) = dstrect->h - center->y;
|
||||
*(verts++) = maxu;
|
||||
*(verts++) = maxv;
|
||||
|
||||
*(verts++) = dstrect->w - center->x;
|
||||
*(verts++) = -center->y;
|
||||
*(verts++) = maxu;
|
||||
*(verts++) = minv;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#if __has_feature(objc_arc)
|
||||
@@ -1295,7 +1213,7 @@ typedef struct
|
||||
size_t color_offset;
|
||||
} METAL_DrawStateCache;
|
||||
|
||||
static void
|
||||
static SDL_bool
|
||||
SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const SDL_MetalFragmentFunction shader,
|
||||
const size_t constants_offset, id<MTLBuffer> mtlbufvertex, METAL_DrawStateCache *statecache)
|
||||
{
|
||||
@@ -1304,7 +1222,9 @@ SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const SDL_Met
|
||||
size_t first = cmd->data.draw.first;
|
||||
id<MTLRenderPipelineState> newpipeline;
|
||||
|
||||
METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, statecache->vertex_buffer);
|
||||
if (!METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, statecache->vertex_buffer)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (statecache->viewport_dirty) {
|
||||
MTLViewport viewport;
|
||||
@@ -1358,9 +1278,10 @@ SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const SDL_Met
|
||||
}
|
||||
|
||||
[data.mtlcmdencoder setVertexBufferOffset:first atIndex:0]; /* position/texcoords */
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
static SDL_bool
|
||||
SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const size_t constants_offset,
|
||||
id<MTLBuffer> mtlbufvertex, METAL_DrawStateCache *statecache)
|
||||
{
|
||||
@@ -1368,7 +1289,9 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const size_t
|
||||
SDL_Texture *texture = cmd->data.draw.texture;
|
||||
METAL_TextureData *texturedata = (__bridge METAL_TextureData *)texture->driverdata;
|
||||
|
||||
SetDrawState(renderer, cmd, texturedata.fragmentFunction, constants_offset, mtlbufvertex, statecache);
|
||||
if (!SetDrawState(renderer, cmd, texturedata.fragmentFunction, constants_offset, mtlbufvertex, statecache)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (texture != statecache->texture) {
|
||||
METAL_TextureData *oldtexturedata = NULL;
|
||||
@@ -1386,6 +1309,7 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const size_t
|
||||
}
|
||||
statecache->texture = texture;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1483,6 +1407,7 @@ METAL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
|
||||
MTLClearColor color = MTLClearColorMake(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f);
|
||||
|
||||
// get new command encoder, set up with an initial clear operation.
|
||||
// (this might fail, and future draw operations will notice.)
|
||||
METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionClear, &color, mtlbufvertex);
|
||||
break;
|
||||
}
|
||||
@@ -1491,44 +1416,34 @@ METAL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
|
||||
case SDL_RENDERCMD_DRAW_LINES: {
|
||||
const size_t count = cmd->data.draw.count;
|
||||
const MTLPrimitiveType primtype = (cmd->command == SDL_RENDERCMD_DRAW_POINTS) ? MTLPrimitiveTypePoint : MTLPrimitiveTypeLineStrip;
|
||||
SetDrawState(renderer, cmd, SDL_METAL_FRAGMENT_SOLID, CONSTANTS_OFFSET_HALF_PIXEL_TRANSFORM, mtlbufvertex, &statecache);
|
||||
[data.mtlcmdencoder drawPrimitives:primtype vertexStart:0 vertexCount:count];
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_FILL_RECTS: {
|
||||
const size_t count = cmd->data.draw.count;
|
||||
const size_t maxcount = UINT16_MAX / 4;
|
||||
SetDrawState(renderer, cmd, SDL_METAL_FRAGMENT_SOLID, CONSTANTS_OFFSET_IDENTITY, mtlbufvertex, &statecache);
|
||||
if (count == 1) {
|
||||
[data.mtlcmdencoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4];
|
||||
} else {
|
||||
/* Our index buffer has 16 bit indices, so we can only draw
|
||||
* 65k vertices (16k rects) at a time. */
|
||||
for (size_t i = 0; i < count; i += maxcount) {
|
||||
/* Set the vertex buffer offset for our current positions.
|
||||
* The vertex buffer itself was bound in SetDrawState. */
|
||||
[data.mtlcmdencoder setVertexBufferOffset:cmd->data.draw.first + i*sizeof(float)*8 atIndex:0];
|
||||
[data.mtlcmdencoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
||||
indexCount:SDL_min(maxcount, count - i) * 6
|
||||
indexType:MTLIndexTypeUInt16
|
||||
indexBuffer:data.mtlbufquadindices
|
||||
indexBufferOffset:0];
|
||||
}
|
||||
if (SetDrawState(renderer, cmd, SDL_METAL_FRAGMENT_SOLID, CONSTANTS_OFFSET_HALF_PIXEL_TRANSFORM, mtlbufvertex, &statecache)) {
|
||||
[data.mtlcmdencoder drawPrimitives:primtype vertexStart:0 vertexCount:count];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_COPY: {
|
||||
SetCopyState(renderer, cmd, CONSTANTS_OFFSET_IDENTITY, mtlbufvertex, &statecache);
|
||||
[data.mtlcmdencoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4];
|
||||
case SDL_RENDERCMD_FILL_RECTS: /* unused */
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_COPY_EX: {
|
||||
SetCopyState(renderer, cmd, CONSTANTS_OFFSET_INVALID, mtlbufvertex, &statecache);
|
||||
[data.mtlcmdencoder setVertexBuffer:mtlbufvertex offset:cmd->data.draw.count atIndex:3]; // transform
|
||||
[data.mtlcmdencoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4];
|
||||
case SDL_RENDERCMD_COPY: /* unused */
|
||||
break;
|
||||
|
||||
case SDL_RENDERCMD_COPY_EX: /* unused */
|
||||
break;
|
||||
|
||||
case SDL_RENDERCMD_GEOMETRY: {
|
||||
const size_t count = cmd->data.draw.count;
|
||||
SDL_Texture *texture = cmd->data.draw.texture;
|
||||
|
||||
if (texture) {
|
||||
if (SetCopyState(renderer, cmd, CONSTANTS_OFFSET_IDENTITY, mtlbufvertex, &statecache)) {
|
||||
[data.mtlcmdencoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:count];
|
||||
}
|
||||
} else {
|
||||
if (SetDrawState(renderer, cmd, SDL_METAL_FRAGMENT_SOLID, CONSTANTS_OFFSET_IDENTITY, mtlbufvertex, &statecache)) {
|
||||
[data.mtlcmdencoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:count];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1546,7 +1461,9 @@ METAL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
||||
Uint32 pixel_format, void * pixels, int pitch)
|
||||
{ @autoreleasepool {
|
||||
METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata;
|
||||
METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, nil);
|
||||
if (!METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, nil)) {
|
||||
return SDL_SetError("Failed to activate render command encoder (is your window in the background?");
|
||||
}
|
||||
|
||||
[data.mtlcmdencoder endEncoding];
|
||||
id<MTLTexture> mtltexture = data.mtlpassdesc.colorAttachments[0].texture;
|
||||
@@ -1591,20 +1508,28 @@ static void
|
||||
METAL_RenderPresent(SDL_Renderer * renderer)
|
||||
{ @autoreleasepool {
|
||||
METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata;
|
||||
SDL_bool ready = SDL_TRUE;
|
||||
|
||||
// If we don't have a command buffer, we can't present, so activate to get one.
|
||||
if (data.mtlcmdencoder == nil) {
|
||||
// We haven't even gotten a backbuffer yet? Clear it to black. Otherwise, load the existing data.
|
||||
if (data.mtlbackbuffer == nil) {
|
||||
MTLClearColor color = MTLClearColorMake(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionClear, &color, nil);
|
||||
ready = METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionClear, &color, nil);
|
||||
} else {
|
||||
METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, nil);
|
||||
ready = METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, nil);
|
||||
}
|
||||
}
|
||||
|
||||
[data.mtlcmdencoder endEncoding];
|
||||
[data.mtlcmdbuffer presentDrawable:data.mtlbackbuffer];
|
||||
|
||||
// If we don't have a drawable to present, don't try to present it.
|
||||
// But we'll still try to commit the command buffer in case it was already enqueued.
|
||||
if (ready) {
|
||||
SDL_assert(data.mtlbackbuffer != nil);
|
||||
[data.mtlcmdbuffer presentDrawable:data.mtlbackbuffer];
|
||||
}
|
||||
|
||||
[data.mtlcmdbuffer commit];
|
||||
|
||||
data.mtlcmdencoder = nil;
|
||||
@@ -1647,11 +1572,34 @@ METAL_GetMetalLayer(SDL_Renderer * renderer)
|
||||
static void *
|
||||
METAL_GetMetalCommandEncoder(SDL_Renderer * renderer)
|
||||
{ @autoreleasepool {
|
||||
// note that data.mtlcmdencoder can be nil if METAL_ActivateRenderCommandEncoder fails.
|
||||
// Before SDL 2.0.18, it might have returned a non-nil encoding that might not have been
|
||||
// usable for presentation. Check your return values!
|
||||
METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, nil);
|
||||
METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata;
|
||||
return (__bridge void*)data.mtlcmdencoder;
|
||||
}}
|
||||
|
||||
static int
|
||||
METAL_SetVSync(SDL_Renderer * renderer, const int vsync)
|
||||
{
|
||||
#if (defined(__MACOSX__) && defined(MAC_OS_X_VERSION_10_13)) || TARGET_OS_MACCATALYST
|
||||
if (@available(macOS 10.13, *)) {
|
||||
METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata;
|
||||
if (vsync) {
|
||||
data.mtllayer.displaySyncEnabled = YES;
|
||||
renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
|
||||
} else {
|
||||
data.mtllayer.displaySyncEnabled = NO;
|
||||
renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return SDL_SetError("This Apple OS does not support displaySyncEnabled!");
|
||||
}
|
||||
|
||||
|
||||
static SDL_Renderer *
|
||||
METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
{ @autoreleasepool {
|
||||
@@ -1891,14 +1839,13 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
renderer->QueueSetDrawColor = METAL_QueueSetDrawColor;
|
||||
renderer->QueueDrawPoints = METAL_QueueDrawPoints;
|
||||
renderer->QueueDrawLines = METAL_QueueDrawLines;
|
||||
renderer->QueueFillRects = METAL_QueueFillRects;
|
||||
renderer->QueueCopy = METAL_QueueCopy;
|
||||
renderer->QueueCopyEx = METAL_QueueCopyEx;
|
||||
renderer->QueueGeometry = METAL_QueueGeometry;
|
||||
renderer->RunCommandQueue = METAL_RunCommandQueue;
|
||||
renderer->RenderReadPixels = METAL_RenderReadPixels;
|
||||
renderer->RenderPresent = METAL_RenderPresent;
|
||||
renderer->DestroyTexture = METAL_DestroyTexture;
|
||||
renderer->DestroyRenderer = METAL_DestroyRenderer;
|
||||
renderer->SetVSync = METAL_SetVSync;
|
||||
renderer->GetMetalLayer = METAL_GetMetalLayer;
|
||||
renderer->GetMetalCommandEncoder = METAL_GetMetalCommandEncoder;
|
||||
|
||||
|
@@ -6,11 +6,13 @@ using namespace metal;
|
||||
struct SolidVertexInput
|
||||
{
|
||||
float2 position [[attribute(0)]];
|
||||
float4 color [[attribute(1)]];
|
||||
};
|
||||
|
||||
struct SolidVertexOutput
|
||||
{
|
||||
float4 position [[position]];
|
||||
float4 color;
|
||||
float pointSize [[point_size]];
|
||||
};
|
||||
|
||||
@@ -20,24 +22,27 @@ vertex SolidVertexOutput SDL_Solid_vertex(SolidVertexInput in [[stage_in]],
|
||||
{
|
||||
SolidVertexOutput v;
|
||||
v.position = (projection * transform) * float4(in.position, 0.0f, 1.0f);
|
||||
v.color = in.color;
|
||||
v.pointSize = 1.0f;
|
||||
return v;
|
||||
}
|
||||
|
||||
fragment float4 SDL_Solid_fragment(const device float4 &col [[buffer(0)]])
|
||||
fragment float4 SDL_Solid_fragment(SolidVertexInput in [[stage_in]])
|
||||
{
|
||||
return col;
|
||||
return in.color;
|
||||
}
|
||||
|
||||
struct CopyVertexInput
|
||||
{
|
||||
float2 position [[attribute(0)]];
|
||||
float2 texcoord [[attribute(1)]];
|
||||
float4 color [[attribute(1)]];
|
||||
float2 texcoord [[attribute(2)]];
|
||||
};
|
||||
|
||||
struct CopyVertexOutput
|
||||
{
|
||||
float4 position [[position]];
|
||||
float4 color;
|
||||
float2 texcoord;
|
||||
};
|
||||
|
||||
@@ -47,16 +52,16 @@ vertex CopyVertexOutput SDL_Copy_vertex(CopyVertexInput in [[stage_in]],
|
||||
{
|
||||
CopyVertexOutput v;
|
||||
v.position = (projection * transform) * float4(in.position, 0.0f, 1.0f);
|
||||
v.color = in.color;
|
||||
v.texcoord = in.texcoord;
|
||||
return v;
|
||||
}
|
||||
|
||||
fragment float4 SDL_Copy_fragment(CopyVertexOutput vert [[stage_in]],
|
||||
const device float4 &col [[buffer(0)]],
|
||||
texture2d<float> tex [[texture(0)]],
|
||||
sampler s [[sampler(0)]])
|
||||
{
|
||||
return tex.sample(s, vert.texcoord) * col;
|
||||
return tex.sample(s, vert.texcoord) * vert.color;
|
||||
}
|
||||
|
||||
struct YUVDecode
|
||||
@@ -68,7 +73,6 @@ struct YUVDecode
|
||||
};
|
||||
|
||||
fragment float4 SDL_YUV_fragment(CopyVertexOutput vert [[stage_in]],
|
||||
const device float4 &col [[buffer(0)]],
|
||||
constant YUVDecode &decode [[buffer(1)]],
|
||||
texture2d<float> texY [[texture(0)]],
|
||||
texture2d_array<float> texUV [[texture(1)]],
|
||||
@@ -81,11 +85,10 @@ fragment float4 SDL_YUV_fragment(CopyVertexOutput vert [[stage_in]],
|
||||
|
||||
yuv += decode.offset;
|
||||
|
||||
return col * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0);
|
||||
return vert.color * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0);
|
||||
}
|
||||
|
||||
fragment float4 SDL_NV12_fragment(CopyVertexOutput vert [[stage_in]],
|
||||
const device float4 &col [[buffer(0)]],
|
||||
constant YUVDecode &decode [[buffer(1)]],
|
||||
texture2d<float> texY [[texture(0)]],
|
||||
texture2d<float> texUV [[texture(1)]],
|
||||
@@ -97,11 +100,10 @@ fragment float4 SDL_NV12_fragment(CopyVertexOutput vert [[stage_in]],
|
||||
|
||||
yuv += decode.offset;
|
||||
|
||||
return col * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0);
|
||||
return vert.color * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0);
|
||||
}
|
||||
|
||||
fragment float4 SDL_NV21_fragment(CopyVertexOutput vert [[stage_in]],
|
||||
const device float4 &col [[buffer(0)]],
|
||||
constant YUVDecode &decode [[buffer(1)]],
|
||||
texture2d<float> texY [[texture(0)]],
|
||||
texture2d<float> texUV [[texture(1)]],
|
||||
@@ -113,5 +115,6 @@ fragment float4 SDL_NV21_fragment(CopyVertexOutput vert [[stage_in]],
|
||||
|
||||
yuv += decode.offset;
|
||||
|
||||
return col * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0);
|
||||
return vert.color * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0);
|
||||
}
|
||||
|
||||
|
3426
externals/SDL/src/render/metal/SDL_shaders_metal_ios.h
vendored
3426
externals/SDL/src/render/metal/SDL_shaders_metal_ios.h
vendored
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
3454
externals/SDL/src/render/metal/SDL_shaders_metal_osx.h
vendored
3454
externals/SDL/src/render/metal/SDL_shaders_metal_osx.h
vendored
File diff suppressed because it is too large
Load Diff
3426
externals/SDL/src/render/metal/SDL_shaders_metal_tvos.h
vendored
3426
externals/SDL/src/render/metal/SDL_shaders_metal_tvos.h
vendored
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
10
externals/SDL/src/render/opengl/SDL_glfuncs.h
vendored
10
externals/SDL/src/render/opengl/SDL_glfuncs.h
vendored
@@ -159,7 +159,7 @@ SDL_PROC_UNUSED(void, glGetBooleanv, (GLenum pname, GLboolean * params))
|
||||
SDL_PROC_UNUSED(void, glGetClipPlane, (GLenum plane, GLdouble * equation))
|
||||
SDL_PROC_UNUSED(void, glGetDoublev, (GLenum pname, GLdouble * params))
|
||||
SDL_PROC(GLenum, glGetError, (void))
|
||||
SDL_PROC_UNUSED(void, glGetFloatv, (GLenum pname, GLfloat * params))
|
||||
SDL_PROC(void, glGetFloatv, (GLenum pname, GLfloat * params))
|
||||
SDL_PROC(void, glGetIntegerv, (GLenum pname, GLint * params))
|
||||
SDL_PROC_UNUSED(void, glGetLightfv,
|
||||
(GLenum light, GLenum pname, GLfloat * params))
|
||||
@@ -302,14 +302,14 @@ SDL_PROC_UNUSED(void, glPolygonOffset, (GLfloat factor, GLfloat units))
|
||||
SDL_PROC_UNUSED(void, glPolygonStipple, (const GLubyte * mask))
|
||||
SDL_PROC_UNUSED(void, glPopAttrib, (void))
|
||||
SDL_PROC_UNUSED(void, glPopClientAttrib, (void))
|
||||
SDL_PROC(void, glPopMatrix, (void))
|
||||
SDL_PROC_UNUSED(void, glPopMatrix, (void))
|
||||
SDL_PROC_UNUSED(void, glPopName, (void))
|
||||
SDL_PROC_UNUSED(void, glPrioritizeTextures,
|
||||
(GLsizei n, const GLuint * textures,
|
||||
const GLclampf * priorities))
|
||||
SDL_PROC_UNUSED(void, glPushAttrib, (GLbitfield mask))
|
||||
SDL_PROC_UNUSED(void, glPushClientAttrib, (GLbitfield mask))
|
||||
SDL_PROC(void, glPushMatrix, (void))
|
||||
SDL_PROC_UNUSED(void, glPushMatrix, (void))
|
||||
SDL_PROC_UNUSED(void, glPushName, (GLuint name))
|
||||
SDL_PROC_UNUSED(void, glRasterPos2d, (GLdouble x, GLdouble y))
|
||||
SDL_PROC_UNUSED(void, glRasterPos2dv, (const GLdouble * v))
|
||||
@@ -354,7 +354,7 @@ SDL_PROC_UNUSED(void, glRects,
|
||||
(GLshort x1, GLshort y1, GLshort x2, GLshort y2))
|
||||
SDL_PROC_UNUSED(void, glRectsv, (const GLshort * v1, const GLshort * v2))
|
||||
SDL_PROC_UNUSED(GLint, glRenderMode, (GLenum mode))
|
||||
SDL_PROC(void, glRotated,
|
||||
SDL_PROC_UNUSED(void, glRotated,
|
||||
(GLdouble angle, GLdouble x, GLdouble y, GLdouble z))
|
||||
SDL_PROC(void, glRotatef,
|
||||
(GLfloat angle, GLfloat x, GLfloat y, GLfloat z))
|
||||
@@ -442,7 +442,7 @@ SDL_PROC(void, glTexSubImage2D,
|
||||
GLsizei width, GLsizei height, GLenum format, GLenum type,
|
||||
const GLvoid * pixels))
|
||||
SDL_PROC_UNUSED(void, glTranslated, (GLdouble x, GLdouble y, GLdouble z))
|
||||
SDL_PROC(void, glTranslatef, (GLfloat x, GLfloat y, GLfloat z))
|
||||
SDL_PROC_UNUSED(void, glTranslatef, (GLfloat x, GLfloat y, GLfloat z))
|
||||
SDL_PROC_UNUSED(void, glVertex2d, (GLdouble x, GLdouble y))
|
||||
SDL_PROC_UNUSED(void, glVertex2dv, (const GLdouble * v))
|
||||
SDL_PROC(void, glVertex2f, (GLfloat x, GLfloat y))
|
||||
|
553
externals/SDL/src/render/opengl/SDL_render_gl.c
vendored
553
externals/SDL/src/render/opengl/SDL_render_gl.c
vendored
@@ -21,7 +21,6 @@
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_RENDER_OGL && !SDL_RENDER_DISABLED
|
||||
|
||||
#include "SDL_hints.h"
|
||||
#include "SDL_opengl.h"
|
||||
#include "../SDL_sysrender.h"
|
||||
@@ -124,6 +123,7 @@ typedef struct
|
||||
GLfloat texh;
|
||||
GLenum format;
|
||||
GLenum formattype;
|
||||
GL_Shader shader;
|
||||
void *pixels;
|
||||
int pitch;
|
||||
SDL_Rect locked_rect;
|
||||
@@ -631,6 +631,57 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (texture->format == SDL_PIXELFORMAT_ABGR8888 || texture->format == SDL_PIXELFORMAT_ARGB8888) {
|
||||
data->shader = SHADER_RGBA;
|
||||
} else {
|
||||
data->shader = SHADER_RGB;
|
||||
}
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
if (data->yuv || data->nv12) {
|
||||
switch (SDL_GetYUVConversionModeForResolution(texture->w, texture->h)) {
|
||||
case SDL_YUV_CONVERSION_JPEG:
|
||||
if (data->yuv) {
|
||||
data->shader = SHADER_YUV_JPEG;
|
||||
} else if (texture->format == SDL_PIXELFORMAT_NV12) {
|
||||
data->shader = SHADER_NV12_JPEG;
|
||||
} else {
|
||||
data->shader = SHADER_NV21_JPEG;
|
||||
}
|
||||
break;
|
||||
case SDL_YUV_CONVERSION_BT601:
|
||||
if (data->yuv) {
|
||||
data->shader = SHADER_YUV_BT601;
|
||||
} else if (texture->format == SDL_PIXELFORMAT_NV12) {
|
||||
if (SDL_GetHintBoolean("SDL_RENDER_OPENGL_NV12_RG_SHADER", SDL_FALSE)) {
|
||||
data->shader = SHADER_NV12_RG_BT601;
|
||||
} else {
|
||||
data->shader = SHADER_NV12_RA_BT601;
|
||||
}
|
||||
} else {
|
||||
data->shader = SHADER_NV21_BT601;
|
||||
}
|
||||
break;
|
||||
case SDL_YUV_CONVERSION_BT709:
|
||||
if (data->yuv) {
|
||||
data->shader = SHADER_YUV_BT709;
|
||||
} else if (texture->format == SDL_PIXELFORMAT_NV12) {
|
||||
if (SDL_GetHintBoolean("SDL_RENDER_OPENGL_NV12_RG_SHADER", SDL_FALSE)) {
|
||||
data->shader = SHADER_NV12_RG_BT709;
|
||||
} else {
|
||||
data->shader = SHADER_NV12_RA_BT709;
|
||||
}
|
||||
} else {
|
||||
data->shader = SHADER_NV21_BT709;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
SDL_assert(!"unsupported YUV conversion mode");
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* SDL_HAVE_YUV */
|
||||
|
||||
return GL_CheckError("", renderer);
|
||||
}
|
||||
|
||||
@@ -891,164 +942,98 @@ static int
|
||||
GL_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
|
||||
{
|
||||
int i;
|
||||
GLfloat prevx, prevy;
|
||||
const size_t vertlen = (sizeof (GLfloat) * 2) * count;
|
||||
GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, vertlen, 0, &cmd->data.draw.first);
|
||||
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
cmd->data.draw.count = count;
|
||||
|
||||
/* Offset to hit the center of the pixel. */
|
||||
for (i = 0; i < count; i++) {
|
||||
*(verts++) = 0.5f + points[i].x;
|
||||
*(verts++) = 0.5f + points[i].y;
|
||||
/* 0.5f offset to hit the center of the pixel. */
|
||||
prevx = 0.5f + points->x;
|
||||
prevy = 0.5f + points->y;
|
||||
*(verts++) = prevx;
|
||||
*(verts++) = prevy;
|
||||
|
||||
/* bump the end of each line segment out a quarter of a pixel, to provoke
|
||||
the diamond-exit rule. Without this, you won't just drop the last
|
||||
pixel of the last line segment, but you might also drop pixels at the
|
||||
edge of any given line segment along the way too. */
|
||||
for (i = 1; i < count; i++) {
|
||||
const GLfloat xstart = prevx;
|
||||
const GLfloat ystart = prevy;
|
||||
const GLfloat xend = points[i].x + 0.5f; /* 0.5f to hit pixel center. */
|
||||
const GLfloat yend = points[i].y + 0.5f;
|
||||
/* bump a little in the direction we are moving in. */
|
||||
const GLfloat deltax = xend - xstart;
|
||||
const GLfloat deltay = yend - ystart;
|
||||
const GLfloat angle = SDL_atan2f(deltay, deltax);
|
||||
prevx = xend + (SDL_cosf(angle) * 0.25f);
|
||||
prevy = yend + (SDL_sinf(angle) * 0.25f);
|
||||
*(verts++) = prevx;
|
||||
*(verts++) = prevy;
|
||||
}
|
||||
|
||||
/* Make the last line segment one pixel longer, to satisfy the
|
||||
diamond-exit rule. */
|
||||
verts -= 4;
|
||||
{
|
||||
const GLfloat xstart = verts[0];
|
||||
const GLfloat ystart = verts[1];
|
||||
const GLfloat xend = verts[2];
|
||||
const GLfloat yend = verts[3];
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ystart == yend) { /* horizontal line */
|
||||
verts[(xend > xstart) ? 2 : 0] += 1.0f;
|
||||
} else if (xstart == xend) { /* vertical line */
|
||||
verts[(yend > ystart) ? 3 : 1] += 1.0f;
|
||||
} else { /* bump a pixel in the direction we are moving in. */
|
||||
const GLfloat deltax = xend - xstart;
|
||||
const GLfloat deltay = yend - ystart;
|
||||
const GLfloat angle = SDL_atan2f(deltay, deltax);
|
||||
verts[2] += SDL_cosf(angle);
|
||||
verts[3] += SDL_sinf(angle);
|
||||
static int
|
||||
GL_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)
|
||||
{
|
||||
GL_TextureData *texturedata = NULL;
|
||||
int i;
|
||||
int count = indices ? num_indices : num_vertices;
|
||||
GLfloat *verts;
|
||||
int sz = 2 + 4 + (texture ? 2 : 0);
|
||||
|
||||
verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * sz * sizeof (GLfloat), 0, &cmd->data.draw.first);
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (texture) {
|
||||
texturedata = (GL_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 * inv255f;
|
||||
*(verts++) = col_.g * inv255f;
|
||||
*(verts++) = col_.b * inv255f;
|
||||
*(verts++) = col_.a * inv255f;
|
||||
|
||||
if (texture) {
|
||||
float *uv_ = (float *)((char*)uv + j * uv_stride);
|
||||
*(verts++) = uv_[0] * texturedata->texw;
|
||||
*(verts++) = uv_[1] * texturedata->texh;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
GL_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count)
|
||||
{
|
||||
GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * 4 * sizeof (GLfloat), 0, &cmd->data.draw.first);
|
||||
int i;
|
||||
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd->data.draw.count = count;
|
||||
for (i = 0; i < count; i++) {
|
||||
const SDL_FRect *rect = &rects[i];
|
||||
*(verts++) = rect->x;
|
||||
*(verts++) = rect->y;
|
||||
*(verts++) = rect->x + rect->w;
|
||||
*(verts++) = rect->y + rect->h;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
GL_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
|
||||
const SDL_Rect * srcrect, const SDL_FRect * dstrect)
|
||||
{
|
||||
GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
|
||||
GLfloat minx, miny, maxx, maxy;
|
||||
GLfloat minu, maxu, minv, maxv;
|
||||
GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, 8 * sizeof (GLfloat), 0, &cmd->data.draw.first);
|
||||
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd->data.draw.count = 1;
|
||||
|
||||
minx = dstrect->x;
|
||||
miny = dstrect->y;
|
||||
maxx = dstrect->x + dstrect->w;
|
||||
maxy = dstrect->y + dstrect->h;
|
||||
|
||||
minu = (GLfloat) srcrect->x / texture->w;
|
||||
minu *= texturedata->texw;
|
||||
maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w;
|
||||
maxu *= texturedata->texw;
|
||||
minv = (GLfloat) srcrect->y / texture->h;
|
||||
minv *= texturedata->texh;
|
||||
maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
|
||||
maxv *= texturedata->texh;
|
||||
|
||||
cmd->data.draw.count = 1;
|
||||
*(verts++) = minx;
|
||||
*(verts++) = miny;
|
||||
*(verts++) = maxx;
|
||||
*(verts++) = maxy;
|
||||
*(verts++) = minu;
|
||||
*(verts++) = maxu;
|
||||
*(verts++) = minv;
|
||||
*(verts++) = maxv;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
GL_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
|
||||
const SDL_Rect * srcrect, const SDL_FRect * dstrect,
|
||||
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
|
||||
{
|
||||
GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
|
||||
GLfloat minx, miny, maxx, maxy;
|
||||
GLfloat centerx, centery;
|
||||
GLfloat minu, maxu, minv, maxv;
|
||||
GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, 11 * sizeof (GLfloat), 0, &cmd->data.draw.first);
|
||||
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
centerx = center->x;
|
||||
centery = center->y;
|
||||
|
||||
if (flip & SDL_FLIP_HORIZONTAL) {
|
||||
minx = dstrect->w - centerx;
|
||||
maxx = -centerx;
|
||||
}
|
||||
else {
|
||||
minx = -centerx;
|
||||
maxx = dstrect->w - centerx;
|
||||
}
|
||||
|
||||
if (flip & SDL_FLIP_VERTICAL) {
|
||||
miny = dstrect->h - centery;
|
||||
maxy = -centery;
|
||||
}
|
||||
else {
|
||||
miny = -centery;
|
||||
maxy = dstrect->h - centery;
|
||||
}
|
||||
|
||||
minu = (GLfloat) srcrect->x / texture->w;
|
||||
minu *= texturedata->texw;
|
||||
maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w;
|
||||
maxu *= texturedata->texw;
|
||||
minv = (GLfloat) srcrect->y / texture->h;
|
||||
minv *= texturedata->texh;
|
||||
maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
|
||||
maxv *= texturedata->texh;
|
||||
|
||||
cmd->data.draw.count = 1;
|
||||
*(verts++) = minx;
|
||||
*(verts++) = miny;
|
||||
*(verts++) = maxx;
|
||||
*(verts++) = maxy;
|
||||
*(verts++) = minu;
|
||||
*(verts++) = maxu;
|
||||
*(verts++) = minv;
|
||||
*(verts++) = maxv;
|
||||
*(verts++) = (GLfloat) dstrect->x + centerx;
|
||||
*(verts++) = (GLfloat) dstrect->y + centery;
|
||||
*(verts++) = (GLfloat) angle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1128,71 +1113,33 @@ SetCopyState(GL_RenderData *data, const SDL_RenderCommand *cmd)
|
||||
{
|
||||
SDL_Texture *texture = cmd->data.draw.texture;
|
||||
const GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
|
||||
GL_Shader shader;
|
||||
|
||||
if (texture->format == SDL_PIXELFORMAT_ABGR8888 || texture->format == SDL_PIXELFORMAT_ARGB8888) {
|
||||
shader = SHADER_RGBA;
|
||||
} else {
|
||||
shader = SHADER_RGB;
|
||||
}
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
if (data->shaders) {
|
||||
if (texturedata->yuv || texturedata->nv12) {
|
||||
switch (SDL_GetYUVConversionModeForResolution(texture->w, texture->h)) {
|
||||
case SDL_YUV_CONVERSION_JPEG:
|
||||
if (texturedata->yuv) {
|
||||
shader = SHADER_YUV_JPEG;
|
||||
} else if (texture->format == SDL_PIXELFORMAT_NV12) {
|
||||
shader = SHADER_NV12_JPEG;
|
||||
} else {
|
||||
shader = SHADER_NV21_JPEG;
|
||||
}
|
||||
break;
|
||||
case SDL_YUV_CONVERSION_BT601:
|
||||
if (texturedata->yuv) {
|
||||
shader = SHADER_YUV_BT601;
|
||||
} else if (texture->format == SDL_PIXELFORMAT_NV12) {
|
||||
shader = SHADER_NV12_BT601;
|
||||
} else {
|
||||
shader = SHADER_NV21_BT601;
|
||||
}
|
||||
break;
|
||||
case SDL_YUV_CONVERSION_BT709:
|
||||
if (texturedata->yuv) {
|
||||
shader = SHADER_YUV_BT709;
|
||||
} else if (texture->format == SDL_PIXELFORMAT_NV12) {
|
||||
shader = SHADER_NV12_BT709;
|
||||
} else {
|
||||
shader = SHADER_NV21_BT709;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
SDL_assert(!"unsupported YUV conversion mode");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
SetDrawState(data, cmd, shader);
|
||||
SetDrawState(data, cmd, texturedata->shader);
|
||||
|
||||
if (texture != data->drawstate.texture) {
|
||||
const GLenum textype = data->textype;
|
||||
#if SDL_HAVE_YUV
|
||||
if (texturedata->yuv) {
|
||||
data->glActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
if (data->GL_ARB_multitexture_supported) {
|
||||
data->glActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
}
|
||||
data->glBindTexture(textype, texturedata->vtexture);
|
||||
|
||||
data->glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
if (data->GL_ARB_multitexture_supported) {
|
||||
data->glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
}
|
||||
data->glBindTexture(textype, texturedata->utexture);
|
||||
}
|
||||
if (texturedata->nv12) {
|
||||
data->glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
if (data->GL_ARB_multitexture_supported) {
|
||||
data->glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
}
|
||||
data->glBindTexture(textype, texturedata->utexture);
|
||||
}
|
||||
#endif
|
||||
data->glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
if (data->GL_ARB_multitexture_supported) {
|
||||
data->glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
data->glBindTexture(textype, texturedata->texture);
|
||||
|
||||
data->drawstate.texture = texture;
|
||||
@@ -1212,9 +1159,22 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
|
||||
|
||||
data->drawstate.target = renderer->target;
|
||||
if (!data->drawstate.target) {
|
||||
SDL_GL_GetDrawableSize(renderer->window, &data->drawstate.drawablew, &data->drawstate.drawableh);
|
||||
int w, h;
|
||||
SDL_GL_GetDrawableSize(renderer->window, &w, &h);
|
||||
if ((w != data->drawstate.drawablew) || (h != data->drawstate.drawableh)) {
|
||||
data->drawstate.viewport_dirty = SDL_TRUE; // if the window dimensions changed, invalidate the current viewport, etc.
|
||||
data->drawstate.cliprect_dirty = SDL_TRUE;
|
||||
data->drawstate.drawablew = w;
|
||||
data->drawstate.drawableh = h;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __MACOSX__
|
||||
// On macOS, moving the window seems to invalidate the OpenGL viewport state,
|
||||
// so don't bother trying to persist it across frames; always reset it.
|
||||
// Workaround for: https://github.com/libsdl-org/SDL/issues/1504
|
||||
data->drawstate.viewport_dirty = SDL_TRUE;
|
||||
#endif
|
||||
|
||||
while (cmd) {
|
||||
switch (cmd->command) {
|
||||
@@ -1223,7 +1183,7 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
|
||||
const Uint8 g = cmd->data.color.g;
|
||||
const Uint8 b = cmd->data.color.b;
|
||||
const Uint8 a = cmd->data.color.a;
|
||||
const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
|
||||
const Uint32 color = (((Uint32)a << 24) | (r << 16) | (g << 8) | b);
|
||||
if (color != data->drawstate.color) {
|
||||
data->glColor4f((GLfloat) r * inv255f,
|
||||
(GLfloat) g * inv255f,
|
||||
@@ -1261,7 +1221,7 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
|
||||
const Uint8 g = cmd->data.color.g;
|
||||
const Uint8 b = cmd->data.color.b;
|
||||
const Uint8 a = cmd->data.color.a;
|
||||
const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
|
||||
const Uint32 color = (((Uint32)a << 24) | (r << 16) | (g << 8) | b);
|
||||
if (color != data->drawstate.clear_color) {
|
||||
const GLfloat fr = ((GLfloat) r) * inv255f;
|
||||
const GLfloat fg = ((GLfloat) g) * inv255f;
|
||||
@@ -1306,72 +1266,56 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_FILL_RECTS: {
|
||||
const size_t count = cmd->data.draw.count;
|
||||
case SDL_RENDERCMD_FILL_RECTS: /* unused */
|
||||
break;
|
||||
|
||||
case SDL_RENDERCMD_COPY: /* unused */
|
||||
break;
|
||||
|
||||
case SDL_RENDERCMD_COPY_EX: /* unused */
|
||||
break;
|
||||
|
||||
case SDL_RENDERCMD_GEOMETRY: {
|
||||
const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
|
||||
SetDrawState(data, cmd, SHADER_SOLID);
|
||||
for (i = 0; i < count; ++i, verts += 4) {
|
||||
data->glRectf(verts[0], verts[1], verts[2], verts[3]);
|
||||
SDL_Texture *texture = cmd->data.draw.texture;
|
||||
const size_t count = cmd->data.draw.count;
|
||||
|
||||
if (texture) {
|
||||
SetCopyState(data, cmd);
|
||||
} else {
|
||||
SetDrawState(data, cmd, SHADER_SOLID);
|
||||
}
|
||||
|
||||
{
|
||||
size_t j;
|
||||
float currentColor[4];
|
||||
data->glGetFloatv(GL_CURRENT_COLOR, currentColor);
|
||||
data->glBegin(GL_TRIANGLES);
|
||||
for (j = 0; j < count; ++j)
|
||||
{
|
||||
const GLfloat x = *(verts++);
|
||||
const GLfloat y = *(verts++);
|
||||
|
||||
const GLfloat r = *(verts++);
|
||||
const GLfloat g = *(verts++);
|
||||
const GLfloat b = *(verts++);
|
||||
const GLfloat a = *(verts++);
|
||||
|
||||
data->glColor4f(r, g, b, a);
|
||||
|
||||
if (texture) {
|
||||
GLfloat u = *(verts++);
|
||||
GLfloat v = *(verts++);
|
||||
data->glTexCoord2f(u,v);
|
||||
}
|
||||
data->glVertex2f(x, y);
|
||||
}
|
||||
data->glEnd();
|
||||
data->glColor4f(currentColor[0], currentColor[1], currentColor[2], currentColor[3]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_COPY: {
|
||||
const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
|
||||
const GLfloat minx = verts[0];
|
||||
const GLfloat miny = verts[1];
|
||||
const GLfloat maxx = verts[2];
|
||||
const GLfloat maxy = verts[3];
|
||||
const GLfloat minu = verts[4];
|
||||
const GLfloat maxu = verts[5];
|
||||
const GLfloat minv = verts[6];
|
||||
const GLfloat maxv = verts[7];
|
||||
SetCopyState(data, cmd);
|
||||
data->glBegin(GL_TRIANGLE_STRIP);
|
||||
data->glTexCoord2f(minu, minv);
|
||||
data->glVertex2f(minx, miny);
|
||||
data->glTexCoord2f(maxu, minv);
|
||||
data->glVertex2f(maxx, miny);
|
||||
data->glTexCoord2f(minu, maxv);
|
||||
data->glVertex2f(minx, maxy);
|
||||
data->glTexCoord2f(maxu, maxv);
|
||||
data->glVertex2f(maxx, maxy);
|
||||
data->glEnd();
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_COPY_EX: {
|
||||
const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
|
||||
const GLfloat minx = verts[0];
|
||||
const GLfloat miny = verts[1];
|
||||
const GLfloat maxx = verts[2];
|
||||
const GLfloat maxy = verts[3];
|
||||
const GLfloat minu = verts[4];
|
||||
const GLfloat maxu = verts[5];
|
||||
const GLfloat minv = verts[6];
|
||||
const GLfloat maxv = verts[7];
|
||||
const GLfloat translatex = verts[8];
|
||||
const GLfloat translatey = verts[9];
|
||||
const GLdouble angle = verts[10];
|
||||
SetCopyState(data, cmd);
|
||||
|
||||
/* Translate to flip, rotate, translate to position */
|
||||
data->glPushMatrix();
|
||||
data->glTranslatef(translatex, translatey, 0.0f);
|
||||
data->glRotated(angle, 0.0, 0.0, 1.0);
|
||||
data->glBegin(GL_TRIANGLE_STRIP);
|
||||
data->glTexCoord2f(minu, minv);
|
||||
data->glVertex2f(minx, miny);
|
||||
data->glTexCoord2f(maxu, minv);
|
||||
data->glVertex2f(maxx, miny);
|
||||
data->glTexCoord2f(minu, maxv);
|
||||
data->glVertex2f(minx, maxy);
|
||||
data->glTexCoord2f(maxu, maxv);
|
||||
data->glVertex2f(maxx, maxy);
|
||||
data->glEnd();
|
||||
data->glPopMatrix();
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_NO_OP:
|
||||
break;
|
||||
@@ -1544,13 +1488,29 @@ GL_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, floa
|
||||
data->glEnable(textype);
|
||||
#if SDL_HAVE_YUV
|
||||
if (texturedata->yuv) {
|
||||
data->glActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
if (data->GL_ARB_multitexture_supported) {
|
||||
data->glActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
}
|
||||
data->glBindTexture(textype, texturedata->vtexture);
|
||||
|
||||
data->glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
if (data->GL_ARB_multitexture_supported) {
|
||||
data->glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
}
|
||||
data->glBindTexture(textype, texturedata->utexture);
|
||||
|
||||
data->glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
if (data->GL_ARB_multitexture_supported) {
|
||||
data->glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
}
|
||||
if (texturedata->nv12) {
|
||||
if (data->GL_ARB_multitexture_supported) {
|
||||
data->glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
}
|
||||
data->glBindTexture(textype, texturedata->utexture);
|
||||
|
||||
if (data->GL_ARB_multitexture_supported) {
|
||||
data->glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
data->glBindTexture(textype, texturedata->texture);
|
||||
@@ -1558,9 +1518,12 @@ GL_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, floa
|
||||
data->drawstate.texturing = SDL_TRUE;
|
||||
data->drawstate.texture = texture;
|
||||
|
||||
if(texw) *texw = (float)texturedata->texw;
|
||||
if(texh) *texh = (float)texturedata->texh;
|
||||
|
||||
if (texw) {
|
||||
*texw = (float)texturedata->texw;
|
||||
}
|
||||
if (texh) {
|
||||
*texh = (float)texturedata->texh;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1575,16 +1538,35 @@ GL_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture)
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
if (texturedata->yuv) {
|
||||
data->glActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
if (data->GL_ARB_multitexture_supported) {
|
||||
data->glActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
}
|
||||
data->glBindTexture(textype, 0);
|
||||
data->glDisable(textype);
|
||||
|
||||
data->glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
if (data->GL_ARB_multitexture_supported) {
|
||||
data->glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
}
|
||||
data->glBindTexture(textype, 0);
|
||||
data->glDisable(textype);
|
||||
|
||||
data->glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
if (data->GL_ARB_multitexture_supported) {
|
||||
data->glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
}
|
||||
if (texturedata->nv12) {
|
||||
if (data->GL_ARB_multitexture_supported) {
|
||||
data->glActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
}
|
||||
data->glBindTexture(textype, 0);
|
||||
data->glDisable(textype);
|
||||
|
||||
if (data->GL_ARB_multitexture_supported) {
|
||||
data->glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
data->glBindTexture(textype, 0);
|
||||
data->glDisable(textype);
|
||||
|
||||
data->drawstate.texturing = SDL_FALSE;
|
||||
@@ -1593,6 +1575,26 @@ GL_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
GL_SetVSync(SDL_Renderer * renderer, const int vsync)
|
||||
{
|
||||
int retval;
|
||||
if (vsync) {
|
||||
retval = SDL_GL_SetSwapInterval(1);
|
||||
} else {
|
||||
retval = SDL_GL_SetSwapInterval(0);
|
||||
}
|
||||
if (retval != 0) {
|
||||
return retval;
|
||||
}
|
||||
if (SDL_GL_GetSwapInterval() > 0) {
|
||||
renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
|
||||
} else {
|
||||
renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
static SDL_Renderer *
|
||||
GL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
@@ -1651,14 +1653,13 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
renderer->QueueSetDrawColor = GL_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */
|
||||
renderer->QueueDrawPoints = GL_QueueDrawPoints;
|
||||
renderer->QueueDrawLines = GL_QueueDrawLines;
|
||||
renderer->QueueFillRects = GL_QueueFillRects;
|
||||
renderer->QueueCopy = GL_QueueCopy;
|
||||
renderer->QueueCopyEx = GL_QueueCopyEx;
|
||||
renderer->QueueGeometry = GL_QueueGeometry;
|
||||
renderer->RunCommandQueue = GL_RunCommandQueue;
|
||||
renderer->RenderReadPixels = GL_RenderReadPixels;
|
||||
renderer->RenderPresent = GL_RenderPresent;
|
||||
renderer->DestroyTexture = GL_DestroyTexture;
|
||||
renderer->DestroyRenderer = GL_DestroyRenderer;
|
||||
renderer->SetVSync = GL_SetVSync;
|
||||
renderer->GL_BindTexture = GL_BindTexture;
|
||||
renderer->GL_UnbindTexture = GL_UnbindTexture;
|
||||
renderer->info = GL_RenderDriver.info;
|
||||
|
55
externals/SDL/src/render/opengl/SDL_shaders_gl.c
vendored
55
externals/SDL/src/render/opengl/SDL_shaders_gl.c
vendored
@@ -149,7 +149,7 @@ struct GL_ShaderContext
|
||||
"uniform sampler2D tex1; // U/V \n" \
|
||||
"\n" \
|
||||
|
||||
#define NV12_SHADER_BODY \
|
||||
#define NV12_RA_SHADER_BODY \
|
||||
"\n" \
|
||||
"void main()\n" \
|
||||
"{\n" \
|
||||
@@ -174,6 +174,31 @@ struct GL_ShaderContext
|
||||
" gl_FragColor = vec4(rgb, 1.0) * v_color;\n" \
|
||||
"}" \
|
||||
|
||||
#define NV12_RG_SHADER_BODY \
|
||||
"\n" \
|
||||
"void main()\n" \
|
||||
"{\n" \
|
||||
" vec2 tcoord;\n" \
|
||||
" vec3 yuv, rgb;\n" \
|
||||
"\n" \
|
||||
" // Get the Y value \n" \
|
||||
" tcoord = v_texCoord;\n" \
|
||||
" yuv.x = texture2D(tex0, tcoord).r;\n" \
|
||||
"\n" \
|
||||
" // Get the U and V values \n" \
|
||||
" tcoord *= UVCoordScale;\n" \
|
||||
" yuv.yz = texture2D(tex1, tcoord).rg;\n" \
|
||||
"\n" \
|
||||
" // Do the color transform \n" \
|
||||
" yuv += offset;\n" \
|
||||
" rgb.r = dot(yuv, Rcoeff);\n" \
|
||||
" rgb.g = dot(yuv, Gcoeff);\n" \
|
||||
" rgb.b = dot(yuv, Bcoeff);\n" \
|
||||
"\n" \
|
||||
" // That was easy. :) \n" \
|
||||
" gl_FragColor = vec4(rgb, 1.0) * v_color;\n" \
|
||||
"}" \
|
||||
|
||||
#define NV21_SHADER_PROLOGUE \
|
||||
"varying vec4 v_color;\n" \
|
||||
"varying vec2 v_texCoord;\n" \
|
||||
@@ -294,25 +319,43 @@ static const char *shader_source[NUM_SHADERS][2] =
|
||||
/* fragment shader */
|
||||
NV12_SHADER_PROLOGUE
|
||||
JPEG_SHADER_CONSTANTS
|
||||
NV12_SHADER_BODY
|
||||
NV12_RA_SHADER_BODY
|
||||
},
|
||||
/* SHADER_NV12_BT601 */
|
||||
/* SHADER_NV12_RA_BT601 */
|
||||
{
|
||||
/* vertex shader */
|
||||
TEXTURE_VERTEX_SHADER,
|
||||
/* fragment shader */
|
||||
NV12_SHADER_PROLOGUE
|
||||
BT601_SHADER_CONSTANTS
|
||||
NV12_SHADER_BODY
|
||||
NV12_RA_SHADER_BODY
|
||||
},
|
||||
/* SHADER_NV12_BT709 */
|
||||
/* SHADER_NV12_RG_BT601 */
|
||||
{
|
||||
/* vertex shader */
|
||||
TEXTURE_VERTEX_SHADER,
|
||||
/* fragment shader */
|
||||
NV12_SHADER_PROLOGUE
|
||||
BT601_SHADER_CONSTANTS
|
||||
NV12_RG_SHADER_BODY
|
||||
},
|
||||
/* SHADER_NV12_RA_BT709 */
|
||||
{
|
||||
/* vertex shader */
|
||||
TEXTURE_VERTEX_SHADER,
|
||||
/* fragment shader */
|
||||
NV12_SHADER_PROLOGUE
|
||||
BT709_SHADER_CONSTANTS
|
||||
NV12_SHADER_BODY
|
||||
NV12_RA_SHADER_BODY
|
||||
},
|
||||
/* SHADER_NV12_RG_BT709 */
|
||||
{
|
||||
/* vertex shader */
|
||||
TEXTURE_VERTEX_SHADER,
|
||||
/* fragment shader */
|
||||
NV12_SHADER_PROLOGUE
|
||||
BT709_SHADER_CONSTANTS
|
||||
NV12_RG_SHADER_BODY
|
||||
},
|
||||
/* SHADER_NV21_JPEG */
|
||||
{
|
||||
|
@@ -36,8 +36,10 @@ typedef enum {
|
||||
SHADER_YUV_BT601,
|
||||
SHADER_YUV_BT709,
|
||||
SHADER_NV12_JPEG,
|
||||
SHADER_NV12_BT601,
|
||||
SHADER_NV12_BT709,
|
||||
SHADER_NV12_RA_BT601,
|
||||
SHADER_NV12_RG_BT601,
|
||||
SHADER_NV12_RA_BT709,
|
||||
SHADER_NV12_RG_BT709,
|
||||
SHADER_NV21_JPEG,
|
||||
SHADER_NV21_BT601,
|
||||
SHADER_NV21_BT709,
|
||||
|
@@ -27,6 +27,7 @@ SDL_PROC_OES(void, glBlendFuncSeparateOES, (GLenum, GLenum, GLenum, GLenum))
|
||||
SDL_PROC(void, glClear, (GLbitfield))
|
||||
SDL_PROC(void, glClearColor, (GLclampf, GLclampf, GLclampf, GLclampf))
|
||||
SDL_PROC(void, glColor4f, (GLfloat, GLfloat, GLfloat, GLfloat))
|
||||
SDL_PROC(void, glColorPointer, (GLint, GLenum, GLsizei, const GLvoid *))
|
||||
SDL_PROC(void, glDeleteTextures, (GLsizei, const GLuint *))
|
||||
SDL_PROC(void, glDisable, (GLenum))
|
||||
SDL_PROC(void, glDisableClientState, (GLenum array))
|
||||
@@ -56,10 +57,6 @@ SDL_PROC(void, glViewport, (GLint, GLint, GLsizei, GLsizei))
|
||||
SDL_PROC_OES(void, glBindFramebufferOES, (GLenum, GLuint))
|
||||
SDL_PROC_OES(void, glFramebufferTexture2DOES, (GLenum, GLenum, GLenum, GLuint, GLint))
|
||||
SDL_PROC_OES(GLenum, glCheckFramebufferStatusOES, (GLenum))
|
||||
SDL_PROC(void, glPushMatrix, (void))
|
||||
SDL_PROC(void, glTranslatef, (GLfloat, GLfloat, GLfloat))
|
||||
SDL_PROC(void, glRotatef, (GLfloat, GLfloat, GLfloat, GLfloat))
|
||||
SDL_PROC(void, glPopMatrix, (void))
|
||||
SDL_PROC_OES(void, glDeleteFramebuffersOES, (GLsizei, const GLuint*))
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
355
externals/SDL/src/render/opengles/SDL_render_gles.c
vendored
355
externals/SDL/src/render/opengles/SDL_render_gles.c
vendored
@@ -564,194 +564,98 @@ static int
|
||||
GLES_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
|
||||
{
|
||||
int i;
|
||||
GLfloat prevx, prevy;
|
||||
const size_t vertlen = (sizeof (GLfloat) * 2) * count;
|
||||
GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, vertlen, 0, &cmd->data.draw.first);
|
||||
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
cmd->data.draw.count = count;
|
||||
|
||||
/* Offset to hit the center of the pixel. */
|
||||
for (i = 0; i < count; i++) {
|
||||
*(verts++) = 0.5f + points[i].x;
|
||||
*(verts++) = 0.5f + points[i].y;
|
||||
/* 0.5f offset to hit the center of the pixel. */
|
||||
prevx = 0.5f + points->x;
|
||||
prevy = 0.5f + points->y;
|
||||
*(verts++) = prevx;
|
||||
*(verts++) = prevy;
|
||||
|
||||
/* bump the end of each line segment out a quarter of a pixel, to provoke
|
||||
the diamond-exit rule. Without this, you won't just drop the last
|
||||
pixel of the last line segment, but you might also drop pixels at the
|
||||
edge of any given line segment along the way too. */
|
||||
for (i = 1; i < count; i++) {
|
||||
const GLfloat xstart = prevx;
|
||||
const GLfloat ystart = prevy;
|
||||
const GLfloat xend = points[i].x + 0.5f; /* 0.5f to hit pixel center. */
|
||||
const GLfloat yend = points[i].y + 0.5f;
|
||||
/* bump a little in the direction we are moving in. */
|
||||
const GLfloat deltax = xend - xstart;
|
||||
const GLfloat deltay = yend - ystart;
|
||||
const GLfloat angle = SDL_atan2f(deltay, deltax);
|
||||
prevx = xend + (SDL_cosf(angle) * 0.25f);
|
||||
prevy = yend + (SDL_sinf(angle) * 0.25f);
|
||||
*(verts++) = prevx;
|
||||
*(verts++) = prevy;
|
||||
}
|
||||
|
||||
/* Make the last line segment one pixel longer, to satisfy the
|
||||
diamond-exit rule. */
|
||||
verts -= 4;
|
||||
{
|
||||
const GLfloat xstart = verts[0];
|
||||
const GLfloat ystart = verts[1];
|
||||
const GLfloat xend = verts[2];
|
||||
const GLfloat yend = verts[3];
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ystart == yend) { /* horizontal line */
|
||||
verts[(xend > xstart) ? 2 : 0] += 1.0f;
|
||||
} else if (xstart == xend) { /* vertical line */
|
||||
verts[(yend > ystart) ? 3 : 1] += 1.0f;
|
||||
} else { /* bump a pixel in the direction we are moving in. */
|
||||
const GLfloat deltax = xend - xstart;
|
||||
const GLfloat deltay = yend - ystart;
|
||||
const GLfloat angle = SDL_atan2f(deltay, deltax);
|
||||
verts[2] += SDL_cosf(angle);
|
||||
verts[3] += SDL_sinf(angle);
|
||||
static int
|
||||
GLES_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)
|
||||
{
|
||||
GLES_TextureData *texturedata = NULL;
|
||||
int i;
|
||||
int count = indices ? num_indices : num_vertices;
|
||||
GLfloat *verts;
|
||||
int sz = 2 + 4 + (texture ? 2 : 0);
|
||||
|
||||
verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * sz * sizeof (GLfloat), 0, &cmd->data.draw.first);
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (texture) {
|
||||
texturedata = (GLES_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 * inv255f;
|
||||
*(verts++) = col_.g * inv255f;
|
||||
*(verts++) = col_.b * inv255f;
|
||||
*(verts++) = col_.a * inv255f;
|
||||
|
||||
if (texture) {
|
||||
float *uv_ = (float *)((char*)uv + j * uv_stride);
|
||||
*(verts++) = uv_[0] * texturedata->texw;
|
||||
*(verts++) = uv_[1] * texturedata->texh;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
GLES_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count)
|
||||
{
|
||||
GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * 8 * sizeof (GLfloat), 0, &cmd->data.draw.first);
|
||||
int i;
|
||||
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd->data.draw.count = count;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
const SDL_FRect *rect = &rects[i];
|
||||
const GLfloat minx = rect->x;
|
||||
const GLfloat maxx = rect->x + rect->w;
|
||||
const GLfloat miny = rect->y;
|
||||
const GLfloat maxy = rect->y + rect->h;
|
||||
*(verts++) = minx;
|
||||
*(verts++) = miny;
|
||||
*(verts++) = maxx;
|
||||
*(verts++) = miny;
|
||||
*(verts++) = minx;
|
||||
*(verts++) = maxy;
|
||||
*(verts++) = maxx;
|
||||
*(verts++) = maxy;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
GLES_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
|
||||
const SDL_Rect * srcrect, const SDL_FRect * dstrect)
|
||||
{
|
||||
GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata;
|
||||
GLfloat minx, miny, maxx, maxy;
|
||||
GLfloat minu, maxu, minv, maxv;
|
||||
GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, 16 * sizeof (GLfloat), 0, &cmd->data.draw.first);
|
||||
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd->data.draw.count = 1;
|
||||
|
||||
minx = dstrect->x;
|
||||
miny = dstrect->y;
|
||||
maxx = dstrect->x + dstrect->w;
|
||||
maxy = dstrect->y + dstrect->h;
|
||||
|
||||
minu = (GLfloat) srcrect->x / texture->w;
|
||||
minu *= texturedata->texw;
|
||||
maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w;
|
||||
maxu *= texturedata->texw;
|
||||
minv = (GLfloat) srcrect->y / texture->h;
|
||||
minv *= texturedata->texh;
|
||||
maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
|
||||
maxv *= texturedata->texh;
|
||||
|
||||
*(verts++) = minx;
|
||||
*(verts++) = miny;
|
||||
*(verts++) = maxx;
|
||||
*(verts++) = miny;
|
||||
*(verts++) = minx;
|
||||
*(verts++) = maxy;
|
||||
*(verts++) = maxx;
|
||||
*(verts++) = maxy;
|
||||
|
||||
*(verts++) = minu;
|
||||
*(verts++) = minv;
|
||||
*(verts++) = maxu;
|
||||
*(verts++) = minv;
|
||||
*(verts++) = minu;
|
||||
*(verts++) = maxv;
|
||||
*(verts++) = maxu;
|
||||
*(verts++) = maxv;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
GLES_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
|
||||
const SDL_Rect * srcquad, const SDL_FRect * dstrect,
|
||||
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
|
||||
{
|
||||
GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata;
|
||||
GLfloat minx, miny, maxx, maxy;
|
||||
GLfloat centerx, centery;
|
||||
GLfloat minu, maxu, minv, maxv;
|
||||
GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, 19 * sizeof (GLfloat), 0, &cmd->data.draw.first);
|
||||
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
centerx = center->x;
|
||||
centery = center->y;
|
||||
|
||||
if (flip & SDL_FLIP_HORIZONTAL) {
|
||||
minx = dstrect->w - centerx;
|
||||
maxx = -centerx;
|
||||
}
|
||||
else {
|
||||
minx = -centerx;
|
||||
maxx = dstrect->w - centerx;
|
||||
}
|
||||
|
||||
if (flip & SDL_FLIP_VERTICAL) {
|
||||
miny = dstrect->h - centery;
|
||||
maxy = -centery;
|
||||
}
|
||||
else {
|
||||
miny = -centery;
|
||||
maxy = dstrect->h - centery;
|
||||
}
|
||||
|
||||
minu = (GLfloat) srcquad->x / texture->w;
|
||||
minu *= texturedata->texw;
|
||||
maxu = (GLfloat) (srcquad->x + srcquad->w) / texture->w;
|
||||
maxu *= texturedata->texw;
|
||||
minv = (GLfloat) srcquad->y / texture->h;
|
||||
minv *= texturedata->texh;
|
||||
maxv = (GLfloat) (srcquad->y + srcquad->h) / texture->h;
|
||||
maxv *= texturedata->texh;
|
||||
|
||||
cmd->data.draw.count = 1;
|
||||
|
||||
*(verts++) = minx;
|
||||
*(verts++) = miny;
|
||||
*(verts++) = maxx;
|
||||
*(verts++) = miny;
|
||||
*(verts++) = minx;
|
||||
*(verts++) = maxy;
|
||||
*(verts++) = maxx;
|
||||
*(verts++) = maxy;
|
||||
|
||||
*(verts++) = minu;
|
||||
*(verts++) = minv;
|
||||
*(verts++) = maxu;
|
||||
*(verts++) = minv;
|
||||
*(verts++) = minu;
|
||||
*(verts++) = maxv;
|
||||
*(verts++) = maxu;
|
||||
*(verts++) = maxv;
|
||||
|
||||
*(verts++) = (GLfloat) dstrect->x + centerx;
|
||||
*(verts++) = (GLfloat) dstrect->y + centery;
|
||||
*(verts++) = (GLfloat) angle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -763,7 +667,7 @@ SetDrawState(GLES_RenderData *data, const SDL_RenderCommand *cmd)
|
||||
const Uint8 g = cmd->data.draw.g;
|
||||
const Uint8 b = cmd->data.draw.b;
|
||||
const Uint8 a = cmd->data.draw.a;
|
||||
const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
|
||||
const Uint32 color = (((Uint32)a << 24) | (r << 16) | (g << 8) | b);
|
||||
|
||||
if (color != data->drawstate.color) {
|
||||
const GLfloat fr = ((GLfloat) r) * inv255f;
|
||||
@@ -865,7 +769,6 @@ static int
|
||||
GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
|
||||
{
|
||||
GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
|
||||
size_t i;
|
||||
|
||||
if (GLES_ActivateRenderer(renderer) < 0) {
|
||||
return -1;
|
||||
@@ -874,7 +777,15 @@ GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vert
|
||||
data->drawstate.target = renderer->target;
|
||||
|
||||
if (!renderer->target) {
|
||||
SDL_GL_GetDrawableSize(renderer->window, &data->drawstate.drawablew, &data->drawstate.drawableh);
|
||||
int w, h;
|
||||
SDL_GL_GetDrawableSize(renderer->window, &w, &h);
|
||||
if ((w != data->drawstate.drawablew) || (h != data->drawstate.drawableh)) {
|
||||
data->drawstate.viewport_dirty = SDL_TRUE; // if the window dimensions changed, invalidate the current viewport, etc.
|
||||
data->drawstate.cliprect_dirty = SDL_TRUE;
|
||||
data->drawstate.drawablew = w;
|
||||
data->drawstate.drawableh = h;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
while (cmd) {
|
||||
@@ -910,7 +821,7 @@ GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vert
|
||||
const Uint8 g = cmd->data.color.g;
|
||||
const Uint8 b = cmd->data.color.b;
|
||||
const Uint8 a = cmd->data.color.a;
|
||||
const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
|
||||
const Uint32 color = (((Uint32)a << 24) | (r << 16) | (g << 8) | b);
|
||||
if (color != data->drawstate.clear_color) {
|
||||
const GLfloat fr = ((GLfloat) r) * inv255f;
|
||||
const GLfloat fg = ((GLfloat) g) * inv255f;
|
||||
@@ -949,42 +860,38 @@ GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vert
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_FILL_RECTS: {
|
||||
case SDL_RENDERCMD_FILL_RECTS: /* unused */
|
||||
break;
|
||||
|
||||
case SDL_RENDERCMD_COPY: /* unused */
|
||||
break;
|
||||
|
||||
case SDL_RENDERCMD_COPY_EX: /* unused */
|
||||
break;
|
||||
|
||||
case SDL_RENDERCMD_GEOMETRY: {
|
||||
const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
|
||||
SDL_Texture *texture = cmd->data.draw.texture;
|
||||
const size_t count = cmd->data.draw.count;
|
||||
const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
|
||||
GLsizei offset = 0;
|
||||
SetDrawState(data, cmd);
|
||||
data->glVertexPointer(2, GL_FLOAT, 0, verts);
|
||||
for (i = 0; i < count; ++i, offset += 4) {
|
||||
data->glDrawArrays(GL_TRIANGLE_STRIP, offset, 4);
|
||||
int stride = (2 + 4 + (texture ? 2 : 0)) * sizeof (float);
|
||||
|
||||
if (texture) {
|
||||
SetCopyState(data, cmd);
|
||||
} else {
|
||||
SetDrawState(data, cmd);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_COPY: {
|
||||
const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
|
||||
SetCopyState(data, cmd);
|
||||
data->glVertexPointer(2, GL_FLOAT, 0, verts);
|
||||
data->glTexCoordPointer(2, GL_FLOAT, 0, verts + 8);
|
||||
data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
break;
|
||||
}
|
||||
data->glEnableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
case SDL_RENDERCMD_COPY_EX: {
|
||||
const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
|
||||
const GLfloat translatex = verts[16];
|
||||
const GLfloat translatey = verts[17];
|
||||
const GLfloat angle = verts[18];
|
||||
SetCopyState(data, cmd);
|
||||
data->glVertexPointer(2, GL_FLOAT, 0, verts);
|
||||
data->glTexCoordPointer(2, GL_FLOAT, 0, verts + 8);
|
||||
data->glVertexPointer(2, GL_FLOAT, stride, verts);
|
||||
data->glColorPointer(4, GL_FLOAT, stride, verts + 2);
|
||||
if (texture) {
|
||||
data->glTexCoordPointer(2, GL_FLOAT, stride, verts + 2 + 4);
|
||||
}
|
||||
|
||||
/* Translate to flip, rotate, translate to position */
|
||||
data->glPushMatrix();
|
||||
data->glTranslatef(translatex, translatey, 0.0f);
|
||||
data->glRotatef(angle, 0.0, 0.0, 1.0);
|
||||
data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
data->glPopMatrix();
|
||||
data->glDrawArrays(GL_TRIANGLES, 0, (GLsizei) count);
|
||||
|
||||
data->glDisableClientState(GL_COLOR_ARRAY);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1141,6 +1048,27 @@ static int GLES_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
GLES_SetVSync(SDL_Renderer * renderer, const int vsync)
|
||||
{
|
||||
int retval;
|
||||
if (vsync) {
|
||||
retval = SDL_GL_SetSwapInterval(1);
|
||||
} else {
|
||||
retval = SDL_GL_SetSwapInterval(0);
|
||||
}
|
||||
if (retval != 0) {
|
||||
return retval;
|
||||
}
|
||||
if (SDL_GL_GetSwapInterval() > 0) {
|
||||
renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
|
||||
} else {
|
||||
renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
static SDL_Renderer *
|
||||
GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
{
|
||||
@@ -1195,14 +1123,13 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
renderer->QueueSetDrawColor = GLES_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */
|
||||
renderer->QueueDrawPoints = GLES_QueueDrawPoints;
|
||||
renderer->QueueDrawLines = GLES_QueueDrawLines;
|
||||
renderer->QueueFillRects = GLES_QueueFillRects;
|
||||
renderer->QueueCopy = GLES_QueueCopy;
|
||||
renderer->QueueCopyEx = GLES_QueueCopyEx;
|
||||
renderer->QueueGeometry = GLES_QueueGeometry;
|
||||
renderer->RunCommandQueue = GLES_RunCommandQueue;
|
||||
renderer->RenderReadPixels = GLES_RenderReadPixels;
|
||||
renderer->RenderPresent = GLES_RenderPresent;
|
||||
renderer->DestroyTexture = GLES_DestroyTexture;
|
||||
renderer->DestroyRenderer = GLES_DestroyRenderer;
|
||||
renderer->SetVSync = GLES_SetVSync;
|
||||
renderer->GL_BindTexture = GLES_BindTexture;
|
||||
renderer->GL_UnbindTexture = GLES_UnbindTexture;
|
||||
renderer->info = GLES_RenderDriver.info;
|
||||
|
@@ -74,7 +74,6 @@ typedef struct GLES2_ProgramCacheEntry
|
||||
GLuint vertex_shader;
|
||||
GLuint fragment_shader;
|
||||
GLuint uniform_locations[16];
|
||||
Uint32 color;
|
||||
GLfloat projection[4][4];
|
||||
struct GLES2_ProgramCacheEntry *prev;
|
||||
struct GLES2_ProgramCacheEntry *next;
|
||||
@@ -90,16 +89,14 @@ typedef struct GLES2_ProgramCache
|
||||
typedef enum
|
||||
{
|
||||
GLES2_ATTRIBUTE_POSITION = 0,
|
||||
GLES2_ATTRIBUTE_TEXCOORD = 1,
|
||||
GLES2_ATTRIBUTE_ANGLE = 2,
|
||||
GLES2_ATTRIBUTE_CENTER = 3,
|
||||
GLES2_ATTRIBUTE_COLOR = 1,
|
||||
GLES2_ATTRIBUTE_TEXCOORD = 2,
|
||||
} GLES2_Attribute;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GLES2_UNIFORM_PROJECTION,
|
||||
GLES2_UNIFORM_TEXTURE,
|
||||
GLES2_UNIFORM_COLOR,
|
||||
GLES2_UNIFORM_TEXTURE_U,
|
||||
GLES2_UNIFORM_TEXTURE_V
|
||||
} GLES2_Uniform;
|
||||
@@ -130,8 +127,6 @@ typedef struct
|
||||
SDL_bool cliprect_dirty;
|
||||
SDL_Rect cliprect;
|
||||
SDL_bool texturing;
|
||||
SDL_bool is_copy_ex;
|
||||
Uint32 color;
|
||||
Uint32 clear_color;
|
||||
int drawablew;
|
||||
int drawableh;
|
||||
@@ -422,9 +417,8 @@ GLES2_CacheProgram(GLES2_RenderData *data, GLuint vertex, GLuint fragment)
|
||||
data->glAttachShader(entry->id, vertex);
|
||||
data->glAttachShader(entry->id, fragment);
|
||||
data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_POSITION, "a_position");
|
||||
data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_COLOR, "a_color");
|
||||
data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_TEXCOORD, "a_texCoord");
|
||||
data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_ANGLE, "a_angle");
|
||||
data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_CENTER, "a_center");
|
||||
data->glLinkProgram(entry->id);
|
||||
data->glGetProgramiv(entry->id, GL_LINK_STATUS, &linkSuccessful);
|
||||
if (!linkSuccessful) {
|
||||
@@ -443,10 +437,6 @@ GLES2_CacheProgram(GLES2_RenderData *data, GLuint vertex, GLuint fragment)
|
||||
data->glGetUniformLocation(entry->id, "u_texture_u");
|
||||
entry->uniform_locations[GLES2_UNIFORM_TEXTURE] =
|
||||
data->glGetUniformLocation(entry->id, "u_texture");
|
||||
entry->uniform_locations[GLES2_UNIFORM_COLOR] =
|
||||
data->glGetUniformLocation(entry->id, "u_color");
|
||||
|
||||
entry->color = 0;
|
||||
|
||||
data->glUseProgram(entry->id);
|
||||
if (entry->uniform_locations[GLES2_UNIFORM_TEXTURE_V] != -1) {
|
||||
@@ -461,9 +451,6 @@ GLES2_CacheProgram(GLES2_RenderData *data, GLuint vertex, GLuint fragment)
|
||||
if (entry->uniform_locations[GLES2_UNIFORM_PROJECTION] != -1) {
|
||||
data->glUniformMatrix4fv(entry->uniform_locations[GLES2_UNIFORM_PROJECTION], 1, GL_FALSE, (GLfloat *)entry->projection);
|
||||
}
|
||||
if (entry->uniform_locations[GLES2_UNIFORM_COLOR] != -1) {
|
||||
data->glUniform4f(entry->uniform_locations[GLES2_UNIFORM_COLOR], 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
/* Cache the linked program */
|
||||
if (data->program_cache.head) {
|
||||
@@ -582,10 +569,18 @@ GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int
|
||||
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG;
|
||||
break;
|
||||
case SDL_YUV_CONVERSION_BT601:
|
||||
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT601;
|
||||
if (SDL_GetHintBoolean("SDL_RENDER_OPENGL_NV12_RG_SHADER", SDL_FALSE)) {
|
||||
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT601;
|
||||
} else {
|
||||
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT601;
|
||||
}
|
||||
break;
|
||||
case SDL_YUV_CONVERSION_BT709:
|
||||
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT709;
|
||||
if (SDL_GetHintBoolean("SDL_RENDER_OPENGL_NV12_RG_SHADER", SDL_FALSE)) {
|
||||
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT709;
|
||||
} else {
|
||||
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT709;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
SDL_SetError("Unsupported YUV conversion mode: %d\n", SDL_GetYUVConversionModeForResolution(w, h));
|
||||
@@ -667,17 +662,27 @@ GLES2_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd)
|
||||
static int
|
||||
GLES2_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
|
||||
{
|
||||
GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * 2 * sizeof (GLfloat), 0, &cmd->data.draw.first);
|
||||
const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 || renderer->target->format == SDL_PIXELFORMAT_RGB888));
|
||||
int color;
|
||||
const size_t vertlen = (2 * sizeof (float) + sizeof (int)) * count;
|
||||
GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, vertlen, 0, &cmd->data.draw.first);
|
||||
int i;
|
||||
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (colorswap == 0) {
|
||||
color = (cmd->data.draw.r << 0) | (cmd->data.draw.g << 8) | (cmd->data.draw.b << 16) | ((Uint32)cmd->data.draw.a << 24);
|
||||
} else {
|
||||
color = (cmd->data.draw.r << 16) | (cmd->data.draw.g << 8) | (cmd->data.draw.b << 0) | ((Uint32)cmd->data.draw.a << 24);
|
||||
}
|
||||
|
||||
cmd->data.draw.count = count;
|
||||
for (i = 0; i < count; i++) {
|
||||
*(verts++) = 0.5f + points[i].x;
|
||||
*(verts++) = 0.5f + points[i].y;
|
||||
*((int *)verts++) = color;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -686,211 +691,122 @@ GLES2_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL
|
||||
static int
|
||||
GLES2_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
|
||||
{
|
||||
const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 || renderer->target->format == SDL_PIXELFORMAT_RGB888));
|
||||
int color;
|
||||
int i;
|
||||
const size_t vertlen = (sizeof (GLfloat) * 2) * count;
|
||||
GLfloat prevx, prevy;
|
||||
const size_t vertlen = ((2 * sizeof (float)) + sizeof (int)) * count;
|
||||
GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, vertlen, 0, &cmd->data.draw.first);
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
cmd->data.draw.count = count;
|
||||
|
||||
/* Offset to hit the center of the pixel. */
|
||||
for (i = 0; i < count; i++) {
|
||||
*(verts++) = 0.5f + points[i].x;
|
||||
*(verts++) = 0.5f + points[i].y;
|
||||
if (colorswap == 0) {
|
||||
color = (cmd->data.draw.r << 0) | (cmd->data.draw.g << 8) | (cmd->data.draw.b << 16) | ((Uint32)cmd->data.draw.a << 24);
|
||||
} else {
|
||||
color = (cmd->data.draw.r << 16) | (cmd->data.draw.g << 8) | (cmd->data.draw.b << 0) | ((Uint32)cmd->data.draw.a << 24);
|
||||
}
|
||||
|
||||
/* Make the last line segment one pixel longer, to satisfy the
|
||||
diamond-exit rule. */
|
||||
verts -= 4;
|
||||
{
|
||||
const GLfloat xstart = verts[0];
|
||||
const GLfloat ystart = verts[1];
|
||||
const GLfloat xend = verts[2];
|
||||
const GLfloat yend = verts[3];
|
||||
cmd->data.draw.count = count;
|
||||
|
||||
if (ystart == yend) { /* horizontal line */
|
||||
verts[(xend > xstart) ? 2 : 0] += 1.0f;
|
||||
} else if (xstart == xend) { /* vertical line */
|
||||
verts[(yend > ystart) ? 3 : 1] += 1.0f;
|
||||
} else { /* bump a pixel in the direction we are moving in. */
|
||||
const GLfloat deltax = xend - xstart;
|
||||
const GLfloat deltay = yend - ystart;
|
||||
const GLfloat angle = SDL_atan2f(deltay, deltax);
|
||||
verts[2] += SDL_cosf(angle);
|
||||
verts[3] += SDL_sinf(angle);
|
||||
/* 0.5f offset to hit the center of the pixel. */
|
||||
prevx = 0.5f + points->x;
|
||||
prevy = 0.5f + points->y;
|
||||
*(verts++) = prevx;
|
||||
*(verts++) = prevy;
|
||||
*((int *)verts++) = color;
|
||||
|
||||
/* bump the end of each line segment out a quarter of a pixel, to provoke
|
||||
the diamond-exit rule. Without this, you won't just drop the last
|
||||
pixel of the last line segment, but you might also drop pixels at the
|
||||
edge of any given line segment along the way too. */
|
||||
for (i = 1; i < count; i++) {
|
||||
const GLfloat xstart = prevx;
|
||||
const GLfloat ystart = prevy;
|
||||
const GLfloat xend = points[i].x + 0.5f; /* 0.5f to hit pixel center. */
|
||||
const GLfloat yend = points[i].y + 0.5f;
|
||||
/* bump a little in the direction we are moving in. */
|
||||
const GLfloat deltax = xend - xstart;
|
||||
const GLfloat deltay = yend - ystart;
|
||||
const GLfloat angle = SDL_atan2f(deltay, deltax);
|
||||
prevx = xend + (SDL_cosf(angle) * 0.25f);
|
||||
prevy = yend + (SDL_sinf(angle) * 0.25f);
|
||||
*(verts++) = prevx;
|
||||
*(verts++) = prevy;
|
||||
*((int *)verts++) = color;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
GLES2_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)
|
||||
{
|
||||
int i;
|
||||
const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 || renderer->target->format == SDL_PIXELFORMAT_RGB888));
|
||||
int count = indices ? num_indices : num_vertices;
|
||||
const size_t vertlen = (2 * sizeof (float) + sizeof (int) + (texture ? 2 : 0) * sizeof (float)) * count;
|
||||
GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, vertlen, 0, &cmd->data.draw.first);
|
||||
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd->data.draw.count = count;
|
||||
size_indices = indices ? size_indices : 0;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
int j;
|
||||
float *xy_;
|
||||
int 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_ = *(int *)((char*)color + j * color_stride);
|
||||
|
||||
*(verts++) = xy_[0] * scale_x;
|
||||
*(verts++) = xy_[1] * scale_y;
|
||||
|
||||
if (colorswap == 0) {
|
||||
*((int *)verts++) = col_;
|
||||
} else {
|
||||
Uint8 r, g, b, a;
|
||||
r = (col_ >> 0) & 0xff;
|
||||
g = (col_ >> 8) & 0xff;
|
||||
b = (col_ >> 16) & 0xff;
|
||||
a = (col_ >> 24) & 0xff;
|
||||
col_ = (r << 16) | (g << 8) | (b << 0) | ((Uint32)a << 24);
|
||||
*((int *)verts++) = col_;
|
||||
}
|
||||
|
||||
if (texture) {
|
||||
float *uv_ = (float *)((char*)uv + j * uv_stride);
|
||||
*(verts++) = uv_[0];
|
||||
*(verts++) = uv_[1];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
GLES2_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count)
|
||||
{
|
||||
GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * 8 * sizeof (GLfloat), 0, &cmd->data.draw.first);
|
||||
int i;
|
||||
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd->data.draw.count = count;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
const SDL_FRect *rect = &rects[i];
|
||||
const GLfloat minx = rect->x;
|
||||
const GLfloat maxx = rect->x + rect->w;
|
||||
const GLfloat miny = rect->y;
|
||||
const GLfloat maxy = rect->y + rect->h;
|
||||
*(verts++) = minx;
|
||||
*(verts++) = miny;
|
||||
*(verts++) = maxx;
|
||||
*(verts++) = miny;
|
||||
*(verts++) = minx;
|
||||
*(verts++) = maxy;
|
||||
*(verts++) = maxx;
|
||||
*(verts++) = maxy;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
GLES2_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
|
||||
const SDL_Rect * srcrect, const SDL_FRect * dstrect)
|
||||
{
|
||||
GLfloat minx, miny, maxx, maxy;
|
||||
GLfloat minu, maxu, minv, maxv;
|
||||
GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, 16 * sizeof (GLfloat), 0, &cmd->data.draw.first);
|
||||
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd->data.draw.count = 1;
|
||||
|
||||
minx = dstrect->x;
|
||||
miny = dstrect->y;
|
||||
maxx = dstrect->x + dstrect->w;
|
||||
maxy = dstrect->y + dstrect->h;
|
||||
|
||||
minu = (GLfloat) srcrect->x / texture->w;
|
||||
maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w;
|
||||
minv = (GLfloat) srcrect->y / texture->h;
|
||||
maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
|
||||
|
||||
*(verts++) = minx;
|
||||
*(verts++) = miny;
|
||||
*(verts++) = maxx;
|
||||
*(verts++) = miny;
|
||||
*(verts++) = minx;
|
||||
*(verts++) = maxy;
|
||||
*(verts++) = maxx;
|
||||
*(verts++) = maxy;
|
||||
|
||||
*(verts++) = minu;
|
||||
*(verts++) = minv;
|
||||
*(verts++) = maxu;
|
||||
*(verts++) = minv;
|
||||
*(verts++) = minu;
|
||||
*(verts++) = maxv;
|
||||
*(verts++) = maxu;
|
||||
*(verts++) = maxv;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
GLES2_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
|
||||
const SDL_Rect * srcquad, const SDL_FRect * dstrect,
|
||||
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
|
||||
{
|
||||
/* render expects cos value - 1 (see GLES2_Vertex_Default) */
|
||||
const float radian_angle = (float)(M_PI * (360.0 - angle) / 180.0);
|
||||
const GLfloat s = (GLfloat) SDL_sin(radian_angle);
|
||||
const GLfloat c = (GLfloat) SDL_cos(radian_angle) - 1.0f;
|
||||
const GLfloat centerx = center->x + dstrect->x;
|
||||
const GLfloat centery = center->y + dstrect->y;
|
||||
GLfloat minx, miny, maxx, maxy;
|
||||
GLfloat minu, maxu, minv, maxv;
|
||||
GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, 32 * sizeof (GLfloat), 0, &cmd->data.draw.first);
|
||||
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flip & SDL_FLIP_HORIZONTAL) {
|
||||
minx = dstrect->x + dstrect->w;
|
||||
maxx = dstrect->x;
|
||||
} else {
|
||||
minx = dstrect->x;
|
||||
maxx = dstrect->x + dstrect->w;
|
||||
}
|
||||
|
||||
if (flip & SDL_FLIP_VERTICAL) {
|
||||
miny = dstrect->y + dstrect->h;
|
||||
maxy = dstrect->y;
|
||||
} else {
|
||||
miny = dstrect->y;
|
||||
maxy = dstrect->y + dstrect->h;
|
||||
}
|
||||
|
||||
minu = ((GLfloat) srcquad->x) / ((GLfloat) texture->w);
|
||||
maxu = ((GLfloat) (srcquad->x + srcquad->w)) / ((GLfloat) texture->w);
|
||||
minv = ((GLfloat) srcquad->y) / ((GLfloat) texture->h);
|
||||
maxv = ((GLfloat) (srcquad->y + srcquad->h)) / ((GLfloat) texture->h);
|
||||
|
||||
|
||||
cmd->data.draw.count = 1;
|
||||
|
||||
*(verts++) = minx;
|
||||
*(verts++) = miny;
|
||||
*(verts++) = maxx;
|
||||
*(verts++) = miny;
|
||||
*(verts++) = minx;
|
||||
*(verts++) = maxy;
|
||||
*(verts++) = maxx;
|
||||
*(verts++) = maxy;
|
||||
|
||||
*(verts++) = minu;
|
||||
*(verts++) = minv;
|
||||
*(verts++) = maxu;
|
||||
*(verts++) = minv;
|
||||
*(verts++) = minu;
|
||||
*(verts++) = maxv;
|
||||
*(verts++) = maxu;
|
||||
*(verts++) = maxv;
|
||||
|
||||
*(verts++) = s;
|
||||
*(verts++) = c;
|
||||
*(verts++) = s;
|
||||
*(verts++) = c;
|
||||
*(verts++) = s;
|
||||
*(verts++) = c;
|
||||
*(verts++) = s;
|
||||
*(verts++) = c;
|
||||
|
||||
*(verts++) = centerx;
|
||||
*(verts++) = centery;
|
||||
*(verts++) = centerx;
|
||||
*(verts++) = centery;
|
||||
*(verts++) = centerx;
|
||||
*(verts++) = centery;
|
||||
*(verts++) = centerx;
|
||||
*(verts++) = centery;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_ImageSource imgsrc)
|
||||
{
|
||||
const SDL_bool was_copy_ex = data->drawstate.is_copy_ex;
|
||||
const SDL_bool is_copy_ex = (cmd->command == SDL_RENDERCMD_COPY_EX);
|
||||
SDL_Texture *texture = cmd->data.draw.texture;
|
||||
const SDL_BlendMode blend = cmd->data.draw.blend;
|
||||
GLES2_ProgramCacheEntry *program;
|
||||
int stride = sizeof (GLfloat) * 2 /* position */ + sizeof (int) /* color */;
|
||||
|
||||
SDL_assert((texture != NULL) == (imgsrc != GLES2_IMAGESOURCE_SOLID));
|
||||
|
||||
@@ -961,7 +877,11 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I
|
||||
}
|
||||
|
||||
if (texture) {
|
||||
data->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (uintptr_t) (cmd->data.draw.first + (sizeof (GLfloat) * 8)));
|
||||
stride += sizeof (GLfloat) * 2; /* tex coord */
|
||||
}
|
||||
|
||||
if (texture) {
|
||||
data->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, stride, (const GLvoid *) (uintptr_t) (cmd->data.draw.first + sizeof (GLfloat) * (2 + 1)));
|
||||
}
|
||||
|
||||
if (GLES2_SelectProgram(data, imgsrc, texture ? texture->w : 0, texture ? texture->h : 0) < 0) {
|
||||
@@ -977,17 +897,6 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I
|
||||
}
|
||||
}
|
||||
|
||||
if (program->uniform_locations[GLES2_UNIFORM_COLOR] != -1) {
|
||||
if (data->drawstate.color != program->color) {
|
||||
const Uint8 r = (data->drawstate.color >> 16) & 0xFF;
|
||||
const Uint8 g = (data->drawstate.color >> 8) & 0xFF;
|
||||
const Uint8 b = (data->drawstate.color >> 0) & 0xFF;
|
||||
const Uint8 a = (data->drawstate.color >> 24) & 0xFF;
|
||||
data->glUniform4f(program->uniform_locations[GLES2_UNIFORM_COLOR], r * inv255f, g * inv255f, b * inv255f, a * inv255f);
|
||||
program->color = data->drawstate.color;
|
||||
}
|
||||
}
|
||||
|
||||
if (blend != data->drawstate.blend) {
|
||||
if (blend == SDL_BLENDMODE_NONE) {
|
||||
data->glDisable(GL_BLEND);
|
||||
@@ -1004,23 +913,8 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I
|
||||
}
|
||||
|
||||
/* all drawing commands use this */
|
||||
data->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (uintptr_t) cmd->data.draw.first);
|
||||
|
||||
if (is_copy_ex != was_copy_ex) {
|
||||
if (is_copy_ex) {
|
||||
data->glEnableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_ANGLE);
|
||||
data->glEnableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_CENTER);
|
||||
} else {
|
||||
data->glDisableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_ANGLE);
|
||||
data->glDisableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_CENTER);
|
||||
}
|
||||
data->drawstate.is_copy_ex = is_copy_ex;
|
||||
}
|
||||
|
||||
if (is_copy_ex) {
|
||||
data->glVertexAttribPointer(GLES2_ATTRIBUTE_ANGLE, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (uintptr_t) (cmd->data.draw.first + (sizeof (GLfloat) * 16)));
|
||||
data->glVertexAttribPointer(GLES2_ATTRIBUTE_CENTER, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (uintptr_t) (cmd->data.draw.first + (sizeof (GLfloat) * 24)));
|
||||
}
|
||||
data->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, stride, (const GLvoid *) (uintptr_t) cmd->data.draw.first);
|
||||
data->glVertexAttribPointer(GLES2_ATTRIBUTE_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE /* Normalized */, stride, (const GLvoid *) (uintptr_t) (cmd->data.draw.first + sizeof (GLfloat) * 2));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1146,7 +1040,6 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
|
||||
const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 || renderer->target->format == SDL_PIXELFORMAT_RGB888));
|
||||
const int vboidx = data->current_vertex_buffer;
|
||||
const GLuint vbo = data->vertex_buffers[vboidx];
|
||||
size_t i;
|
||||
|
||||
if (GLES2_ActivateRenderer(renderer) < 0) {
|
||||
return -1;
|
||||
@@ -1154,7 +1047,14 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
|
||||
|
||||
data->drawstate.target = renderer->target;
|
||||
if (!data->drawstate.target) {
|
||||
SDL_GL_GetDrawableSize(renderer->window, &data->drawstate.drawablew, &data->drawstate.drawableh);
|
||||
int w, h;
|
||||
SDL_GL_GetDrawableSize(renderer->window, &w, &h);
|
||||
if ((w != data->drawstate.drawablew) || (h != data->drawstate.drawableh)) {
|
||||
data->drawstate.viewport_dirty = SDL_TRUE; // if the window dimensions changed, invalidate the current viewport, etc.
|
||||
data->drawstate.cliprect_dirty = SDL_TRUE;
|
||||
data->drawstate.drawablew = w;
|
||||
data->drawstate.drawableh = h;
|
||||
}
|
||||
}
|
||||
|
||||
/* upload the new VBO data for this set of commands. */
|
||||
@@ -1175,11 +1075,6 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
|
||||
while (cmd) {
|
||||
switch (cmd->command) {
|
||||
case SDL_RENDERCMD_SETDRAWCOLOR: {
|
||||
const Uint8 r = colorswap ? cmd->data.color.b : cmd->data.color.r;
|
||||
const Uint8 g = cmd->data.color.g;
|
||||
const Uint8 b = colorswap ? cmd->data.color.r : cmd->data.color.b;
|
||||
const Uint8 a = cmd->data.color.a;
|
||||
data->drawstate.color = ((a << 24) | (r << 16) | (g << 8) | b);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1211,7 +1106,7 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
|
||||
const Uint8 g = cmd->data.color.g;
|
||||
const Uint8 b = colorswap ? cmd->data.color.r : cmd->data.color.b;
|
||||
const Uint8 a = cmd->data.color.a;
|
||||
const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
|
||||
const Uint32 color = (((Uint32)a << 24) | (r << 16) | (g << 8) | b);
|
||||
if (color != data->drawstate.clear_color) {
|
||||
const GLfloat fr = ((GLfloat) r) * inv255f;
|
||||
const GLfloat fg = ((GLfloat) g) * inv255f;
|
||||
@@ -1230,38 +1125,88 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_DRAW_POINTS: {
|
||||
if (SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID) == 0) {
|
||||
data->glDrawArrays(GL_POINTS, 0, (GLsizei) cmd->data.draw.count);
|
||||
}
|
||||
case SDL_RENDERCMD_FILL_RECTS: /* unused */
|
||||
break;
|
||||
|
||||
case SDL_RENDERCMD_COPY: /* unused */
|
||||
break;
|
||||
|
||||
case SDL_RENDERCMD_COPY_EX: /* unused */
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_DRAW_LINES: {
|
||||
const size_t count = cmd->data.draw.count;
|
||||
SDL_assert(count >= 2);
|
||||
if (SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID) == 0) {
|
||||
data->glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) count);
|
||||
}
|
||||
break;
|
||||
}
|
||||
size_t count = cmd->data.draw.count;
|
||||
if (count > 2) {
|
||||
/* joined lines cannot be grouped */
|
||||
data->glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)count);
|
||||
} else {
|
||||
/* let's group non joined lines */
|
||||
SDL_RenderCommand *finalcmd = cmd;
|
||||
SDL_RenderCommand *nextcmd = cmd->next;
|
||||
SDL_BlendMode thisblend = cmd->data.draw.blend;
|
||||
|
||||
case SDL_RENDERCMD_FILL_RECTS: {
|
||||
const size_t count = cmd->data.draw.count;
|
||||
size_t offset = 0;
|
||||
if (SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID) == 0) {
|
||||
for (i = 0; i < count; ++i, offset += 4) {
|
||||
data->glDrawArrays(GL_TRIANGLE_STRIP, (GLsizei) offset, 4);
|
||||
while (nextcmd != NULL) {
|
||||
const SDL_RenderCommandType nextcmdtype = nextcmd->command;
|
||||
if (nextcmdtype != SDL_RENDERCMD_DRAW_LINES) {
|
||||
break; /* can't go any further on this draw call, different render command up next. */
|
||||
} else if (nextcmd->data.draw.count != 2) {
|
||||
break; /* can't go any further on this draw call, those are joined lines */
|
||||
} else if (nextcmd->data.draw.blend != thisblend) {
|
||||
break; /* can't go any further on this draw call, different blendmode copy up next. */
|
||||
} else {
|
||||
finalcmd = nextcmd; /* we can combine copy operations here. Mark this one as the furthest okay command. */
|
||||
count += cmd->data.draw.count;
|
||||
}
|
||||
nextcmd = nextcmd->next;
|
||||
}
|
||||
|
||||
data->glDrawArrays(GL_LINES, 0, (GLsizei)count);
|
||||
cmd = finalcmd; /* skip any copy commands we just combined in here. */
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_COPY:
|
||||
case SDL_RENDERCMD_COPY_EX: {
|
||||
if (SetCopyState(renderer, cmd) == 0) {
|
||||
data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
case SDL_RENDERCMD_DRAW_POINTS:
|
||||
case SDL_RENDERCMD_GEOMETRY: {
|
||||
/* as long as we have the same copy command in a row, with the
|
||||
same texture, we can combine them all into a single draw call. */
|
||||
SDL_Texture *thistexture = cmd->data.draw.texture;
|
||||
SDL_BlendMode thisblend = cmd->data.draw.blend;
|
||||
const SDL_RenderCommandType thiscmdtype = cmd->command;
|
||||
SDL_RenderCommand *finalcmd = cmd;
|
||||
SDL_RenderCommand *nextcmd = cmd->next;
|
||||
size_t count = cmd->data.draw.count;
|
||||
int ret;
|
||||
while (nextcmd != NULL) {
|
||||
const SDL_RenderCommandType nextcmdtype = nextcmd->command;
|
||||
if (nextcmdtype != thiscmdtype) {
|
||||
break; /* can't go any further on this draw call, different render command up next. */
|
||||
} else if (nextcmd->data.draw.texture != thistexture || nextcmd->data.draw.blend != thisblend) {
|
||||
break; /* can't go any further on this draw call, different texture/blendmode copy up next. */
|
||||
} else {
|
||||
finalcmd = nextcmd; /* we can combine copy operations here. Mark this one as the furthest okay command. */
|
||||
count += cmd->data.draw.count;
|
||||
}
|
||||
nextcmd = nextcmd->next;
|
||||
}
|
||||
|
||||
if (thistexture) {
|
||||
ret = SetCopyState(renderer, cmd);
|
||||
} else {
|
||||
ret = SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
int op = GL_TRIANGLES; /* SDL_RENDERCMD_GEOMETRY */
|
||||
if (thiscmdtype == SDL_RENDERCMD_DRAW_POINTS) {
|
||||
op = GL_POINTS;
|
||||
}
|
||||
data->glDrawArrays(op, 0, (GLsizei) count);
|
||||
}
|
||||
|
||||
cmd = finalcmd; /* skip any copy commands we just combined in here. */
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1882,6 +1827,26 @@ GLES2_RenderPresent(SDL_Renderer *renderer)
|
||||
SDL_GL_SwapWindow(renderer->window);
|
||||
}
|
||||
|
||||
static int
|
||||
GLES2_SetVSync(SDL_Renderer * renderer, const int vsync)
|
||||
{
|
||||
int retval;
|
||||
if (vsync) {
|
||||
retval = SDL_GL_SetSwapInterval(1);
|
||||
} else {
|
||||
retval = SDL_GL_SetSwapInterval(0);
|
||||
}
|
||||
if (retval != 0) {
|
||||
return retval;
|
||||
}
|
||||
if (SDL_GL_GetSwapInterval() > 0) {
|
||||
renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
|
||||
} else {
|
||||
renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************************************
|
||||
* Bind/unbinding of textures
|
||||
@@ -2056,14 +2021,13 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
|
||||
renderer->QueueSetDrawColor = GLES2_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */
|
||||
renderer->QueueDrawPoints = GLES2_QueueDrawPoints;
|
||||
renderer->QueueDrawLines = GLES2_QueueDrawLines;
|
||||
renderer->QueueFillRects = GLES2_QueueFillRects;
|
||||
renderer->QueueCopy = GLES2_QueueCopy;
|
||||
renderer->QueueCopyEx = GLES2_QueueCopyEx;
|
||||
renderer->QueueGeometry = GLES2_QueueGeometry;
|
||||
renderer->RunCommandQueue = GLES2_RunCommandQueue;
|
||||
renderer->RenderReadPixels = GLES2_RenderReadPixels;
|
||||
renderer->RenderPresent = GLES2_RenderPresent;
|
||||
renderer->DestroyTexture = GLES2_DestroyTexture;
|
||||
renderer->DestroyRenderer = GLES2_DestroyRenderer;
|
||||
renderer->SetVSync = GLES2_SetVSync;
|
||||
renderer->GL_BindTexture = GLES2_BindTexture;
|
||||
renderer->GL_UnbindTexture = GLES2_UnbindTexture;
|
||||
|
||||
@@ -2081,12 +2045,12 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
|
||||
data->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION);
|
||||
data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_COLOR);
|
||||
data->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
|
||||
|
||||
data->glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
data->drawstate.blend = SDL_BLENDMODE_INVALID;
|
||||
data->drawstate.color = 0xFFFFFFFF;
|
||||
data->drawstate.clear_color = 0xFFFFFFFF;
|
||||
data->drawstate.projection[3][0] = -1.0f;
|
||||
data->drawstate.projection[3][3] = 1.0f;
|
||||
|
@@ -30,52 +30,43 @@
|
||||
/*************************************************************************************************
|
||||
* Vertex/fragment shader source *
|
||||
*************************************************************************************************/
|
||||
/* Notes on a_angle:
|
||||
* It is a vector containing sin and cos for rotation matrix
|
||||
* To get correct rotation for most cases when a_angle is disabled cos
|
||||
value is decremented by 1.0 to get proper output with 0.0 which is
|
||||
default value
|
||||
*/
|
||||
static const Uint8 GLES2_Vertex_Default[] = " \
|
||||
uniform mat4 u_projection; \
|
||||
attribute vec2 a_position; \
|
||||
attribute vec4 a_color; \
|
||||
attribute vec2 a_texCoord; \
|
||||
attribute vec2 a_angle; \
|
||||
attribute vec2 a_center; \
|
||||
varying vec2 v_texCoord; \
|
||||
varying vec4 v_color; \
|
||||
\
|
||||
void main() \
|
||||
{ \
|
||||
float s = a_angle[0]; \
|
||||
float c = a_angle[1] + 1.0; \
|
||||
mat2 rotationMatrix = mat2(c, -s, s, c); \
|
||||
vec2 position = rotationMatrix * (a_position - a_center) + a_center; \
|
||||
v_texCoord = a_texCoord; \
|
||||
gl_Position = u_projection * vec4(position, 0.0, 1.0);\
|
||||
gl_Position = u_projection * vec4(a_position, 0.0, 1.0);\
|
||||
gl_PointSize = 1.0; \
|
||||
v_color = a_color; \
|
||||
} \
|
||||
";
|
||||
|
||||
static const Uint8 GLES2_Fragment_Solid[] = " \
|
||||
precision mediump float; \
|
||||
uniform vec4 u_color; \
|
||||
varying vec4 v_color; \
|
||||
\
|
||||
void main() \
|
||||
{ \
|
||||
gl_FragColor = u_color; \
|
||||
gl_FragColor = v_color; \
|
||||
} \
|
||||
";
|
||||
|
||||
static const Uint8 GLES2_Fragment_TextureABGR[] = " \
|
||||
precision mediump float; \
|
||||
uniform sampler2D u_texture; \
|
||||
uniform vec4 u_color; \
|
||||
varying vec4 v_color; \
|
||||
varying vec2 v_texCoord; \
|
||||
\
|
||||
void main() \
|
||||
{ \
|
||||
gl_FragColor = texture2D(u_texture, v_texCoord); \
|
||||
gl_FragColor *= u_color; \
|
||||
gl_FragColor *= v_color; \
|
||||
} \
|
||||
";
|
||||
|
||||
@@ -83,7 +74,7 @@ static const Uint8 GLES2_Fragment_TextureABGR[] = " \
|
||||
static const Uint8 GLES2_Fragment_TextureARGB[] = " \
|
||||
precision mediump float; \
|
||||
uniform sampler2D u_texture; \
|
||||
uniform vec4 u_color; \
|
||||
varying vec4 v_color; \
|
||||
varying vec2 v_texCoord; \
|
||||
\
|
||||
void main() \
|
||||
@@ -92,7 +83,7 @@ static const Uint8 GLES2_Fragment_TextureARGB[] = " \
|
||||
gl_FragColor = abgr; \
|
||||
gl_FragColor.r = abgr.b; \
|
||||
gl_FragColor.b = abgr.r; \
|
||||
gl_FragColor *= u_color; \
|
||||
gl_FragColor *= v_color; \
|
||||
} \
|
||||
";
|
||||
|
||||
@@ -100,7 +91,7 @@ static const Uint8 GLES2_Fragment_TextureARGB[] = " \
|
||||
static const Uint8 GLES2_Fragment_TextureRGB[] = " \
|
||||
precision mediump float; \
|
||||
uniform sampler2D u_texture; \
|
||||
uniform vec4 u_color; \
|
||||
varying vec4 v_color; \
|
||||
varying vec2 v_texCoord; \
|
||||
\
|
||||
void main() \
|
||||
@@ -110,7 +101,7 @@ static const Uint8 GLES2_Fragment_TextureRGB[] = " \
|
||||
gl_FragColor.r = abgr.b; \
|
||||
gl_FragColor.b = abgr.r; \
|
||||
gl_FragColor.a = 1.0; \
|
||||
gl_FragColor *= u_color; \
|
||||
gl_FragColor *= v_color; \
|
||||
} \
|
||||
";
|
||||
|
||||
@@ -118,7 +109,7 @@ static const Uint8 GLES2_Fragment_TextureRGB[] = " \
|
||||
static const Uint8 GLES2_Fragment_TextureBGR[] = " \
|
||||
precision mediump float; \
|
||||
uniform sampler2D u_texture; \
|
||||
uniform vec4 u_color; \
|
||||
varying vec4 v_color; \
|
||||
varying vec2 v_texCoord; \
|
||||
\
|
||||
void main() \
|
||||
@@ -126,7 +117,7 @@ static const Uint8 GLES2_Fragment_TextureBGR[] = " \
|
||||
vec4 abgr = texture2D(u_texture, v_texCoord); \
|
||||
gl_FragColor = abgr; \
|
||||
gl_FragColor.a = 1.0; \
|
||||
gl_FragColor *= u_color; \
|
||||
gl_FragColor *= v_color; \
|
||||
} \
|
||||
";
|
||||
|
||||
@@ -163,7 +154,7 @@ static const Uint8 GLES2_Fragment_TextureBGR[] = " \
|
||||
"uniform sampler2D u_texture;\n" \
|
||||
"uniform sampler2D u_texture_u;\n" \
|
||||
"uniform sampler2D u_texture_v;\n" \
|
||||
"uniform vec4 u_color;\n" \
|
||||
"varying vec4 v_color;\n" \
|
||||
"varying vec2 v_texCoord;\n" \
|
||||
"\n" \
|
||||
|
||||
@@ -185,10 +176,10 @@ static const Uint8 GLES2_Fragment_TextureBGR[] = " \
|
||||
"\n" \
|
||||
" // That was easy. :) \n" \
|
||||
" gl_FragColor = vec4(rgb, 1);\n" \
|
||||
" gl_FragColor *= u_color;\n" \
|
||||
" gl_FragColor *= v_color;\n" \
|
||||
"}" \
|
||||
|
||||
#define NV12_SHADER_BODY \
|
||||
#define NV12_RA_SHADER_BODY \
|
||||
"\n" \
|
||||
"void main()\n" \
|
||||
"{\n" \
|
||||
@@ -205,7 +196,27 @@ static const Uint8 GLES2_Fragment_TextureBGR[] = " \
|
||||
"\n" \
|
||||
" // That was easy. :) \n" \
|
||||
" gl_FragColor = vec4(rgb, 1);\n" \
|
||||
" gl_FragColor *= u_color;\n" \
|
||||
" gl_FragColor *= v_color;\n" \
|
||||
"}" \
|
||||
|
||||
#define NV12_RG_SHADER_BODY \
|
||||
"\n" \
|
||||
"void main()\n" \
|
||||
"{\n" \
|
||||
" mediump vec3 yuv;\n" \
|
||||
" lowp vec3 rgb;\n" \
|
||||
"\n" \
|
||||
" // Get the YUV values \n" \
|
||||
" yuv.x = texture2D(u_texture, v_texCoord).r;\n" \
|
||||
" yuv.yz = texture2D(u_texture_u, v_texCoord).rg;\n" \
|
||||
"\n" \
|
||||
" // Do the color transform \n" \
|
||||
" yuv += offset;\n" \
|
||||
" rgb = matrix * yuv;\n" \
|
||||
"\n" \
|
||||
" // That was easy. :) \n" \
|
||||
" gl_FragColor = vec4(rgb, 1);\n" \
|
||||
" gl_FragColor *= v_color;\n" \
|
||||
"}" \
|
||||
|
||||
#define NV21_SHADER_BODY \
|
||||
@@ -225,7 +236,7 @@ static const Uint8 GLES2_Fragment_TextureBGR[] = " \
|
||||
"\n" \
|
||||
" // That was easy. :) \n" \
|
||||
" gl_FragColor = vec4(rgb, 1);\n" \
|
||||
" gl_FragColor *= u_color;\n" \
|
||||
" gl_FragColor *= v_color;\n" \
|
||||
"}" \
|
||||
|
||||
/* YUV to ABGR conversion */
|
||||
@@ -249,17 +260,27 @@ static const Uint8 GLES2_Fragment_TextureYUVBT709[] = \
|
||||
static const Uint8 GLES2_Fragment_TextureNV12JPEG[] = \
|
||||
YUV_SHADER_PROLOGUE \
|
||||
JPEG_SHADER_CONSTANTS \
|
||||
NV12_SHADER_BODY \
|
||||
NV12_RA_SHADER_BODY \
|
||||
;
|
||||
static const Uint8 GLES2_Fragment_TextureNV12BT601[] = \
|
||||
static const Uint8 GLES2_Fragment_TextureNV12BT601_RA[] = \
|
||||
YUV_SHADER_PROLOGUE \
|
||||
BT601_SHADER_CONSTANTS \
|
||||
NV12_SHADER_BODY \
|
||||
NV12_RA_SHADER_BODY \
|
||||
;
|
||||
static const Uint8 GLES2_Fragment_TextureNV12BT709[] = \
|
||||
static const Uint8 GLES2_Fragment_TextureNV12BT601_RG[] = \
|
||||
YUV_SHADER_PROLOGUE \
|
||||
BT601_SHADER_CONSTANTS \
|
||||
NV12_RG_SHADER_BODY \
|
||||
;
|
||||
static const Uint8 GLES2_Fragment_TextureNV12BT709_RA[] = \
|
||||
YUV_SHADER_PROLOGUE \
|
||||
BT709_SHADER_CONSTANTS \
|
||||
NV12_SHADER_BODY \
|
||||
NV12_RA_SHADER_BODY \
|
||||
;
|
||||
static const Uint8 GLES2_Fragment_TextureNV12BT709_RG[] = \
|
||||
YUV_SHADER_PROLOGUE \
|
||||
BT709_SHADER_CONSTANTS \
|
||||
NV12_RG_SHADER_BODY \
|
||||
;
|
||||
|
||||
/* NV21 to ABGR conversion */
|
||||
@@ -284,13 +305,13 @@ static const Uint8 GLES2_Fragment_TextureExternalOES[] = " \
|
||||
#extension GL_OES_EGL_image_external : require\n\
|
||||
precision mediump float; \
|
||||
uniform samplerExternalOES u_texture; \
|
||||
uniform vec4 u_color; \
|
||||
varying vec4 v_color; \
|
||||
varying vec2 v_texCoord; \
|
||||
\
|
||||
void main() \
|
||||
{ \
|
||||
gl_FragColor = texture2D(u_texture, v_texCoord); \
|
||||
gl_FragColor *= u_color; \
|
||||
gl_FragColor *= v_color; \
|
||||
} \
|
||||
";
|
||||
|
||||
@@ -322,10 +343,14 @@ const Uint8 *GLES2_GetShader(GLES2_ShaderType type)
|
||||
return GLES2_Fragment_TextureYUVBT709;
|
||||
case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG:
|
||||
return GLES2_Fragment_TextureNV12JPEG;
|
||||
case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT601:
|
||||
return GLES2_Fragment_TextureNV12BT601;
|
||||
case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT709:
|
||||
return GLES2_Fragment_TextureNV12BT709;
|
||||
case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT601:
|
||||
return GLES2_Fragment_TextureNV12BT601_RA;
|
||||
case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT601:
|
||||
return GLES2_Fragment_TextureNV12BT601_RG;
|
||||
case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT709:
|
||||
return GLES2_Fragment_TextureNV12BT709_RA;
|
||||
case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT709:
|
||||
return GLES2_Fragment_TextureNV12BT709_RG;
|
||||
case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG:
|
||||
return GLES2_Fragment_TextureNV21JPEG;
|
||||
case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601:
|
||||
|
@@ -38,16 +38,17 @@ typedef enum
|
||||
GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601,
|
||||
GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709,
|
||||
GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG,
|
||||
GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT601,
|
||||
GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT709,
|
||||
GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT601,
|
||||
GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT601,
|
||||
GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT709,
|
||||
GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT709,
|
||||
GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG,
|
||||
GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601,
|
||||
GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709,
|
||||
GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES
|
||||
GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES,
|
||||
GLES2_SHADER_COUNT
|
||||
} GLES2_ShaderType;
|
||||
|
||||
#define GLES2_SHADER_COUNT 16
|
||||
|
||||
const Uint8 *GLES2_GetShader(GLES2_ShaderType type);
|
||||
|
||||
#endif /* SDL_VIDEO_RENDER_OGL_ES2 */
|
||||
|
174
externals/SDL/src/render/psp/SDL_render_psp.c
vendored
174
externals/SDL/src/render/psp/SDL_render_psp.c
vendored
@@ -56,6 +56,15 @@ static unsigned int __attribute__((aligned(16))) DisplayList[262144];
|
||||
#define COL4444(r,g,b,a) ((r>>4) | ((g>>4)<<4) | ((b>>4)<<8) | ((a>>4)<<12))
|
||||
#define COL8888(r,g,b,a) ((r) | ((g)<<8) | ((b)<<16) | ((a)<<24))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SDL_bool viewport_dirty;
|
||||
SDL_Rect viewport;
|
||||
SDL_bool cliprect_enabled_dirty;
|
||||
SDL_bool cliprect_enabled;
|
||||
SDL_bool cliprect_dirty;
|
||||
SDL_Rect cliprect;
|
||||
} PSP_DrawStateCache;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -70,6 +79,7 @@ typedef struct
|
||||
unsigned int currentColor;
|
||||
int currentBlendMode;
|
||||
|
||||
PSP_DrawStateCache drawstate;
|
||||
} PSP_RenderData;
|
||||
|
||||
|
||||
@@ -98,9 +108,22 @@ typedef struct
|
||||
{
|
||||
float u, v;
|
||||
float x, y, z;
|
||||
|
||||
} VertTV;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int col;
|
||||
float x, y, z;
|
||||
} VertCV;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float u, v;
|
||||
int col;
|
||||
float x, y, z;
|
||||
} VertTCV;
|
||||
|
||||
#define PI 3.14159265358979f
|
||||
|
||||
#define radToDeg(x) ((x)*180.f/PI)
|
||||
@@ -198,7 +221,7 @@ TextureSwizzle(PSP_TextureData *psp_texture)
|
||||
unsigned int *src = (unsigned int*) psp_texture->data;
|
||||
|
||||
unsigned char *data = NULL;
|
||||
data = malloc(psp_texture->size);
|
||||
data = SDL_malloc(psp_texture->size);
|
||||
|
||||
int j;
|
||||
|
||||
@@ -223,7 +246,7 @@ TextureSwizzle(PSP_TextureData *psp_texture)
|
||||
blockaddress += rowblocksadd;
|
||||
}
|
||||
|
||||
free(psp_texture->data);
|
||||
SDL_free(psp_texture->data);
|
||||
psp_texture->data = data;
|
||||
psp_texture->swizzled = SDL_TRUE;
|
||||
|
||||
@@ -249,7 +272,7 @@ int TextureUnswizzle(PSP_TextureData *psp_texture)
|
||||
|
||||
unsigned char *data = NULL;
|
||||
|
||||
data = malloc(psp_texture->size);
|
||||
data = SDL_malloc(psp_texture->size);
|
||||
|
||||
if(!data)
|
||||
return 0;
|
||||
@@ -285,7 +308,7 @@ int TextureUnswizzle(PSP_TextureData *psp_texture)
|
||||
ydst += dstrow;
|
||||
}
|
||||
|
||||
free(psp_texture->data);
|
||||
SDL_free(psp_texture->data);
|
||||
|
||||
psp_texture->data = data;
|
||||
|
||||
@@ -346,12 +369,6 @@ PSP_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
PSP_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
void
|
||||
TextureActivate(SDL_Texture * texture)
|
||||
{
|
||||
@@ -373,6 +390,9 @@ TextureActivate(SDL_Texture * texture)
|
||||
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
|
||||
}
|
||||
|
||||
static int
|
||||
PSP_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
const SDL_Rect * rect, void **pixels, int *pitch);
|
||||
|
||||
static int
|
||||
PSP_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
@@ -466,10 +486,98 @@ PSP_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_F
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
PSP_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)
|
||||
{
|
||||
int i;
|
||||
int count = indices ? num_indices : num_vertices;
|
||||
|
||||
cmd->data.draw.count = count;
|
||||
size_indices = indices ? size_indices : 0;
|
||||
|
||||
if (texture == NULL) {
|
||||
VertCV *verts;
|
||||
verts = (VertCV *) SDL_AllocateRenderVertices(renderer, count * sizeof (VertCV), 4, &cmd->data.draw.first);
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
int j;
|
||||
float *xy_;
|
||||
int 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_ = *(int *)((char*)color + j * color_stride);
|
||||
|
||||
verts->x = xy_[0] * scale_x;
|
||||
verts->y = xy_[1] * scale_y;
|
||||
verts->z = 0;
|
||||
|
||||
verts->col = col_;
|
||||
|
||||
verts++;
|
||||
}
|
||||
} else {
|
||||
PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata;
|
||||
VertTCV *verts;
|
||||
verts = (VertTCV *) SDL_AllocateRenderVertices(renderer, count * sizeof (VertTCV), 4, &cmd->data.draw.first);
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
int j;
|
||||
float *xy_;
|
||||
int col_;
|
||||
float *uv_;
|
||||
|
||||
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_ = *(int *)((char*)color + j * color_stride);
|
||||
uv_ = (float *)((char*)uv + j * uv_stride);
|
||||
|
||||
verts->x = xy_[0] * scale_x;
|
||||
verts->y = xy_[1] * scale_y;
|
||||
verts->z = 0;
|
||||
|
||||
verts->col = col_;
|
||||
|
||||
verts->u = uv_[0] * psp_texture->textureWidth;
|
||||
verts->v = uv_[1] * psp_texture->textureHeight;
|
||||
|
||||
verts++;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
PSP_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count)
|
||||
{
|
||||
VertV *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * 2 * sizeof (VertV), 4, &cmd->data.draw.first);
|
||||
VertV *verts = (VertV *) SDL_AllocateRenderVertices(renderer, count * 2 * sizeof (VertV), 4, &cmd->data.draw.first);
|
||||
int i;
|
||||
|
||||
if (!verts) {
|
||||
@@ -691,7 +799,6 @@ static int
|
||||
PSP_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
|
||||
{
|
||||
PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
|
||||
size_t i;
|
||||
|
||||
StartDrawing(renderer);
|
||||
|
||||
@@ -740,7 +847,7 @@ PSP_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti
|
||||
const Uint8 g = cmd->data.color.g;
|
||||
const Uint8 b = cmd->data.color.b;
|
||||
const Uint8 a = cmd->data.color.a;
|
||||
const Uint32 color = ((a << 24) | (b << 16) | (g << 8) | r);
|
||||
const Uint32 color = (((Uint32)a << 24) | (b << 16) | (g << 8) | r);
|
||||
/* !!! FIXME: we could cache drawstate like clear color */
|
||||
sceGuClearColor(color);
|
||||
sceGuClearDepth(0);
|
||||
@@ -755,7 +862,7 @@ PSP_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti
|
||||
const Uint8 g = cmd->data.draw.g;
|
||||
const Uint8 b = cmd->data.draw.b;
|
||||
const Uint8 a = cmd->data.draw.a;
|
||||
const Uint32 color = ((a << 24) | (b << 16) | (g << 8) | r);
|
||||
const Uint32 color = (((Uint32)a << 24) | (b << 16) | (g << 8) | r);
|
||||
/* !!! FIXME: we could cache draw state like color, texturing, etc */
|
||||
sceGuColor(color);
|
||||
sceGuDisable(GU_TEXTURE_2D);
|
||||
@@ -773,7 +880,7 @@ PSP_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti
|
||||
const Uint8 g = cmd->data.draw.g;
|
||||
const Uint8 b = cmd->data.draw.b;
|
||||
const Uint8 a = cmd->data.draw.a;
|
||||
const Uint32 color = ((a << 24) | (b << 16) | (g << 8) | r);
|
||||
const Uint32 color = (((Uint32)a << 24) | (b << 16) | (g << 8) | r);
|
||||
/* !!! FIXME: we could cache draw state like color, texturing, etc */
|
||||
sceGuColor(color);
|
||||
sceGuDisable(GU_TEXTURE_2D);
|
||||
@@ -791,7 +898,7 @@ PSP_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti
|
||||
const Uint8 g = cmd->data.draw.g;
|
||||
const Uint8 b = cmd->data.draw.b;
|
||||
const Uint8 a = cmd->data.draw.a;
|
||||
const Uint32 color = ((a << 24) | (b << 16) | (g << 8) | r);
|
||||
const Uint32 color = (((Uint32)a << 24) | (b << 16) | (g << 8) | r);
|
||||
/* !!! FIXME: we could cache draw state like color, texturing, etc */
|
||||
sceGuColor(color);
|
||||
sceGuDisable(GU_TEXTURE_2D);
|
||||
@@ -847,6 +954,25 @@ PSP_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_GEOMETRY: {
|
||||
const size_t count = cmd->data.draw.count;
|
||||
if (cmd->data.draw.texture == NULL) {
|
||||
const VertCV *verts = (VertCV *) (gpumem + cmd->data.draw.first);
|
||||
sceGuDisable(GU_TEXTURE_2D);
|
||||
/* In GU_SMOOTH mode */
|
||||
sceGuDrawArray(GU_TRIANGLES, GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_2D, count, 0, verts);
|
||||
sceGuEnable(GU_TEXTURE_2D);
|
||||
} else {
|
||||
const VertTCV *verts = (VertTCV *) (gpumem + cmd->data.draw.first);
|
||||
TextureActivate(cmd->data.draw.texture);
|
||||
/* Need to force refresh of blending mode, probably something to FIXME */
|
||||
PSP_SetBlendMode(renderer, SDL_BLENDMODE_INVALID);
|
||||
PSP_SetBlendMode(renderer, cmd->data.draw.blend);
|
||||
sceGuDrawArray(GU_TRIANGLES, GU_TEXTURE_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_2D, count, 0, verts);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_NO_OP:
|
||||
break;
|
||||
}
|
||||
@@ -921,6 +1047,14 @@ PSP_DestroyRenderer(SDL_Renderer * renderer)
|
||||
SDL_free(renderer);
|
||||
}
|
||||
|
||||
static int
|
||||
PSP_SetVSync(SDL_Renderer * renderer, const int vsync)
|
||||
{
|
||||
PSP_RenderData *data = renderer->driverdata;
|
||||
data->vsync = vsync;
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_Renderer *
|
||||
PSP_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
{
|
||||
@@ -944,7 +1078,6 @@ PSP_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
|
||||
renderer->WindowEvent = PSP_WindowEvent;
|
||||
renderer->CreateTexture = PSP_CreateTexture;
|
||||
renderer->SetTextureColorMod = PSP_SetTextureColorMod;
|
||||
renderer->UpdateTexture = PSP_UpdateTexture;
|
||||
renderer->LockTexture = PSP_LockTexture;
|
||||
renderer->UnlockTexture = PSP_UnlockTexture;
|
||||
@@ -954,6 +1087,7 @@ PSP_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
renderer->QueueSetDrawColor = PSP_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */
|
||||
renderer->QueueDrawPoints = PSP_QueueDrawPoints;
|
||||
renderer->QueueDrawLines = PSP_QueueDrawPoints; /* lines and points queue vertices the same way. */
|
||||
renderer->QueueGeometry = PSP_QueueGeometry;
|
||||
renderer->QueueFillRects = PSP_QueueFillRects;
|
||||
renderer->QueueCopy = PSP_QueueCopy;
|
||||
renderer->QueueCopyEx = PSP_QueueCopyEx;
|
||||
@@ -962,6 +1096,7 @@ PSP_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
renderer->RenderPresent = PSP_RenderPresent;
|
||||
renderer->DestroyTexture = PSP_DestroyTexture;
|
||||
renderer->DestroyRenderer = PSP_DestroyRenderer;
|
||||
renderer->SetVSync = PSP_SetVSync;
|
||||
renderer->info = PSP_RenderDriver.info;
|
||||
renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
|
||||
renderer->driverdata = data;
|
||||
@@ -1014,8 +1149,11 @@ PSP_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
sceGuEnable(GU_SCISSOR_TEST);
|
||||
|
||||
/* Backface culling */
|
||||
/*
|
||||
FIXME: Culling probably un-needed ? It can conflict with SDL_RENDERCMD_GEOMETRY
|
||||
sceGuFrontFace(GU_CCW);
|
||||
sceGuEnable(GU_CULL_FACE);
|
||||
*/
|
||||
|
||||
/* Texturing */
|
||||
sceGuEnable(GU_TEXTURE_2D);
|
||||
|
8
externals/SDL/src/render/software/SDL_draw.h
vendored
8
externals/SDL/src/render/software/SDL_draw.h
vendored
@@ -618,10 +618,10 @@ do { \
|
||||
while (height--) { \
|
||||
{ int n = (width+3)/4; \
|
||||
switch (width & 3) { \
|
||||
case 0: do { op; pixel++; /* fallthrough */ \
|
||||
case 3: op; pixel++; /* fallthrough */ \
|
||||
case 2: op; pixel++; /* fallthrough */ \
|
||||
case 1: op; pixel++; /* fallthrough */ \
|
||||
case 0: do { op; pixel++; SDL_FALLTHROUGH; \
|
||||
case 3: op; pixel++; SDL_FALLTHROUGH; \
|
||||
case 2: op; pixel++; SDL_FALLTHROUGH; \
|
||||
case 1: op; pixel++; \
|
||||
} while ( --n > 0 ); \
|
||||
} \
|
||||
} \
|
||||
|
@@ -193,8 +193,8 @@ SDL_DrawLines(SDL_Surface * dst, const SDL_Point * points, int count,
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Draw the end if it was clipped */
|
||||
draw_end = (x2 != points[i].x || y2 != points[i].y);
|
||||
/* Draw the end if the whole line is a single point or it was clipped */
|
||||
draw_end = ((x1 == x2) && (y1 == y2)) || (x2 != points[i].x || y2 != points[i].y);
|
||||
|
||||
func(dst, x1, y1, x2, y2, color, draw_end);
|
||||
}
|
||||
|
154
externals/SDL/src/render/software/SDL_render_sw.c
vendored
154
externals/SDL/src/render/software/SDL_render_sw.c
vendored
@@ -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 */
|
||||
|
||||
@@ -116,9 +117,8 @@ SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
texture->driverdata =
|
||||
SDL_CreateRGBSurface(0, texture->w, texture->h, bpp, Rmask, Gmask,
|
||||
Bmask, Amask);
|
||||
SDL_SetSurfaceColorMod(texture->driverdata, texture->r, texture->g,
|
||||
texture->b);
|
||||
SDL_SetSurfaceAlphaMod(texture->driverdata, texture->a);
|
||||
SDL_SetSurfaceColorMod(texture->driverdata, texture->color.r, texture->color.g, texture->color.b);
|
||||
SDL_SetSurfaceAlphaMod(texture->driverdata, texture->color.a);
|
||||
SDL_SetSurfaceBlendMode(texture->driverdata, texture->blendMode);
|
||||
|
||||
/* Only RLE encode textures without an alpha channel since the RLE coder
|
||||
@@ -560,6 +560,104 @@ 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,
|
||||
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)
|
||||
{
|
||||
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;
|
||||
size_indices = indices ? size_indices : 0;
|
||||
|
||||
if (texture) {
|
||||
GeometryCopyData *ptr = (GeometryCopyData *) verts;
|
||||
for (i = 0; i < count; i++) {
|
||||
int j;
|
||||
float *xy_;
|
||||
SDL_Color col_;
|
||||
float *uv_;
|
||||
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);
|
||||
|
||||
uv_ = (float *)((char*)uv + j * uv_stride);
|
||||
|
||||
ptr->src.x = (int)(uv_[0] * texture->w);
|
||||
ptr->src.y = (int)(uv_[1] * texture->h);
|
||||
|
||||
ptr->dst.x = (int)(xy_[0] * scale_x + renderer->viewport.x);
|
||||
ptr->dst.y = (int)(xy_[1] * scale_y + renderer->viewport.y);
|
||||
trianglepoint_2_fixedpoint(&ptr->dst);
|
||||
|
||||
ptr->color = col_;
|
||||
|
||||
ptr++;
|
||||
}
|
||||
} else {
|
||||
GeometryFillData *ptr = (GeometryFillData *) verts;
|
||||
|
||||
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);
|
||||
|
||||
ptr->dst.x = (int)(xy_[0] * scale_x + renderer->viewport.x);
|
||||
ptr->dst.y = (int)(xy_[1] * scale_y + renderer->viewport.y);
|
||||
trianglepoint_2_fixedpoint(&ptr->dst);
|
||||
|
||||
ptr->color = col_;
|
||||
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
PrepTextureForCopy(const SDL_RenderCommand *cmd)
|
||||
{
|
||||
@@ -634,7 +732,7 @@ SW_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_SETCLIPRECT: {
|
||||
drawstate.cliprect = cmd->data.cliprect.enabled ? &cmd->data.cliprect.rect : NULL;
|
||||
drawstate.cliprect = cmd->data.cliprect.enabled ? &cmd->data.cliprect.rect : NULL;
|
||||
drawstate.surface_cliprect_dirty = SDL_TRUE;
|
||||
break;
|
||||
}
|
||||
@@ -734,6 +832,38 @@ 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 +973,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;
|
||||
@@ -859,9 +990,22 @@ SW_CreateRendererForSurface(SDL_Surface * surface)
|
||||
static SDL_Renderer *
|
||||
SW_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
{
|
||||
const char *hint;
|
||||
SDL_Surface *surface;
|
||||
|
||||
/* Set the vsync hint based on our flags, if it's not already set */
|
||||
hint = SDL_GetHint(SDL_HINT_RENDER_VSYNC);
|
||||
if (!hint || !*hint) {
|
||||
SDL_SetHint(SDL_HINT_RENDER_VSYNC, (flags & SDL_RENDERER_PRESENTVSYNC) ? "1" : "0");
|
||||
}
|
||||
|
||||
surface = SDL_GetWindowSurface(window);
|
||||
|
||||
/* Reset the vsync hint if we set it above */
|
||||
if (!hint || !*hint) {
|
||||
SDL_SetHint(SDL_HINT_RENDER_VSYNC, "");
|
||||
}
|
||||
|
||||
if (!surface) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -872,7 +1016,7 @@ SDL_RenderDriver SW_RenderDriver = {
|
||||
SW_CreateRenderer,
|
||||
{
|
||||
"software",
|
||||
SDL_RENDERER_SOFTWARE | SDL_RENDERER_TARGETTEXTURE,
|
||||
SDL_RENDERER_SOFTWARE | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE,
|
||||
8,
|
||||
{
|
||||
SDL_PIXELFORMAT_ARGB8888,
|
||||
|
@@ -184,7 +184,7 @@ computeSourceIncrements90(SDL_Surface * src, int bpp, int angle, int flipx, int
|
||||
if (signy < 0) sp += (src->h-1)*src->pitch; \
|
||||
\
|
||||
for (dy = 0; dy < dst->h; sp += sincy, dp += dincy, dy++) { \
|
||||
if (sincx == sizeof(pixelType)) { /* if advancing src and dest equally, use memcpy */ \
|
||||
if (sincx == sizeof(pixelType)) { /* if advancing src and dest equally, use SDL_memcpy */ \
|
||||
SDL_memcpy(dp, sp, dst->w*sizeof(pixelType)); \
|
||||
sp += dst->w*sizeof(pixelType); \
|
||||
dp += dst->w*sizeof(pixelType); \
|
||||
@@ -439,7 +439,7 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery,
|
||||
if (!(is8bit || (src->format->BitsPerPixel == 32 && src->format->Amask)))
|
||||
return NULL;
|
||||
|
||||
/* Calculate target factors from sin/cos and zoom */
|
||||
/* Calculate target factors from sine/cosine and zoom */
|
||||
sangleinv = sangle*65536.0;
|
||||
cangleinv = cangle*65536.0;
|
||||
|
||||
|
828
externals/SDL/src/render/software/SDL_triangle.c
vendored
Executable file
828
externals/SDL/src/render/software/SDL_triangle.c
vendored
Executable file
@@ -0,0 +1,828 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED
|
||||
|
||||
#include "SDL_surface.h"
|
||||
#include "SDL_triangle.h"
|
||||
|
||||
#include "../../video/SDL_blit.h"
|
||||
|
||||
/* fixed points bits precision
|
||||
* Set to 1, so that it can start rendering wth middle of a pixel precision.
|
||||
* It doesn't need to be increased.
|
||||
* But, if increased too much, it overflows (srcx, srcy) coordinates used for filling with texture.
|
||||
* (which could be turned to int64).
|
||||
*/
|
||||
#define FP_BITS 1
|
||||
|
||||
|
||||
#define COLOR_EQ(c1, c2) ((c1).r == (c2).r && (c1).g == (c2).g && (c1).b == (c2).b && (c1).a == (c2).a)
|
||||
|
||||
static void SDL_BlitTriangle_Slow(SDL_BlitInfo * info,
|
||||
SDL_Point s2_x_area, SDL_Rect dstrect, int area, int bias_w0, int bias_w1, int bias_w2,
|
||||
int d2d1_y, int d1d2_x, int d0d2_y, int d2d0_x, int d1d0_y, int d0d1_x,
|
||||
int s2s0_x, int s2s1_x, int s2s0_y, int s2s1_y, int w0_row, int w1_row, int w2_row,
|
||||
SDL_Color c0, SDL_Color c1, SDL_Color c2, int is_uniform);
|
||||
|
||||
#if 0
|
||||
int SDL_BlitTriangle(SDL_Surface *src, const SDL_Point srcpoints[3], SDL_Surface *dst, const SDL_Point dstpoints[3])
|
||||
{
|
||||
int i;
|
||||
SDL_Point points[6];
|
||||
|
||||
if (src == NULL || dst == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (srcpoints[i].x < 0 || srcpoints[i].y < 0 || srcpoints[i].x >= src->w || srcpoints[i].y >= src->h) {
|
||||
return SDL_SetError("Values of 'srcpoints' out of bounds");
|
||||
}
|
||||
}
|
||||
|
||||
points[0] = srcpoints[0];
|
||||
points[1] = dstpoints[0];
|
||||
points[2] = srcpoints[1];
|
||||
points[3] = dstpoints[1];
|
||||
points[4] = srcpoints[2];
|
||||
points[5] = dstpoints[2];
|
||||
for (i = 0; i < 3; i++) {
|
||||
trianglepoint_2_fixedpoint(&points[2 * i + 1]);
|
||||
}
|
||||
return SDL_SW_BlitTriangle(src, dst, points);
|
||||
}
|
||||
|
||||
int SDL_FillTriangle(SDL_Surface *dst, const SDL_Point points[3], Uint32 color)
|
||||
{
|
||||
int i;
|
||||
SDL_Point points_tmp[3];
|
||||
if (dst == NULL) {
|
||||
return -1;
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
points_tmp[i] = points[i];
|
||||
trianglepoint_2_fixedpoint(&points_tmp[i]);
|
||||
}
|
||||
return SDL_SW_FillTriangle(dst, points_tmp, SDL_BLENDMODE_NONE, color);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* cross product AB x AC */
|
||||
static int cross_product(const SDL_Point *a, const SDL_Point *b, int c_x, int c_y)
|
||||
{
|
||||
return (b->x - a->x) * (c_y - a->y) - (b->y - a->y) * (c_x - a->x);
|
||||
}
|
||||
|
||||
/* check for top left rules */
|
||||
static int is_top_left(const SDL_Point *a, const SDL_Point *b, int is_clockwise)
|
||||
{
|
||||
if (is_clockwise) {
|
||||
if (a->y == b->y && a->x < b->x) {
|
||||
return 1;
|
||||
}
|
||||
if (b->y < a->y) {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
if (a->y == b->y && b->x < a->x) {
|
||||
return 1;
|
||||
}
|
||||
if (a->y < b->y) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void trianglepoint_2_fixedpoint(SDL_Point *a) {
|
||||
a->x <<= FP_BITS;
|
||||
a->y <<= FP_BITS;
|
||||
}
|
||||
|
||||
/* bounding rect of three points */
|
||||
static void bounding_rect(const SDL_Point *a, const SDL_Point *b, const SDL_Point *c, SDL_Rect *r)
|
||||
{
|
||||
int min_x = SDL_min(a->x, SDL_min(b->x, c->x));
|
||||
int max_x = SDL_max(a->x, SDL_max(b->x, c->x));
|
||||
int min_y = SDL_min(a->y, SDL_min(b->y, c->y));
|
||||
int max_y = SDL_max(a->y, SDL_max(b->y, c->y));
|
||||
/* points are in fixed point, shift back */
|
||||
r->x = min_x >> FP_BITS;
|
||||
r->y = min_y >> FP_BITS;
|
||||
r->w = (max_x - min_x) >> FP_BITS;
|
||||
r->h = (max_y - min_y) >> FP_BITS;
|
||||
}
|
||||
|
||||
/* Triangle rendering, using Barycentric coordinates (w0, w1, w2)
|
||||
*
|
||||
* The cross product isn't computed from scratch at each iteration,
|
||||
* but optimized using constant step increments
|
||||
*
|
||||
*/
|
||||
|
||||
#define TRIANGLE_BEGIN_LOOP \
|
||||
{ \
|
||||
int x, y; \
|
||||
for (y = 0; y < dstrect.h; y++) { \
|
||||
/* y start */ \
|
||||
int w0 = w0_row; \
|
||||
int w1 = w1_row; \
|
||||
int w2 = w2_row; \
|
||||
for (x = 0; x < dstrect.w; x++) { \
|
||||
/* In triangle */ \
|
||||
if (w0 + bias_w0 >= 0 && w1 + bias_w1 >= 0 && w2 + bias_w2 >= 0) { \
|
||||
Uint8 *dptr = (Uint8 *) dst_ptr + x * dstbpp; \
|
||||
|
||||
|
||||
/* Use 64 bits precision to prevent overflow when interpolating color / texture with wide triangles */
|
||||
#define TRIANGLE_GET_TEXTCOORD \
|
||||
int srcx = (int)(((Sint64)w0 * s2s0_x + (Sint64)w1 * s2s1_x + s2_x_area.x) / area); \
|
||||
int srcy = (int)(((Sint64)w0 * s2s0_y + (Sint64)w1 * s2s1_y + s2_x_area.y) / area); \
|
||||
|
||||
#define TRIANGLE_GET_MAPPED_COLOR \
|
||||
int r = (int)(((Sint64)w0 * c0.r + (Sint64)w1 * c1.r + (Sint64)w2 * c2.r) / area); \
|
||||
int g = (int)(((Sint64)w0 * c0.g + (Sint64)w1 * c1.g + (Sint64)w2 * c2.g) / area); \
|
||||
int b = (int)(((Sint64)w0 * c0.b + (Sint64)w1 * c1.b + (Sint64)w2 * c2.b) / area); \
|
||||
int a = (int)(((Sint64)w0 * c0.a + (Sint64)w1 * c1.a + (Sint64)w2 * c2.a) / area); \
|
||||
int color = SDL_MapRGBA(format, r, g, b, a); \
|
||||
|
||||
#define TRIANGLE_GET_COLOR \
|
||||
int r = (int)(((Sint64)w0 * c0.r + (Sint64)w1 * c1.r + (Sint64)w2 * c2.r) / area); \
|
||||
int g = (int)(((Sint64)w0 * c0.g + (Sint64)w1 * c1.g + (Sint64)w2 * c2.g) / area); \
|
||||
int b = (int)(((Sint64)w0 * c0.b + (Sint64)w1 * c1.b + (Sint64)w2 * c2.b) / area); \
|
||||
int a = (int)(((Sint64)w0 * c0.a + (Sint64)w1 * c1.a + (Sint64)w2 * c2.a) / area); \
|
||||
|
||||
|
||||
#define TRIANGLE_END_LOOP \
|
||||
} \
|
||||
/* x += 1 */ \
|
||||
w0 += d2d1_y; \
|
||||
w1 += d0d2_y; \
|
||||
w2 += d1d0_y; \
|
||||
} \
|
||||
/* y += 1 */ \
|
||||
w0_row += d1d2_x; \
|
||||
w1_row += d2d0_x; \
|
||||
w2_row += d0d1_x; \
|
||||
dst_ptr += dst_pitch; \
|
||||
} \
|
||||
} \
|
||||
|
||||
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)
|
||||
{
|
||||
int ret = 0;
|
||||
int dst_locked = 0;
|
||||
|
||||
SDL_Rect dstrect;
|
||||
|
||||
int dstbpp;
|
||||
Uint8 *dst_ptr;
|
||||
int dst_pitch;
|
||||
|
||||
int area, is_clockwise;
|
||||
|
||||
int d2d1_y, d1d2_x, d0d2_y, d2d0_x, d1d0_y, d0d1_x;
|
||||
int w0_row, w1_row, w2_row;
|
||||
int bias_w0, bias_w1, bias_w2;
|
||||
|
||||
int is_uniform;
|
||||
|
||||
SDL_Surface *tmp = NULL;
|
||||
|
||||
if (dst == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
area = cross_product(d0, d1, d2->x, d2->y);
|
||||
|
||||
is_uniform = COLOR_EQ(c0, c1) && COLOR_EQ(c1, c2);
|
||||
|
||||
/* Flat triangle */
|
||||
if (area == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Lock the destination, if needed */
|
||||
if (SDL_MUSTLOCK(dst)) {
|
||||
if (SDL_LockSurface(dst) < 0) {
|
||||
ret = -1;
|
||||
goto end;
|
||||
} else {
|
||||
dst_locked = 1;
|
||||
}
|
||||
}
|
||||
|
||||
bounding_rect(d0, d1, d2, &dstrect);
|
||||
|
||||
{
|
||||
/* Clip triangle rect with surface rect */
|
||||
SDL_Rect rect;
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.w = dst->w;
|
||||
rect.h = dst->h;
|
||||
SDL_IntersectRect(&dstrect, &rect, &dstrect);
|
||||
}
|
||||
|
||||
{
|
||||
/* Clip triangle with surface clip rect */
|
||||
SDL_Rect rect;
|
||||
SDL_GetClipRect(dst, &rect);
|
||||
SDL_IntersectRect(&dstrect, &rect, &dstrect);
|
||||
}
|
||||
|
||||
|
||||
if (blend != SDL_BLENDMODE_NONE) {
|
||||
int format = dst->format->format;
|
||||
|
||||
/* need an alpha format */
|
||||
if (! dst->format->Amask) {
|
||||
format = SDL_PIXELFORMAT_ARGB8888;
|
||||
}
|
||||
|
||||
/* Use an intermediate surface */
|
||||
tmp = SDL_CreateRGBSurfaceWithFormat(0, dstrect.w, dstrect.h, 0, format);
|
||||
if (tmp == NULL) {
|
||||
ret = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (blend == SDL_BLENDMODE_MOD) {
|
||||
Uint32 c = SDL_MapRGBA(tmp->format, 255, 255, 255, 255);
|
||||
SDL_FillRect(tmp, NULL, c);
|
||||
}
|
||||
|
||||
SDL_SetSurfaceBlendMode(tmp, blend);
|
||||
|
||||
dstbpp = tmp->format->BytesPerPixel;
|
||||
dst_ptr = tmp->pixels;
|
||||
dst_pitch = tmp->pitch;
|
||||
|
||||
} else {
|
||||
/* Write directly to destination surface */
|
||||
dstbpp = dst->format->BytesPerPixel;
|
||||
dst_ptr = (Uint8 *)dst->pixels + dstrect.x * dstbpp + dstrect.y * dst->pitch;
|
||||
dst_pitch = dst->pitch;
|
||||
}
|
||||
|
||||
is_clockwise = area > 0;
|
||||
area = SDL_abs(area);
|
||||
|
||||
d2d1_y = (d1->y - d2->y) << FP_BITS;
|
||||
d0d2_y = (d2->y - d0->y) << FP_BITS;
|
||||
d1d0_y = (d0->y - d1->y) << FP_BITS;
|
||||
d1d2_x = (d2->x - d1->x) << FP_BITS;
|
||||
d2d0_x = (d0->x - d2->x) << FP_BITS;
|
||||
d0d1_x = (d1->x - d0->x) << FP_BITS;
|
||||
|
||||
/* Starting point for rendering, at the middle of a pixel */
|
||||
{
|
||||
SDL_Point p;
|
||||
p.x = dstrect.x;
|
||||
p.y = dstrect.y;
|
||||
trianglepoint_2_fixedpoint(&p);
|
||||
p.x += (1 << FP_BITS) / 2;
|
||||
p.y += (1 << FP_BITS) / 2;
|
||||
w0_row = cross_product(d1, d2, p.x, p.y);
|
||||
w1_row = cross_product(d2, d0, p.x, p.y);
|
||||
w2_row = cross_product(d0, d1, p.x, p.y);
|
||||
}
|
||||
|
||||
/* Handle anti-clockwise triangles */
|
||||
if (! is_clockwise) {
|
||||
d2d1_y *= -1;
|
||||
d0d2_y *= -1;
|
||||
d1d0_y *= -1;
|
||||
d1d2_x *= -1;
|
||||
d2d0_x *= -1;
|
||||
d0d1_x *= -1;
|
||||
w0_row *= -1;
|
||||
w1_row *= -1;
|
||||
w2_row *= -1;
|
||||
}
|
||||
|
||||
/* Add a bias to respect top-left rasterization rule */
|
||||
bias_w0 = (is_top_left(d1, d2, is_clockwise) ? 0 : -1);
|
||||
bias_w1 = (is_top_left(d2, d0, is_clockwise) ? 0 : -1);
|
||||
bias_w2 = (is_top_left(d0, d1, is_clockwise) ? 0 : -1);
|
||||
|
||||
if (is_uniform) {
|
||||
Uint32 color;
|
||||
if (tmp) {
|
||||
if (dst->format->Amask) {
|
||||
color = SDL_MapRGBA(tmp->format, c0.r, c0.g, c0.b, c0.a);
|
||||
} else {
|
||||
//color = SDL_MapRGB(tmp->format, c0.r, c0.g, c0.b);
|
||||
color = SDL_MapRGBA(tmp->format, c0.r, c0.g, c0.b, c0.a);
|
||||
}
|
||||
} else {
|
||||
color = SDL_MapRGBA(dst->format, c0.r, c0.g, c0.b, c0.a);
|
||||
}
|
||||
|
||||
if (dstbpp == 4) {
|
||||
TRIANGLE_BEGIN_LOOP
|
||||
{
|
||||
*(Uint32 *)dptr = color;
|
||||
}
|
||||
TRIANGLE_END_LOOP
|
||||
} else if (dstbpp == 3) {
|
||||
TRIANGLE_BEGIN_LOOP
|
||||
{
|
||||
Uint8 *s = (Uint8*)&color;
|
||||
dptr[0] = s[0];
|
||||
dptr[1] = s[1];
|
||||
dptr[2] = s[2];
|
||||
}
|
||||
TRIANGLE_END_LOOP
|
||||
} else if (dstbpp == 2) {
|
||||
TRIANGLE_BEGIN_LOOP
|
||||
{
|
||||
*(Uint16 *)dptr = color;
|
||||
}
|
||||
TRIANGLE_END_LOOP
|
||||
} else if (dstbpp == 1) {
|
||||
TRIANGLE_BEGIN_LOOP
|
||||
{
|
||||
*dptr = color;
|
||||
}
|
||||
TRIANGLE_END_LOOP
|
||||
}
|
||||
} else {
|
||||
SDL_PixelFormat *format = dst->format;
|
||||
if (tmp) {
|
||||
format = tmp->format;
|
||||
}
|
||||
if (dstbpp == 4) {
|
||||
TRIANGLE_BEGIN_LOOP
|
||||
{
|
||||
TRIANGLE_GET_MAPPED_COLOR
|
||||
*(Uint32 *)dptr = color;
|
||||
}
|
||||
TRIANGLE_END_LOOP
|
||||
} else if (dstbpp == 3) {
|
||||
TRIANGLE_BEGIN_LOOP
|
||||
{
|
||||
TRIANGLE_GET_MAPPED_COLOR
|
||||
Uint8 *s = (Uint8*)&color;
|
||||
dptr[0] = s[0];
|
||||
dptr[1] = s[1];
|
||||
dptr[2] = s[2];
|
||||
}
|
||||
TRIANGLE_END_LOOP
|
||||
} else if (dstbpp == 2) {
|
||||
TRIANGLE_BEGIN_LOOP
|
||||
{
|
||||
TRIANGLE_GET_MAPPED_COLOR
|
||||
*(Uint16 *)dptr = color;
|
||||
}
|
||||
TRIANGLE_END_LOOP
|
||||
} else if (dstbpp == 1) {
|
||||
TRIANGLE_BEGIN_LOOP
|
||||
{
|
||||
TRIANGLE_GET_MAPPED_COLOR
|
||||
*dptr = color;
|
||||
}
|
||||
TRIANGLE_END_LOOP
|
||||
}
|
||||
}
|
||||
|
||||
if (tmp) {
|
||||
SDL_BlitSurface(tmp, NULL, dst, &dstrect);
|
||||
SDL_FreeSurface(tmp);
|
||||
}
|
||||
|
||||
end:
|
||||
if (dst_locked) {
|
||||
SDL_UnlockSurface(dst);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
int ret = 0;
|
||||
int src_locked = 0;
|
||||
int dst_locked = 0;
|
||||
|
||||
SDL_BlendMode blend;
|
||||
|
||||
SDL_Rect srcrect;
|
||||
SDL_Rect dstrect;
|
||||
|
||||
SDL_Point s2_x_area;
|
||||
|
||||
int dstbpp;
|
||||
Uint8 *dst_ptr;
|
||||
int dst_pitch;
|
||||
|
||||
int *src_ptr;
|
||||
int src_pitch;
|
||||
|
||||
int area, is_clockwise;
|
||||
|
||||
int d2d1_y, d1d2_x, d0d2_y, d2d0_x, d1d0_y, d0d1_x;
|
||||
int s2s0_x, s2s1_x, s2s0_y, s2s1_y;
|
||||
|
||||
int w0_row, w1_row, w2_row;
|
||||
int bias_w0, bias_w1, bias_w2;
|
||||
|
||||
int is_uniform;
|
||||
|
||||
int has_modulation;
|
||||
|
||||
if (src == NULL || dst == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
area = cross_product(d0, d1, d2->x, d2->y);
|
||||
|
||||
/* Flat triangle */
|
||||
if (area == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Lock the destination, if needed */
|
||||
if (SDL_MUSTLOCK(dst)) {
|
||||
if (SDL_LockSurface(dst) < 0) {
|
||||
ret = -1;
|
||||
goto end;
|
||||
} else {
|
||||
dst_locked = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Lock the source, if needed */
|
||||
if (SDL_MUSTLOCK(src)) {
|
||||
if (SDL_LockSurface(src) < 0) {
|
||||
ret = -1;
|
||||
goto end;
|
||||
} else {
|
||||
src_locked = 1;
|
||||
}
|
||||
}
|
||||
|
||||
is_uniform = COLOR_EQ(c0, c1) && COLOR_EQ(c1, c2);
|
||||
|
||||
bounding_rect(s0, s1, s2, &srcrect);
|
||||
bounding_rect(d0, d1, d2, &dstrect);
|
||||
|
||||
SDL_GetSurfaceBlendMode(src, &blend);
|
||||
|
||||
if (is_uniform) {
|
||||
// SDL_GetSurfaceColorMod(src, &r, &g, &b);
|
||||
has_modulation = c0.r != 255 || c0.g != 255 || c0.b != 255 || c0.a != 255;;
|
||||
} else {
|
||||
has_modulation = SDL_TRUE;
|
||||
}
|
||||
|
||||
{
|
||||
/* Clip triangle rect with surface rect */
|
||||
SDL_Rect rect;
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.w = dst->w;
|
||||
rect.h = dst->h;
|
||||
|
||||
SDL_IntersectRect(&dstrect, &rect, &dstrect);
|
||||
}
|
||||
|
||||
{
|
||||
/* Clip triangle with surface clip rect */
|
||||
SDL_Rect rect;
|
||||
SDL_GetClipRect(dst, &rect);
|
||||
SDL_IntersectRect(&dstrect, &rect, &dstrect);
|
||||
}
|
||||
|
||||
/* Set destination pointer */
|
||||
dstbpp = dst->format->BytesPerPixel;
|
||||
dst_ptr = (Uint8 *)dst->pixels + dstrect.x * dstbpp + dstrect.y * dst->pitch;
|
||||
dst_pitch = dst->pitch;
|
||||
|
||||
/* Set source pointer */
|
||||
src_ptr = src->pixels;
|
||||
src_pitch = src->pitch;
|
||||
|
||||
is_clockwise = area > 0;
|
||||
area = SDL_abs(area);
|
||||
|
||||
d2d1_y = (d1->y - d2->y) << FP_BITS;
|
||||
d0d2_y = (d2->y - d0->y) << FP_BITS;
|
||||
d1d0_y = (d0->y - d1->y) << FP_BITS;
|
||||
|
||||
|
||||
d1d2_x = (d2->x - d1->x) << FP_BITS;
|
||||
d2d0_x = (d0->x - d2->x) << FP_BITS;
|
||||
d0d1_x = (d1->x - d0->x) << FP_BITS;
|
||||
|
||||
s2s0_x = s0->x - s2->x;
|
||||
s2s1_x = s1->x - s2->x;
|
||||
s2s0_y = s0->y - s2->y;
|
||||
s2s1_y = s1->y - s2->y;
|
||||
|
||||
/* Starting point for rendering, at the middle of a pixel */
|
||||
{
|
||||
SDL_Point p;
|
||||
p.x = dstrect.x;
|
||||
p.y = dstrect.y;
|
||||
trianglepoint_2_fixedpoint(&p);
|
||||
p.x += (1 << FP_BITS) / 2;
|
||||
p.y += (1 << FP_BITS) / 2;
|
||||
w0_row = cross_product(d1, d2, p.x, p.y);
|
||||
w1_row = cross_product(d2, d0, p.x, p.y);
|
||||
w2_row = cross_product(d0, d1, p.x, p.y);
|
||||
}
|
||||
|
||||
/* Handle anti-clockwise triangles */
|
||||
if (! is_clockwise) {
|
||||
d2d1_y *= -1;
|
||||
d0d2_y *= -1;
|
||||
d1d0_y *= -1;
|
||||
d1d2_x *= -1;
|
||||
d2d0_x *= -1;
|
||||
d0d1_x *= -1;
|
||||
w0_row *= -1;
|
||||
w1_row *= -1;
|
||||
w2_row *= -1;
|
||||
}
|
||||
|
||||
/* Add a bias to respect top-left rasterization rule */
|
||||
bias_w0 = (is_top_left(d1, d2, is_clockwise) ? 0 : -1);
|
||||
bias_w1 = (is_top_left(d2, d0, is_clockwise) ? 0 : -1);
|
||||
bias_w2 = (is_top_left(d0, d1, is_clockwise) ? 0 : -1);
|
||||
|
||||
/* precompute constant 's2->x * area' used in TRIANGLE_GET_TEXTCOORD */
|
||||
s2_x_area.x = s2->x * area;
|
||||
s2_x_area.y = s2->y * area;
|
||||
|
||||
if (blend != SDL_BLENDMODE_NONE || src->format->format != dst->format->format || has_modulation || ! is_uniform) {
|
||||
/* Use SDL_BlitTriangle_Slow */
|
||||
|
||||
SDL_BlitInfo *info = &src->map->info;
|
||||
SDL_BlitInfo tmp_info;
|
||||
|
||||
SDL_zero(tmp_info);
|
||||
|
||||
tmp_info.src_fmt = src->format;
|
||||
tmp_info.dst_fmt = dst->format;
|
||||
tmp_info.flags = info->flags;
|
||||
/*
|
||||
tmp_info.r = info->r;
|
||||
tmp_info.g = info->g;
|
||||
tmp_info.b = info->b;
|
||||
tmp_info.a = info->a;
|
||||
*/
|
||||
tmp_info.r = c0.r;
|
||||
tmp_info.g = c0.g;
|
||||
tmp_info.b = c0.b;
|
||||
tmp_info.a = c0.a;
|
||||
|
||||
|
||||
tmp_info.flags &= ~(SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA);
|
||||
|
||||
if (c0.r != 255 || c1.r != 255 || c2.r != 255 ||
|
||||
c0.g != 255 || c1.g != 255 || c2.g != 255 ||
|
||||
c0.b != 255 || c1.b != 255 || c2.b != 255) {
|
||||
tmp_info.flags |= SDL_COPY_MODULATE_COLOR;
|
||||
}
|
||||
|
||||
if (c0.a != 255 || c1.a != 255 || c2.a != 255) {
|
||||
tmp_info.flags |= SDL_COPY_MODULATE_ALPHA;
|
||||
}
|
||||
|
||||
tmp_info.colorkey = info->colorkey;
|
||||
|
||||
/* src */
|
||||
tmp_info.src = (Uint8 *) src_ptr;
|
||||
tmp_info.src_pitch = src_pitch;
|
||||
|
||||
/* dst */
|
||||
tmp_info.dst = (Uint8 *) dst_ptr;
|
||||
tmp_info.dst_pitch = dst_pitch;
|
||||
|
||||
SDL_BlitTriangle_Slow(&tmp_info, s2_x_area, dstrect, area, bias_w0, bias_w1, bias_w2,
|
||||
d2d1_y, d1d2_x, d0d2_y, d2d0_x, d1d0_y, d0d1_x,
|
||||
s2s0_x, s2s1_x, s2s0_y, s2s1_y, w0_row, w1_row, w2_row,
|
||||
c0, c1, c2, is_uniform);
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (dstbpp == 4) {
|
||||
TRIANGLE_BEGIN_LOOP
|
||||
{
|
||||
TRIANGLE_GET_TEXTCOORD
|
||||
Uint32 *sptr = (Uint32 *)((Uint8 *) src_ptr + srcy * src_pitch);
|
||||
*(Uint32 *)dptr = sptr[srcx];
|
||||
}
|
||||
TRIANGLE_END_LOOP
|
||||
} else if (dstbpp == 3) {
|
||||
TRIANGLE_BEGIN_LOOP
|
||||
{
|
||||
TRIANGLE_GET_TEXTCOORD
|
||||
Uint8 *sptr = (Uint8 *)((Uint8 *) src_ptr + srcy * src_pitch);
|
||||
dptr[0] = sptr[3 * srcx];
|
||||
dptr[1] = sptr[3 * srcx + 1];
|
||||
dptr[2] = sptr[3 * srcx + 2];
|
||||
}
|
||||
TRIANGLE_END_LOOP
|
||||
} else if (dstbpp == 2) {
|
||||
TRIANGLE_BEGIN_LOOP
|
||||
{
|
||||
TRIANGLE_GET_TEXTCOORD
|
||||
Uint16 *sptr = (Uint16 *)((Uint8 *) src_ptr + srcy * src_pitch);
|
||||
*(Uint16 *)dptr = sptr[srcx];
|
||||
}
|
||||
TRIANGLE_END_LOOP
|
||||
} else if (dstbpp == 1) {
|
||||
TRIANGLE_BEGIN_LOOP
|
||||
{
|
||||
TRIANGLE_GET_TEXTCOORD
|
||||
Uint8 *sptr = (Uint8 *)((Uint8 *) src_ptr + srcy * src_pitch);
|
||||
*dptr = sptr[srcx];
|
||||
}
|
||||
TRIANGLE_END_LOOP
|
||||
}
|
||||
|
||||
end:
|
||||
if (dst_locked) {
|
||||
SDL_UnlockSurface(dst);
|
||||
}
|
||||
if (src_locked) {
|
||||
SDL_UnlockSurface(src);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
SDL_BlitTriangle_Slow(SDL_BlitInfo *info,
|
||||
SDL_Point s2_x_area, SDL_Rect dstrect, int area, int bias_w0, int bias_w1, int bias_w2,
|
||||
int d2d1_y, int d1d2_x, int d0d2_y, int d2d0_x, int d1d0_y, int d0d1_x,
|
||||
int s2s0_x, int s2s1_x, int s2s0_y, int s2s1_y, int w0_row, int w1_row, int w2_row,
|
||||
SDL_Color c0, SDL_Color c1, SDL_Color c2, int is_uniform)
|
||||
{
|
||||
const int flags = info->flags;
|
||||
Uint32 modulateR = info->r;
|
||||
Uint32 modulateG = info->g;
|
||||
Uint32 modulateB = info->b;
|
||||
Uint32 modulateA = info->a;
|
||||
Uint32 srcpixel;
|
||||
Uint32 srcR, srcG, srcB, srcA;
|
||||
Uint32 dstpixel;
|
||||
Uint32 dstR, dstG, dstB, dstA;
|
||||
SDL_PixelFormat *src_fmt = info->src_fmt;
|
||||
SDL_PixelFormat *dst_fmt = info->dst_fmt;
|
||||
int srcbpp = src_fmt->BytesPerPixel;
|
||||
int dstbpp = dst_fmt->BytesPerPixel;
|
||||
Uint32 rgbmask = ~src_fmt->Amask;
|
||||
Uint32 ckey = info->colorkey & rgbmask;
|
||||
|
||||
Uint8 *dst_ptr = info->dst;
|
||||
int dst_pitch = info->dst_pitch;;
|
||||
|
||||
TRIANGLE_BEGIN_LOOP
|
||||
{
|
||||
Uint8 *src;
|
||||
Uint8 *dst = dptr;
|
||||
TRIANGLE_GET_TEXTCOORD
|
||||
src = (info->src + (srcy * info->src_pitch) + (srcx * srcbpp));
|
||||
if (src_fmt->Amask) {
|
||||
DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
|
||||
srcB, srcA);
|
||||
} else {
|
||||
DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
|
||||
srcB);
|
||||
srcA = 0xFF;
|
||||
}
|
||||
if (flags & SDL_COPY_COLORKEY) {
|
||||
/* srcpixel isn't set for 24 bpp */
|
||||
if (srcbpp == 3) {
|
||||
srcpixel = (srcR << src_fmt->Rshift) |
|
||||
(srcG << src_fmt->Gshift) | (srcB << src_fmt->Bshift);
|
||||
}
|
||||
if ((srcpixel & rgbmask) == ckey) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (dst_fmt->Amask) {
|
||||
DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
|
||||
dstB, dstA);
|
||||
} else {
|
||||
DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
|
||||
dstB);
|
||||
dstA = 0xFF;
|
||||
}
|
||||
|
||||
if (! is_uniform) {
|
||||
TRIANGLE_GET_COLOR
|
||||
modulateR = r;
|
||||
modulateG = g;
|
||||
modulateB = b;
|
||||
modulateA = a;
|
||||
}
|
||||
|
||||
if (flags & SDL_COPY_MODULATE_COLOR) {
|
||||
srcR = (srcR * modulateR) / 255;
|
||||
srcG = (srcG * modulateG) / 255;
|
||||
srcB = (srcB * modulateB) / 255;
|
||||
}
|
||||
if (flags & SDL_COPY_MODULATE_ALPHA) {
|
||||
srcA = (srcA * modulateA) / 255;
|
||||
}
|
||||
if (flags & (SDL_COPY_BLEND | SDL_COPY_ADD)) {
|
||||
/* This goes away if we ever use premultiplied alpha */
|
||||
if (srcA < 255) {
|
||||
srcR = (srcR * srcA) / 255;
|
||||
srcG = (srcG * srcA) / 255;
|
||||
srcB = (srcB * srcA) / 255;
|
||||
}
|
||||
}
|
||||
switch (flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_MUL)) {
|
||||
case 0:
|
||||
dstR = srcR;
|
||||
dstG = srcG;
|
||||
dstB = srcB;
|
||||
dstA = srcA;
|
||||
break;
|
||||
case SDL_COPY_BLEND:
|
||||
dstR = srcR + ((255 - srcA) * dstR) / 255;
|
||||
dstG = srcG + ((255 - srcA) * dstG) / 255;
|
||||
dstB = srcB + ((255 - srcA) * dstB) / 255;
|
||||
dstA = srcA + ((255 - srcA) * dstA) / 255;
|
||||
break;
|
||||
case SDL_COPY_ADD:
|
||||
dstR = srcR + dstR;
|
||||
if (dstR > 255)
|
||||
dstR = 255;
|
||||
dstG = srcG + dstG;
|
||||
if (dstG > 255)
|
||||
dstG = 255;
|
||||
dstB = srcB + dstB;
|
||||
if (dstB > 255)
|
||||
dstB = 255;
|
||||
break;
|
||||
case SDL_COPY_MOD:
|
||||
dstR = (srcR * dstR) / 255;
|
||||
dstG = (srcG * dstG) / 255;
|
||||
dstB = (srcB * dstB) / 255;
|
||||
break;
|
||||
case SDL_COPY_MUL:
|
||||
dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255;
|
||||
if (dstR > 255)
|
||||
dstR = 255;
|
||||
dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255;
|
||||
if (dstG > 255)
|
||||
dstG = 255;
|
||||
dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255;
|
||||
if (dstB > 255)
|
||||
dstB = 255;
|
||||
dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255;
|
||||
if (dstA > 255)
|
||||
dstA = 255;
|
||||
break;
|
||||
}
|
||||
if (dst_fmt->Amask) {
|
||||
ASSEMBLE_RGBA(dst, dstbpp, dst_fmt, dstR, dstG, dstB, dstA);
|
||||
} else {
|
||||
ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB);
|
||||
}
|
||||
}
|
||||
TRIANGLE_END_LOOP
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
42
externals/SDL/src/render/software/SDL_triangle.h
vendored
Executable file
42
externals/SDL/src/render/software/SDL_triangle.h
vendored
Executable 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: */
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
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
|
||||
@@ -81,24 +81,14 @@ static int VITA_GXM_QueueSetDrawColor(SDL_Renderer * renderer, SDL_RenderCommand
|
||||
static int VITA_GXM_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count);
|
||||
static int VITA_GXM_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count);
|
||||
|
||||
static int VITA_GXM_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
|
||||
const SDL_Rect * srcrect, const SDL_FRect * dstrect);
|
||||
|
||||
static int VITA_GXM_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
|
||||
const SDL_Rect * srcrect, const SDL_FRect * dstrect,
|
||||
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip);
|
||||
static int
|
||||
VITA_GXM_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);
|
||||
|
||||
static int VITA_GXM_RenderClear(SDL_Renderer *renderer, SDL_RenderCommand *cmd);
|
||||
|
||||
static int VITA_GXM_RenderDrawPoints(SDL_Renderer *renderer, const SDL_RenderCommand *cmd);
|
||||
|
||||
static int VITA_GXM_RenderDrawLines(SDL_Renderer *renderer, const SDL_RenderCommand *cmd);
|
||||
|
||||
static int VITA_GXM_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count);
|
||||
|
||||
static int VITA_GXM_RenderFillRects(SDL_Renderer *renderer, const SDL_RenderCommand *cmd);
|
||||
|
||||
|
||||
static int VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize);
|
||||
|
||||
static int VITA_GXM_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
|
||||
@@ -160,7 +150,6 @@ StartDrawing(SDL_Renderer *renderer)
|
||||
data->drawstate.vertex_program = NULL;
|
||||
data->drawstate.fragment_program = NULL;
|
||||
data->drawstate.last_command = -1;
|
||||
data->drawstate.texture_color = 0xFFFFFFFF;
|
||||
data->drawstate.viewport_dirty = SDL_TRUE;
|
||||
|
||||
// reset blend mode
|
||||
@@ -168,7 +157,6 @@ StartDrawing(SDL_Renderer *renderer)
|
||||
// fragment_programs *in = &data->blendFragmentPrograms.blend_mode_blend;
|
||||
// data->colorFragmentProgram = in->color;
|
||||
// data->textureFragmentProgram = in->texture;
|
||||
// data->textureTintFragmentProgram = in->textureTint;
|
||||
|
||||
if (renderer->target == NULL) {
|
||||
sceGxmBeginScene(
|
||||
@@ -201,6 +189,20 @@ StartDrawing(SDL_Renderer *renderer)
|
||||
data->drawing = SDL_TRUE;
|
||||
}
|
||||
|
||||
static int
|
||||
VITA_GXM_SetVSync(SDL_Renderer * renderer, const int vsync)
|
||||
{
|
||||
VITA_GXM_RenderData *data = renderer->driverdata;
|
||||
if (vsync) {
|
||||
data->displayData.wait_vblank = SDL_TRUE;
|
||||
renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
|
||||
} else {
|
||||
data->displayData.wait_vblank = SDL_FALSE;
|
||||
renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_Renderer *
|
||||
VITA_GXM_CreateRenderer(SDL_Window *window, Uint32 flags)
|
||||
{
|
||||
@@ -233,14 +235,13 @@ VITA_GXM_CreateRenderer(SDL_Window *window, Uint32 flags)
|
||||
renderer->QueueSetDrawColor = VITA_GXM_QueueSetDrawColor;
|
||||
renderer->QueueDrawPoints = VITA_GXM_QueueDrawPoints;
|
||||
renderer->QueueDrawLines = VITA_GXM_QueueDrawLines;
|
||||
renderer->QueueFillRects = VITA_GXM_QueueFillRects;
|
||||
renderer->QueueCopy = VITA_GXM_QueueCopy;
|
||||
renderer->QueueCopyEx = VITA_GXM_QueueCopyEx;
|
||||
renderer->QueueGeometry = VITA_GXM_QueueGeometry;
|
||||
renderer->RunCommandQueue = VITA_GXM_RunCommandQueue;
|
||||
renderer->RenderReadPixels = VITA_GXM_RenderReadPixels;
|
||||
renderer->RenderPresent = VITA_GXM_RenderPresent;
|
||||
renderer->DestroyTexture = VITA_GXM_DestroyTexture;
|
||||
renderer->DestroyRenderer = VITA_GXM_DestroyRenderer;
|
||||
renderer->SetVSync = VITA_GXM_SetVSync;
|
||||
|
||||
renderer->info = VITA_GXM_RenderDriver.info;
|
||||
renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
|
||||
@@ -349,12 +350,19 @@ static int
|
||||
VITA_GXM_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||
const SDL_Rect *rect, void **pixels, int *pitch)
|
||||
{
|
||||
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
|
||||
VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) texture->driverdata;
|
||||
|
||||
*pixels =
|
||||
(void *) ((Uint8 *) gxm_texture_get_datap(vita_texture->tex)
|
||||
+ (rect->y * vita_texture->pitch) + rect->x * SDL_BYTESPERPIXEL(texture->format));
|
||||
*pitch = vita_texture->pitch;
|
||||
|
||||
// make sure that rendering is finished on render target textures
|
||||
if (vita_texture->tex->gxm_rendertarget != NULL) {
|
||||
sceGxmFinish(data->gxm_context);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -419,7 +427,6 @@ VITA_GXM_SetBlendMode(VITA_GXM_RenderData *data, int blendMode)
|
||||
}
|
||||
data->colorFragmentProgram = in->color;
|
||||
data->textureFragmentProgram = in->texture;
|
||||
data->textureTintFragmentProgram = in->textureTint;
|
||||
data->currentBlendMode = blendMode;
|
||||
}
|
||||
}
|
||||
@@ -439,7 +446,7 @@ VITA_GXM_QueueSetDrawColor(SDL_Renderer * renderer, SDL_RenderCommand *cmd)
|
||||
const Uint8 g = cmd->data.color.g;
|
||||
const Uint8 b = cmd->data.color.b;
|
||||
const Uint8 a = cmd->data.color.a;
|
||||
data->drawstate.color = ((a << 24) | (b << 16) | (g << 8) | r);
|
||||
data->drawstate.color = (((Uint32)a << 24) | (b << 16) | (g << 8) | r);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -451,10 +458,9 @@ VITA_GXM_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const
|
||||
|
||||
int color = data->drawstate.color;
|
||||
|
||||
color_vertex *vertex = (color_vertex *)pool_memalign(
|
||||
color_vertex *vertex = (color_vertex *)pool_malloc(
|
||||
data,
|
||||
count * sizeof(color_vertex),
|
||||
sizeof(color_vertex)
|
||||
count * sizeof(color_vertex)
|
||||
);
|
||||
|
||||
cmd->data.draw.first = (size_t)vertex;
|
||||
@@ -464,7 +470,6 @@ VITA_GXM_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const
|
||||
{
|
||||
vertex[i].x = points[i].x;
|
||||
vertex[i].y = points[i].y;
|
||||
vertex[i].z = +0.5f;
|
||||
vertex[i].color = color;
|
||||
}
|
||||
|
||||
@@ -477,10 +482,9 @@ VITA_GXM_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const S
|
||||
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
|
||||
int color = data->drawstate.color;
|
||||
|
||||
color_vertex *vertex = (color_vertex *)pool_memalign(
|
||||
color_vertex *vertex = (color_vertex *)pool_malloc(
|
||||
data,
|
||||
(count-1) * 2 * sizeof(color_vertex),
|
||||
sizeof(color_vertex)
|
||||
(count-1) * 2 * sizeof(color_vertex)
|
||||
);
|
||||
|
||||
cmd->data.draw.first = (size_t)vertex;
|
||||
@@ -490,12 +494,10 @@ VITA_GXM_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const S
|
||||
{
|
||||
vertex[i*2].x = points[i].x;
|
||||
vertex[i*2].y = points[i].y;
|
||||
vertex[i*2].z = +0.5f;
|
||||
vertex[i*2].color = color;
|
||||
|
||||
vertex[i*2+1].x = points[i+1].x;
|
||||
vertex[i*2+1].y = points[i+1].y;
|
||||
vertex[i*2+1].z = +0.5f;
|
||||
vertex[i*2+1].color = color;
|
||||
}
|
||||
|
||||
@@ -503,192 +505,98 @@ VITA_GXM_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const S
|
||||
}
|
||||
|
||||
static int
|
||||
VITA_GXM_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count)
|
||||
VITA_GXM_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)
|
||||
{
|
||||
int color;
|
||||
color_vertex *vertices;
|
||||
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
|
||||
int i;
|
||||
int count = indices ? num_indices : num_vertices;
|
||||
|
||||
cmd->data.draw.count = count;
|
||||
color = data->drawstate.color;
|
||||
size_indices = indices ? size_indices : 0;
|
||||
|
||||
vertices = (color_vertex *)pool_memalign(
|
||||
data,
|
||||
4 * count * sizeof(color_vertex), // 4 vertices * count
|
||||
sizeof(color_vertex));
|
||||
if (texture) {
|
||||
texture_vertex *vertices;
|
||||
|
||||
for (int i =0; i < count; i++)
|
||||
{
|
||||
const SDL_FRect *rect = &rects[i];
|
||||
vertices = (texture_vertex *)pool_malloc(
|
||||
data,
|
||||
count * sizeof(texture_vertex));
|
||||
|
||||
vertices[4*i+0].x = rect->x;
|
||||
vertices[4*i+0].y = rect->y;
|
||||
vertices[4*i+0].z = +0.5f;
|
||||
vertices[4*i+0].color = color;
|
||||
if (!vertices) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
vertices[4*i+1].x = rect->x + rect->w;
|
||||
vertices[4*i+1].y = rect->y;
|
||||
vertices[4*i+1].z = +0.5f;
|
||||
vertices[4*i+1].color = color;
|
||||
|
||||
vertices[4*i+2].x = rect->x;
|
||||
vertices[4*i+2].y = rect->y + rect->h;
|
||||
vertices[4*i+2].z = +0.5f;
|
||||
vertices[4*i+2].color = color;
|
||||
for (i = 0; i < count; i++) {
|
||||
int j;
|
||||
float *xy_;
|
||||
float *uv_;
|
||||
int 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;
|
||||
}
|
||||
|
||||
vertices[4*i+3].x = rect->x + rect->w;
|
||||
vertices[4*i+3].y = rect->y + rect->h;
|
||||
vertices[4*i+3].z = +0.5f;
|
||||
vertices[4*i+3].color = color;
|
||||
}
|
||||
xy_ = (float *)((char*)xy + j * xy_stride);
|
||||
col_ = *(int *)((char*)color + j * color_stride);
|
||||
uv_ = (float *)((char*)uv + j * uv_stride);
|
||||
|
||||
cmd->data.draw.first = (size_t)vertices;
|
||||
vertices[i].x = xy_[0] * scale_x;
|
||||
vertices[i].y = xy_[1] * scale_y;
|
||||
vertices[i].u = uv_[0];
|
||||
vertices[i].v = uv_[1];
|
||||
vertices[i].color = col_;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
cmd->data.draw.first = (size_t)vertices;
|
||||
|
||||
#define degToRad(x) ((x)*M_PI/180.f)
|
||||
|
||||
void MathSincos(float r, float *s, float *c)
|
||||
{
|
||||
*s = SDL_sin(r);
|
||||
*c = SDL_cos(r);
|
||||
}
|
||||
|
||||
static int
|
||||
VITA_GXM_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
|
||||
const SDL_Rect * srcrect, const SDL_FRect * dstrect)
|
||||
{
|
||||
texture_vertex *vertices;
|
||||
float u0, v0, u1, v1;
|
||||
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
|
||||
|
||||
cmd->data.draw.count = 1;
|
||||
|
||||
vertices = (texture_vertex *)pool_memalign(
|
||||
data,
|
||||
4 * sizeof(texture_vertex), // 4 vertices
|
||||
sizeof(texture_vertex));
|
||||
|
||||
cmd->data.draw.first = (size_t)vertices;
|
||||
cmd->data.draw.texture = texture;
|
||||
|
||||
u0 = (float)srcrect->x / (float)texture->w;
|
||||
v0 = (float)srcrect->y / (float)texture->h;
|
||||
u1 = (float)(srcrect->x + srcrect->w) / (float)texture->w;
|
||||
v1 = (float)(srcrect->y + srcrect->h) / (float)texture->h;
|
||||
|
||||
vertices[0].x = dstrect->x;
|
||||
vertices[0].y = dstrect->y;
|
||||
vertices[0].z = +0.5f;
|
||||
vertices[0].u = u0;
|
||||
vertices[0].v = v0;
|
||||
|
||||
vertices[1].x = dstrect->x + dstrect->w;
|
||||
vertices[1].y = dstrect->y;
|
||||
vertices[1].z = +0.5f;
|
||||
vertices[1].u = u1;
|
||||
vertices[1].v = v0;
|
||||
|
||||
vertices[2].x = dstrect->x;
|
||||
vertices[2].y = dstrect->y + dstrect->h;
|
||||
vertices[2].z = +0.5f;
|
||||
vertices[2].u = u0;
|
||||
vertices[2].v = v1;
|
||||
|
||||
vertices[3].x = dstrect->x + dstrect->w;
|
||||
vertices[3].y = dstrect->y + dstrect->h;
|
||||
vertices[3].z = +0.5f;
|
||||
vertices[3].u = u1;
|
||||
vertices[3].v = v1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
VITA_GXM_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
|
||||
const SDL_Rect * srcrect, const SDL_FRect * dstrect,
|
||||
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
|
||||
{
|
||||
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
|
||||
|
||||
texture_vertex *vertices;
|
||||
float u0, v0, u1, v1;
|
||||
float x0, y0, x1, y1;
|
||||
float s, c;
|
||||
const float centerx = center->x + dstrect->x;
|
||||
const float centery = center->y + dstrect->y;
|
||||
|
||||
cmd->data.draw.count = 1;
|
||||
|
||||
vertices = (texture_vertex *)pool_memalign(
|
||||
data,
|
||||
4 * sizeof(texture_vertex), // 4 vertices
|
||||
sizeof(texture_vertex));
|
||||
|
||||
cmd->data.draw.first = (size_t)vertices;
|
||||
cmd->data.draw.texture = texture;
|
||||
|
||||
if (flip & SDL_FLIP_HORIZONTAL) {
|
||||
x0 = dstrect->x + dstrect->w;
|
||||
x1 = dstrect->x;
|
||||
} else {
|
||||
x0 = dstrect->x;
|
||||
x1 = dstrect->x + dstrect->w;
|
||||
color_vertex *vertices;
|
||||
|
||||
vertices = (color_vertex *)pool_malloc(
|
||||
data,
|
||||
count * sizeof(color_vertex));
|
||||
|
||||
if (!vertices) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
int j;
|
||||
float *xy_;
|
||||
int 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_ = *(int *)((char*)color + j * color_stride);
|
||||
|
||||
vertices[i].x = xy_[0] * scale_x;
|
||||
vertices[i].y = xy_[1] * scale_y;
|
||||
vertices[i].color = col_;
|
||||
}
|
||||
cmd->data.draw.first = (size_t)vertices;
|
||||
}
|
||||
|
||||
if (flip & SDL_FLIP_VERTICAL) {
|
||||
y0 = dstrect->y + dstrect->h;
|
||||
y1 = dstrect->y;
|
||||
} else {
|
||||
y0 = dstrect->y;
|
||||
y1 = dstrect->y + dstrect->h;
|
||||
}
|
||||
|
||||
u0 = (float)srcrect->x / (float)texture->w;
|
||||
v0 = (float)srcrect->y / (float)texture->h;
|
||||
u1 = (float)(srcrect->x + srcrect->w) / (float)texture->w;
|
||||
v1 = (float)(srcrect->y + srcrect->h) / (float)texture->h;
|
||||
|
||||
MathSincos(degToRad(angle), &s, &c);
|
||||
|
||||
vertices[0].x = x0 - centerx;
|
||||
vertices[0].y = y0 - centery;
|
||||
vertices[0].z = +0.5f;
|
||||
vertices[0].u = u0;
|
||||
vertices[0].v = v0;
|
||||
|
||||
vertices[1].x = x1 - centerx;
|
||||
vertices[1].y = y0 - centery;
|
||||
vertices[1].z = +0.5f;
|
||||
vertices[1].u = u1;
|
||||
vertices[1].v = v0;
|
||||
|
||||
|
||||
vertices[2].x = x0 - centerx;
|
||||
vertices[2].y = y1 - centery;
|
||||
vertices[2].z = +0.5f;
|
||||
vertices[2].u = u0;
|
||||
vertices[2].v = v1;
|
||||
|
||||
vertices[3].x = x1 - centerx;
|
||||
vertices[3].y = y1 - centery;
|
||||
vertices[3].z = +0.5f;
|
||||
vertices[3].u = u1;
|
||||
vertices[3].v = v1;
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
float _x = vertices[i].x;
|
||||
float _y = vertices[i].y;
|
||||
vertices[i].x = _x * c - _y * s + centerx;
|
||||
vertices[i].y = _x * s + _y * c + centery;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
VITA_GXM_RenderClear(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
{
|
||||
@@ -723,43 +631,7 @@ VITA_GXM_RenderClear(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
|
||||
|
||||
static int
|
||||
VITA_GXM_RenderDrawPoints(SDL_Renderer *renderer, const SDL_RenderCommand *cmd)
|
||||
{
|
||||
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
|
||||
|
||||
sceGxmSetFrontPolygonMode(data->gxm_context, SCE_GXM_POLYGON_MODE_POINT);
|
||||
sceGxmDraw(data->gxm_context, SCE_GXM_PRIMITIVE_POINTS, SCE_GXM_INDEX_FORMAT_U16, data->linearIndices, cmd->data.draw.count);
|
||||
sceGxmSetFrontPolygonMode(data->gxm_context, SCE_GXM_POLYGON_MODE_TRIANGLE_FILL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
VITA_GXM_RenderDrawLines(SDL_Renderer *renderer, const SDL_RenderCommand *cmd)
|
||||
{
|
||||
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
|
||||
|
||||
sceGxmSetFrontPolygonMode(data->gxm_context, SCE_GXM_POLYGON_MODE_LINE);
|
||||
sceGxmDraw(data->gxm_context, SCE_GXM_PRIMITIVE_LINES, SCE_GXM_INDEX_FORMAT_U16, data->linearIndices, cmd->data.draw.count);
|
||||
sceGxmSetFrontPolygonMode(data->gxm_context, SCE_GXM_POLYGON_MODE_TRIANGLE_FILL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
VITA_GXM_RenderFillRects(SDL_Renderer *renderer, const SDL_RenderCommand *cmd)
|
||||
{
|
||||
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
|
||||
|
||||
sceGxmSetVertexStream(data->gxm_context, 0, (const void*)cmd->data.draw.first);
|
||||
sceGxmDraw(data->gxm_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, data->linearIndices, 4 * cmd->data.draw.count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd, SDL_bool solid)
|
||||
SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd)
|
||||
{
|
||||
SDL_Texture *texture = cmd->data.draw.texture;
|
||||
const SDL_BlendMode blend = cmd->data.draw.blend;
|
||||
@@ -767,13 +639,6 @@ SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd, SDL_bool s
|
||||
SceGxmVertexProgram *vertex_program;
|
||||
SDL_bool matrix_updated = SDL_FALSE;
|
||||
SDL_bool program_updated = SDL_FALSE;
|
||||
Uint32 texture_color;
|
||||
|
||||
Uint8 r, g, b, a;
|
||||
r = cmd->data.draw.r;
|
||||
g = cmd->data.draw.g;
|
||||
b = cmd->data.draw.b;
|
||||
a = cmd->data.draw.a;
|
||||
|
||||
if (data->drawstate.viewport_dirty) {
|
||||
const SDL_Rect *viewport = &data->drawstate.viewport;
|
||||
@@ -819,11 +684,7 @@ SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd, SDL_bool s
|
||||
|
||||
if (texture) {
|
||||
vertex_program = data->textureVertexProgram;
|
||||
if(cmd->data.draw.r == 255 && cmd->data.draw.g == 255 && cmd->data.draw.b == 255 && cmd->data.draw.a == 255) {
|
||||
fragment_program = data->textureFragmentProgram;
|
||||
} else {
|
||||
fragment_program = data->textureTintFragmentProgram;
|
||||
}
|
||||
fragment_program = data->textureFragmentProgram;
|
||||
} else {
|
||||
vertex_program = data->colorVertexProgram;
|
||||
fragment_program = data->colorFragmentProgram;
|
||||
@@ -841,58 +702,17 @@ SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd, SDL_bool s
|
||||
program_updated = SDL_TRUE;
|
||||
}
|
||||
|
||||
texture_color = ((a << 24) | (b << 16) | (g << 8) | r);
|
||||
|
||||
if (program_updated || matrix_updated) {
|
||||
if (data->drawstate.fragment_program == data->textureFragmentProgram) {
|
||||
void *vertex_wvp_buffer;
|
||||
sceGxmReserveVertexDefaultUniformBuffer(data->gxm_context, &vertex_wvp_buffer);
|
||||
sceGxmSetUniformDataF(vertex_wvp_buffer, data->textureWvpParam, 0, 16, data->ortho_matrix);
|
||||
} else if (data->drawstate.fragment_program == data->textureTintFragmentProgram) {
|
||||
void *vertex_wvp_buffer;
|
||||
void *texture_tint_color_buffer;
|
||||
float *tint_color;
|
||||
sceGxmReserveVertexDefaultUniformBuffer(data->gxm_context, &vertex_wvp_buffer);
|
||||
sceGxmSetUniformDataF(vertex_wvp_buffer, data->textureWvpParam, 0, 16, data->ortho_matrix);
|
||||
|
||||
sceGxmReserveFragmentDefaultUniformBuffer(data->gxm_context, &texture_tint_color_buffer);
|
||||
|
||||
tint_color = pool_memalign(
|
||||
data,
|
||||
4 * sizeof(float), // RGBA
|
||||
sizeof(float)
|
||||
);
|
||||
|
||||
tint_color[0] = r / 255.0f;
|
||||
tint_color[1] = g / 255.0f;
|
||||
tint_color[2] = b / 255.0f;
|
||||
tint_color[3] = a / 255.0f;
|
||||
sceGxmSetUniformDataF(texture_tint_color_buffer, data->textureTintColorParam, 0, 4, tint_color);
|
||||
data->drawstate.texture_color = texture_color;
|
||||
} else { // color
|
||||
void *vertexDefaultBuffer;
|
||||
sceGxmReserveVertexDefaultUniformBuffer(data->gxm_context, &vertexDefaultBuffer);
|
||||
sceGxmSetUniformDataF(vertexDefaultBuffer, data->colorWvpParam, 0, 16, data->ortho_matrix);
|
||||
}
|
||||
} else {
|
||||
if (data->drawstate.fragment_program == data->textureTintFragmentProgram && data->drawstate.texture_color != texture_color) {
|
||||
void *texture_tint_color_buffer;
|
||||
float *tint_color;
|
||||
sceGxmReserveFragmentDefaultUniformBuffer(data->gxm_context, &texture_tint_color_buffer);
|
||||
|
||||
tint_color = pool_memalign(
|
||||
data,
|
||||
4 * sizeof(float), // RGBA
|
||||
sizeof(float)
|
||||
);
|
||||
|
||||
tint_color[0] = r / 255.0f;
|
||||
tint_color[1] = g / 255.0f;
|
||||
tint_color[2] = b / 255.0f;
|
||||
tint_color[3] = a / 255.0f;
|
||||
sceGxmSetUniformDataF(texture_tint_color_buffer, data->textureTintColorParam, 0, 4, tint_color);
|
||||
data->drawstate.texture_color = texture_color;
|
||||
}
|
||||
}
|
||||
|
||||
if (texture != data->drawstate.texture) {
|
||||
@@ -914,7 +734,7 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd)
|
||||
{
|
||||
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
|
||||
|
||||
return SetDrawState(data, cmd, SDL_FALSE);
|
||||
return SetDrawState(data, cmd);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -925,7 +745,15 @@ VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *
|
||||
|
||||
data->drawstate.target = renderer->target;
|
||||
if (!data->drawstate.target) {
|
||||
SDL_GL_GetDrawableSize(renderer->window, &data->drawstate.drawablew, &data->drawstate.drawableh);
|
||||
int w, h;
|
||||
SDL_GL_GetDrawableSize(renderer->window, &w, &h);
|
||||
if ((w != data->drawstate.drawablew) || (h != data->drawstate.drawableh)) {
|
||||
data->drawstate.viewport_dirty = SDL_TRUE; // if the window dimensions changed, invalidate the current viewport, etc.
|
||||
data->drawstate.cliprect_dirty = SDL_TRUE;
|
||||
data->drawstate.drawablew = w;
|
||||
data->drawstate.drawableh = h;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
while (cmd) {
|
||||
@@ -963,29 +791,64 @@ VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_DRAW_POINTS: {
|
||||
SetDrawState(data, cmd, SDL_FALSE);
|
||||
VITA_GXM_RenderDrawPoints(renderer, cmd);
|
||||
case SDL_RENDERCMD_FILL_RECTS: /* unused */
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_DRAW_LINES: {
|
||||
SetDrawState(data, cmd, SDL_FALSE);
|
||||
VITA_GXM_RenderDrawLines(renderer, cmd);
|
||||
case SDL_RENDERCMD_COPY: /* unused */
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_FILL_RECTS: {
|
||||
SetDrawState(data, cmd, SDL_FALSE);
|
||||
VITA_GXM_RenderFillRects(renderer, cmd);
|
||||
case SDL_RENDERCMD_COPY_EX: /* unused */
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_COPY:
|
||||
case SDL_RENDERCMD_COPY_EX: {
|
||||
SetCopyState(renderer, cmd);
|
||||
sceGxmDraw(data->gxm_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, data->linearIndices, 4 * cmd->data.draw.count);
|
||||
case SDL_RENDERCMD_DRAW_POINTS:
|
||||
case SDL_RENDERCMD_DRAW_LINES:
|
||||
case SDL_RENDERCMD_GEOMETRY: {
|
||||
SDL_Texture *thistexture = cmd->data.draw.texture;
|
||||
SDL_BlendMode thisblend = cmd->data.draw.blend;
|
||||
const SDL_RenderCommandType thiscmdtype = cmd->command;
|
||||
SDL_RenderCommand *finalcmd = cmd;
|
||||
SDL_RenderCommand *nextcmd = cmd->next;
|
||||
size_t count = cmd->data.draw.count;
|
||||
int ret;
|
||||
while (nextcmd != NULL) {
|
||||
const SDL_RenderCommandType nextcmdtype = nextcmd->command;
|
||||
if (nextcmdtype != thiscmdtype) {
|
||||
break; /* can't go any further on this draw call, different render command up next. */
|
||||
} else if (nextcmd->data.draw.texture != thistexture || nextcmd->data.draw.blend != thisblend) {
|
||||
break; /* can't go any further on this draw call, different texture/blendmode copy up next. */
|
||||
} else {
|
||||
finalcmd = nextcmd; /* we can combine copy operations here. Mark this one as the furthest okay command. */
|
||||
count += cmd->data.draw.count;
|
||||
}
|
||||
nextcmd = nextcmd->next;
|
||||
}
|
||||
|
||||
if (thistexture) {
|
||||
ret = SetCopyState(renderer, cmd);
|
||||
} else {
|
||||
ret = SetDrawState(data, cmd);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
int op = SCE_GXM_PRIMITIVE_TRIANGLES;
|
||||
|
||||
if (thiscmdtype == SDL_RENDERCMD_DRAW_POINTS) {
|
||||
sceGxmSetFrontPolygonMode(data->gxm_context, SCE_GXM_POLYGON_MODE_POINT);
|
||||
op = SCE_GXM_PRIMITIVE_POINTS;
|
||||
} else if (thiscmdtype == SDL_RENDERCMD_DRAW_LINES) {
|
||||
sceGxmSetFrontPolygonMode(data->gxm_context, SCE_GXM_POLYGON_MODE_LINE);
|
||||
op = SCE_GXM_PRIMITIVE_LINES;
|
||||
}
|
||||
|
||||
sceGxmDraw(data->gxm_context, op, SCE_GXM_INDEX_FORMAT_U16, data->linearIndices, count);
|
||||
|
||||
if (thiscmdtype == SDL_RENDERCMD_DRAW_POINTS || thiscmdtype == SDL_RENDERCMD_DRAW_LINES) {
|
||||
sceGxmSetFrontPolygonMode(data->gxm_context, SCE_GXM_POLYGON_MODE_TRIANGLE_FILL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cmd = finalcmd; /* skip any copy commands we just combined in here. */
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -996,6 +859,9 @@ VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *
|
||||
cmd = cmd->next;
|
||||
}
|
||||
|
||||
sceGxmEndScene(data->gxm_context, NULL, NULL);
|
||||
data->drawing = SDL_FALSE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1091,13 +957,6 @@ VITA_GXM_RenderPresent(SDL_Renderer *renderer)
|
||||
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
|
||||
SceCommonDialogUpdateParam updateParam;
|
||||
|
||||
if (data->drawing) {
|
||||
sceGxmEndScene(data->gxm_context, NULL, NULL);
|
||||
if (data->displayData.wait_vblank) {
|
||||
sceGxmFinish(data->gxm_context);
|
||||
}
|
||||
}
|
||||
|
||||
data->displayData.address = data->displayBufferData[data->backBufferIndex];
|
||||
|
||||
SDL_memset(&updateParam, 0, sizeof(updateParam));
|
||||
@@ -1134,8 +993,6 @@ VITA_GXM_RenderPresent(SDL_Renderer *renderer)
|
||||
data->pool_index = 0;
|
||||
|
||||
data->current_pool = (data->current_pool + 1) % 2;
|
||||
|
||||
data->drawing = SDL_FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
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
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
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
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
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
|
||||
@@ -124,37 +124,39 @@ static const unsigned char gxm_shader_color_f[gxm_shader_color_f_size] = {
|
||||
0x7e, 0x0d, 0x80, 0x40,
|
||||
};
|
||||
|
||||
#define gxm_shader_color_v_size 352
|
||||
#define gxm_shader_color_v_size 368
|
||||
static const unsigned char gxm_shader_color_v[gxm_shader_color_v_size] = {
|
||||
0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03,
|
||||
0x5d, 0x01, 0x00, 0x00, 0x4a, 0xb6, 0x4f, 0x7b,
|
||||
0x51, 0x19, 0x1a, 0xae, 0x00, 0x00, 0x19, 0x00,
|
||||
0x6d, 0x01, 0x00, 0x00, 0x09, 0xce, 0x4e, 0xc2,
|
||||
0xe1, 0xcd, 0x24, 0xbc, 0x00, 0x00, 0x19, 0x00,
|
||||
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0xf0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
|
||||
0x08, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x74, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00,
|
||||
0x98, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x74, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||
0xa8, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00,
|
||||
0xb8, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x06, 0x43, 0x00, 0x61,
|
||||
0x86, 0x81, 0xa2, 0x00, 0x07, 0x53, 0x40, 0x61,
|
||||
0x86, 0x81, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x40, 0x01, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, 0xfa,
|
||||
0x80, 0x00, 0x08, 0x83, 0x21, 0x1d, 0x80, 0x38,
|
||||
0x02, 0x80, 0x81, 0xaf, 0x9c, 0x0d, 0xc0, 0x40,
|
||||
0x0e, 0x86, 0xb9, 0xff, 0xbc, 0x0d, 0xc0, 0x40,
|
||||
0x04, 0x11, 0x49, 0xcf, 0x80, 0x8f, 0xb1, 0x18,
|
||||
0x00, 0x00, 0xf0, 0x83, 0x20, 0x0d, 0x80, 0x38,
|
||||
0x0a, 0x84, 0xb9, 0xff, 0xbc, 0x0d, 0xc0, 0x40,
|
||||
0x02, 0x11, 0x45, 0xcf, 0x80, 0x8f, 0xb1, 0x18,
|
||||
0x00, 0x11, 0x01, 0xc0, 0x81, 0x81, 0xb1, 0x18,
|
||||
0x01, 0xd1, 0x42, 0xc0, 0x81, 0x81, 0xb1, 0x18,
|
||||
@@ -172,142 +174,106 @@ static const unsigned char gxm_shader_color_v[gxm_shader_color_v_size] = {
|
||||
0x00, 0x77, 0x76, 0x70, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
#define gxm_shader_texture_f_size 256
|
||||
#define gxm_shader_texture_f_size 288
|
||||
static const unsigned char gxm_shader_texture_f[gxm_shader_texture_f_size] = {
|
||||
0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03,
|
||||
0x00, 0x01, 0x00, 0x00, 0x2f, 0x18, 0xe0, 0x2b,
|
||||
0x1f, 0x21, 0x47, 0x49, 0x01, 0x08, 0x18, 0x00,
|
||||
0x20, 0x01, 0x00, 0x00, 0xeb, 0x4f, 0xb5, 0xba,
|
||||
0x60, 0xb2, 0xd0, 0x8d, 0x05, 0x18, 0x18, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0xa4, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0xc4, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00,
|
||||
0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x78, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x64, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00,
|
||||
0x84, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
|
||||
0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04,
|
||||
0x01, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x40, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||
0x00, 0xa9, 0xd0, 0x0e, 0x00, 0x00, 0x00, 0x00,
|
||||
0xf0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x07, 0x44, 0xfa, 0x30, 0x00, 0x00, 0x00,
|
||||
0x02, 0x04, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00,
|
||||
0x00, 0x07, 0x44, 0xfa, 0x00, 0x00, 0x00, 0x00,
|
||||
0x40, 0x09, 0x00, 0xf8, 0x02, 0x80, 0x99, 0xaf,
|
||||
0xbc, 0x0d, 0xc0, 0x40, 0x06, 0x82, 0xb9, 0xaf,
|
||||
0xbc, 0x0d, 0x80, 0x40, 0x7c, 0x0f, 0x04, 0x00,
|
||||
0x86, 0x47, 0xa4, 0x10, 0x30, 0x00, 0x00, 0x00,
|
||||
0x02, 0x04, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x00,
|
||||
};
|
||||
|
||||
#define gxm_shader_texture_tint_f_size 324
|
||||
static const unsigned char gxm_shader_texture_tint_f[gxm_shader_texture_tint_f_size] = {
|
||||
0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03,
|
||||
0x43, 0x01, 0x00, 0x00, 0x44, 0x2f, 0x5d, 0xfe,
|
||||
0x9e, 0xda, 0xf8, 0x6f, 0x05, 0x08, 0x18, 0x00,
|
||||
0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0xcc, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
|
||||
0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00,
|
||||
0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x78, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
0x84, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00,
|
||||
0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04,
|
||||
0x01, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xc0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x07, 0x44, 0xfa, 0x00, 0x00, 0x00, 0x00,
|
||||
0x40, 0x09, 0x00, 0xf8, 0x02, 0x80, 0x99, 0xff,
|
||||
0xbc, 0x0d, 0xc0, 0x40, 0x02, 0x80, 0xb9, 0xaf,
|
||||
0xbc, 0x0d, 0x80, 0x40, 0x7c, 0x0f, 0x04, 0x00,
|
||||
0x86, 0x47, 0xa4, 0x10, 0x0e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x04, 0x00, 0x40, 0x00, 0x00, 0x00,
|
||||
0x01, 0xe4, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00,
|
||||
0x02, 0x04, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x75, 0x54, 0x69, 0x6e,
|
||||
0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x74,
|
||||
0x65, 0x78, 0x00, 0x00,
|
||||
};
|
||||
|
||||
#define gxm_shader_texture_v_size 344
|
||||
#define gxm_shader_texture_v_size 400
|
||||
static const unsigned char gxm_shader_texture_v[gxm_shader_texture_v_size] = {
|
||||
0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03,
|
||||
0x58, 0x01, 0x00, 0x00, 0xa3, 0x36, 0x7b, 0x62,
|
||||
0x1b, 0x80, 0x1c, 0xb0, 0x00, 0x00, 0x19, 0x00,
|
||||
0x8f, 0x01, 0x00, 0x00, 0x60, 0x1e, 0x69, 0x97,
|
||||
0x82, 0x7e, 0x0c, 0xac, 0x00, 0x00, 0x19, 0x00,
|
||||
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0xe8, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
|
||||
0x08, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x74, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
0x08, 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
|
||||
0x0c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00,
|
||||
0x98, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x74, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||
0xa0, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00,
|
||||
0xc0, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x33, 0x0f, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x06,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x0a,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x06, 0x43, 0x00, 0x61,
|
||||
0x86, 0x81, 0xa2, 0x00, 0x07, 0x53, 0x40, 0x61,
|
||||
0x86, 0x81, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x40, 0x01, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, 0xfa,
|
||||
0x80, 0x00, 0x08, 0x83, 0x21, 0x0d, 0x80, 0x38,
|
||||
0x02, 0x80, 0x81, 0xaf, 0x9c, 0x0d, 0xc0, 0x40,
|
||||
0x0e, 0x86, 0xb9, 0xff, 0xbc, 0x0d, 0xc0, 0x40,
|
||||
0x04, 0x11, 0x49, 0xcf, 0x80, 0x8f, 0xb1, 0x18,
|
||||
0x01, 0x0e, 0x01, 0x01, 0x02, 0x00, 0x10, 0xfa,
|
||||
0x80, 0x00, 0x08, 0x83, 0x21, 0x25, 0x80, 0x38,
|
||||
0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x14, 0xfa,
|
||||
0x00, 0x00, 0xf0, 0x83, 0x20, 0x0d, 0x80, 0x38,
|
||||
0x0a, 0x84, 0xb9, 0xff, 0xbc, 0x0d, 0xc0, 0x40,
|
||||
0x02, 0x11, 0x45, 0xcf, 0x80, 0x8f, 0xb1, 0x18,
|
||||
0x00, 0x11, 0x01, 0xc0, 0x81, 0x81, 0xb1, 0x18,
|
||||
0x01, 0xd1, 0x42, 0xc0, 0x81, 0x81, 0xb1, 0x18,
|
||||
0x00, 0x00, 0x20, 0xa0, 0x00, 0x50, 0x27, 0xfb,
|
||||
0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
|
||||
0x30, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
|
||||
0x40, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x2a, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
|
||||
0x3a, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
0x24, 0x00, 0x00, 0x00, 0x01, 0xe4, 0x00, 0x00,
|
||||
0x34, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
|
||||
0x2b, 0x00, 0x00, 0x00, 0x01, 0xe4, 0x00, 0x00,
|
||||
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x61, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x00, 0x61, 0x54, 0x65, 0x78, 0x63, 0x6f,
|
||||
0x6f, 0x72, 0x64, 0x00, 0x77, 0x76, 0x70, 0x00,
|
||||
0x6f, 0x72, 0x64, 0x00, 0x61, 0x43, 0x6f, 0x6c,
|
||||
0x6f, 0x72, 0x00, 0x77, 0x76, 0x70, 0x00, 0x00,
|
||||
};
|
||||
|
||||
|
||||
static const SceGxmProgram *const clearVertexProgramGxp = (const SceGxmProgram*)gxm_shader_clear_v;
|
||||
static const SceGxmProgram *const clearVertexProgramGxp = (const SceGxmProgram *)gxm_shader_clear_v;
|
||||
static const SceGxmProgram *const clearFragmentProgramGxp = (const SceGxmProgram *)gxm_shader_clear_f;
|
||||
static const SceGxmProgram *const colorVertexProgramGxp = (const SceGxmProgram *)gxm_shader_color_v;
|
||||
static const SceGxmProgram *const colorFragmentProgramGxp = (const SceGxmProgram *)gxm_shader_color_f;
|
||||
static const SceGxmProgram *const textureVertexProgramGxp = (const SceGxmProgram *)gxm_shader_texture_v;
|
||||
static const SceGxmProgram *const textureFragmentProgramGxp = (const SceGxmProgram *)gxm_shader_texture_f;
|
||||
static const SceGxmProgram *const textureTintFragmentProgramGxp = (const SceGxmProgram *)gxm_shader_texture_tint_f;
|
||||
|
||||
#endif // SDL_RENDER_VITA_GXM_SHADERS_H
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
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
|
||||
@@ -164,7 +164,6 @@ free_fragment_programs(VITA_GXM_RenderData *data, fragment_programs *out)
|
||||
{
|
||||
sceGxmShaderPatcherReleaseFragmentProgram(data->shaderPatcher, out->color);
|
||||
sceGxmShaderPatcherReleaseFragmentProgram(data->shaderPatcher, out->texture);
|
||||
sceGxmShaderPatcherReleaseFragmentProgram(data->shaderPatcher, out->textureTint);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -202,21 +201,6 @@ make_fragment_programs(VITA_GXM_RenderData *data, fragment_programs *out,
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Patcher create fragment failed: %d\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
err = sceGxmShaderPatcherCreateFragmentProgram(
|
||||
data->shaderPatcher,
|
||||
data->textureTintFragmentProgramId,
|
||||
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
|
||||
0,
|
||||
blend_info,
|
||||
textureVertexProgramGxp,
|
||||
&out->textureTint
|
||||
);
|
||||
|
||||
if (err != 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Patcher create fragment failed: %d\n", err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -232,22 +216,18 @@ set_stencil_mask(VITA_GXM_RenderData *data, float x, float y, float w, float h)
|
||||
|
||||
vertices[0].x = x;
|
||||
vertices[0].y = y;
|
||||
vertices[0].z = +0.5f;
|
||||
vertices[0].color = 0;
|
||||
|
||||
vertices[1].x = x + w;
|
||||
vertices[1].y = y;
|
||||
vertices[1].z = +0.5f;
|
||||
vertices[1].color = 0;
|
||||
|
||||
vertices[2].x = x;
|
||||
vertices[2].y = y + h;
|
||||
vertices[2].z = +0.5f;
|
||||
vertices[2].color = 0;
|
||||
|
||||
vertices[3].x = x + w;
|
||||
vertices[3].y = y + h;
|
||||
vertices[3].z = +0.5f;
|
||||
vertices[3].color = 0;
|
||||
|
||||
data->drawstate.fragment_program = data->colorFragmentProgram;
|
||||
@@ -495,7 +475,7 @@ gxm_init(SDL_Renderer *renderer)
|
||||
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
|
||||
&data->displayBufferUid[i]);
|
||||
|
||||
// memset the buffer to black
|
||||
// SDL_memset the buffer to black
|
||||
for (y = 0; y < VITA_GXM_SCREEN_HEIGHT; y++) {
|
||||
unsigned int *row = (unsigned int *)data->displayBufferData[i] + y * VITA_GXM_SCREEN_STRIDE;
|
||||
for (x = 0; x < VITA_GXM_SCREEN_WIDTH; x++) {
|
||||
@@ -654,12 +634,6 @@ gxm_init(SDL_Renderer *renderer)
|
||||
return err;
|
||||
}
|
||||
|
||||
err = sceGxmProgramCheck(textureTintFragmentProgramGxp);
|
||||
if (err != 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "check program (texture tint fragment) failed: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
// register programs with the patcher
|
||||
err = sceGxmShaderPatcherRegisterProgram(data->shaderPatcher, clearVertexProgramGxp, &data->clearVertexProgramId);
|
||||
if (err != 0) {
|
||||
@@ -697,13 +671,6 @@ gxm_init(SDL_Renderer *renderer)
|
||||
return err;
|
||||
}
|
||||
|
||||
err = sceGxmShaderPatcherRegisterProgram(data->shaderPatcher, textureTintFragmentProgramGxp, &data->textureTintFragmentProgramId);
|
||||
if (err != 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "register program (texture tint fragment) failed: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
// get attributes by name to create vertex format bindings
|
||||
const SceGxmProgramParameter *paramClearPositionAttribute = sceGxmProgramFindParameterByName(clearVertexProgramGxp, "aPosition");
|
||||
@@ -789,15 +756,15 @@ gxm_init(SDL_Renderer *renderer)
|
||||
// create color vertex format
|
||||
SceGxmVertexAttribute colorVertexAttributes[2];
|
||||
SceGxmVertexStream colorVertexStreams[1];
|
||||
/* x,y,z: 3 float 32 bits */
|
||||
/* x,y: 2 float 32 bits */
|
||||
colorVertexAttributes[0].streamIndex = 0;
|
||||
colorVertexAttributes[0].offset = 0;
|
||||
colorVertexAttributes[0].format = SCE_GXM_ATTRIBUTE_FORMAT_F32;
|
||||
colorVertexAttributes[0].componentCount = 3; // (x, y, z)
|
||||
colorVertexAttributes[0].componentCount = 2; // (x, y)
|
||||
colorVertexAttributes[0].regIndex = sceGxmProgramParameterGetResourceIndex(paramColorPositionAttribute);
|
||||
/* color: 4 unsigned char = 32 bits */
|
||||
colorVertexAttributes[1].streamIndex = 0;
|
||||
colorVertexAttributes[1].offset = 12; // (x, y, z) * 4 = 12 bytes
|
||||
colorVertexAttributes[1].offset = 8; // (x, y) * 4 = 8 bytes
|
||||
colorVertexAttributes[1].format = SCE_GXM_ATTRIBUTE_FORMAT_U8N;
|
||||
colorVertexAttributes[1].componentCount = 4; // (color)
|
||||
colorVertexAttributes[1].regIndex = sceGxmProgramParameterGetResourceIndex(paramColorColorAttribute);
|
||||
@@ -826,22 +793,29 @@ gxm_init(SDL_Renderer *renderer)
|
||||
{
|
||||
const SceGxmProgramParameter *paramTexturePositionAttribute = sceGxmProgramFindParameterByName(textureVertexProgramGxp, "aPosition");
|
||||
const SceGxmProgramParameter *paramTextureTexcoordAttribute = sceGxmProgramFindParameterByName(textureVertexProgramGxp, "aTexcoord");
|
||||
const SceGxmProgramParameter *paramTextureColorAttribute = sceGxmProgramFindParameterByName(textureVertexProgramGxp, "aColor");
|
||||
|
||||
// create texture vertex format
|
||||
SceGxmVertexAttribute textureVertexAttributes[2];
|
||||
SceGxmVertexAttribute textureVertexAttributes[3];
|
||||
SceGxmVertexStream textureVertexStreams[1];
|
||||
/* x,y,z: 3 float 32 bits */
|
||||
/* x,y: 2 float 32 bits */
|
||||
textureVertexAttributes[0].streamIndex = 0;
|
||||
textureVertexAttributes[0].offset = 0;
|
||||
textureVertexAttributes[0].format = SCE_GXM_ATTRIBUTE_FORMAT_F32;
|
||||
textureVertexAttributes[0].componentCount = 3; // (x, y, z)
|
||||
textureVertexAttributes[0].componentCount = 2; // (x, y)
|
||||
textureVertexAttributes[0].regIndex = sceGxmProgramParameterGetResourceIndex(paramTexturePositionAttribute);
|
||||
/* u,v: 2 floats 32 bits */
|
||||
textureVertexAttributes[1].streamIndex = 0;
|
||||
textureVertexAttributes[1].offset = 12; // (x, y, z) * 4 = 12 bytes
|
||||
textureVertexAttributes[1].offset = 8; // (x, y) * 4 = 8 bytes
|
||||
textureVertexAttributes[1].format = SCE_GXM_ATTRIBUTE_FORMAT_F32;
|
||||
textureVertexAttributes[1].componentCount = 2; // (u, v)
|
||||
textureVertexAttributes[1].regIndex = sceGxmProgramParameterGetResourceIndex(paramTextureTexcoordAttribute);
|
||||
/* r,g,b,a: 4 unsigned chars 32 bits */
|
||||
textureVertexAttributes[2].streamIndex = 0;
|
||||
textureVertexAttributes[2].offset = 16; // (x, y, u, v) * 4 = 16 bytes
|
||||
textureVertexAttributes[2].format = SCE_GXM_ATTRIBUTE_FORMAT_U8N;
|
||||
textureVertexAttributes[2].componentCount = 4; // (r, g, b, a)
|
||||
textureVertexAttributes[2].regIndex = sceGxmProgramParameterGetResourceIndex(paramTextureColorAttribute);
|
||||
// 16 bit (short) indices
|
||||
textureVertexStreams[0].stride = sizeof(texture_vertex);
|
||||
textureVertexStreams[0].indexSource = SCE_GXM_INDEX_SOURCE_INDEX_16BIT;
|
||||
@@ -851,13 +825,13 @@ gxm_init(SDL_Renderer *renderer)
|
||||
data->shaderPatcher,
|
||||
data->textureVertexProgramId,
|
||||
textureVertexAttributes,
|
||||
2,
|
||||
3,
|
||||
textureVertexStreams,
|
||||
1,
|
||||
&data->textureVertexProgram
|
||||
);
|
||||
if (err != 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create program (texture vertex) failed: %d\n", err);
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create program (texture vertex) failed: %x\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -876,7 +850,6 @@ gxm_init(SDL_Renderer *renderer)
|
||||
|
||||
data->colorFragmentProgram = in->color;
|
||||
data->textureFragmentProgram = in->texture;
|
||||
data->textureTintFragmentProgram = in->textureTint;
|
||||
|
||||
}
|
||||
|
||||
@@ -884,7 +857,6 @@ gxm_init(SDL_Renderer *renderer)
|
||||
data->clearClearColorParam = (SceGxmProgramParameter *)sceGxmProgramFindParameterByName(clearFragmentProgramGxp, "uClearColor");
|
||||
data->colorWvpParam = (SceGxmProgramParameter *)sceGxmProgramFindParameterByName(colorVertexProgramGxp, "wvp");
|
||||
data->textureWvpParam = (SceGxmProgramParameter *)sceGxmProgramFindParameterByName(textureVertexProgramGxp, "wvp");
|
||||
data->textureTintColorParam = (SceGxmProgramParameter *)sceGxmProgramFindParameterByName(textureTintFragmentProgramGxp, "uTintColor");
|
||||
|
||||
// Allocate memory for the memory pool
|
||||
data->pool_addr[0] = mem_gpu_alloc(
|
||||
@@ -953,7 +925,7 @@ void gxm_finish(SDL_Renderer *renderer)
|
||||
sceGxmSyncObjectDestroy(data->displayBufferSync[i]);
|
||||
}
|
||||
|
||||
// free the depth and stencil buffer
|
||||
// Free the depth and stencil buffer
|
||||
mem_gpu_free(data->depthBufferUid);
|
||||
mem_gpu_free(data->stencilBufferUid);
|
||||
|
||||
@@ -963,7 +935,6 @@ void gxm_finish(SDL_Renderer *renderer)
|
||||
sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->colorFragmentProgramId);
|
||||
sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->colorVertexProgramId);
|
||||
sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->textureFragmentProgramId);
|
||||
sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->textureTintFragmentProgramId);
|
||||
sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->textureVertexProgramId);
|
||||
|
||||
sceGxmShaderPatcherDestroy(data->shaderPatcher);
|
||||
@@ -1040,7 +1011,7 @@ gxm_texture_get_datap(const gxm_texture *texture)
|
||||
gxm_texture *
|
||||
create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget)
|
||||
{
|
||||
gxm_texture *texture = SDL_malloc(sizeof(gxm_texture));
|
||||
gxm_texture *texture = SDL_calloc(1, sizeof(gxm_texture));
|
||||
const int tex_size = ((w + 7) & ~ 7) * h * tex_format_to_bytespp(format);
|
||||
void *texture_data;
|
||||
|
||||
@@ -1056,8 +1027,20 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
|
||||
&texture->data_UID
|
||||
);
|
||||
|
||||
/* Try SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE in case we're out of VRAM */
|
||||
if (!texture_data) {
|
||||
free(texture);
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_RENDER, "CDRAM texture allocation failed\n");
|
||||
texture_data = mem_gpu_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
||||
tex_size,
|
||||
SCE_GXM_TEXTURE_ALIGNMENT,
|
||||
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
|
||||
&texture->data_UID
|
||||
);
|
||||
}
|
||||
|
||||
if (!texture_data) {
|
||||
SDL_free(texture);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1073,6 +1056,7 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
|
||||
const uint32_t alignedHeight = ALIGN(h, SCE_GXM_TILE_SIZEY);
|
||||
uint32_t sampleCount = alignedWidth*alignedHeight;
|
||||
uint32_t depthStrideInSamples = alignedWidth;
|
||||
const uint32_t alignedColorSurfaceStride = ALIGN(w, 8);
|
||||
|
||||
int err = sceGxmColorSurfaceInit(
|
||||
&texture->gxm_colorsurface,
|
||||
@@ -1082,7 +1066,7 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
|
||||
SCE_GXM_OUTPUT_REGISTER_SIZE_32BIT,
|
||||
w,
|
||||
h,
|
||||
w,
|
||||
alignedColorSurfaceStride,
|
||||
texture_data
|
||||
);
|
||||
|
||||
@@ -1120,7 +1104,7 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
|
||||
|
||||
// set up parameters
|
||||
SceGxmRenderTargetParams renderTargetParams;
|
||||
memset(&renderTargetParams, 0, sizeof(SceGxmRenderTargetParams));
|
||||
SDL_memset(&renderTargetParams, 0, sizeof(SceGxmRenderTargetParams));
|
||||
renderTargetParams.flags = 0;
|
||||
renderTargetParams.width = w;
|
||||
renderTargetParams.height = h;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
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
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
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
|
||||
@@ -61,16 +61,15 @@ typedef struct clear_vertex {
|
||||
typedef struct color_vertex {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
unsigned int color;
|
||||
} color_vertex;
|
||||
|
||||
typedef struct texture_vertex {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float u;
|
||||
float v;
|
||||
unsigned int color;
|
||||
} texture_vertex;
|
||||
|
||||
typedef struct gxm_texture {
|
||||
@@ -85,7 +84,6 @@ typedef struct gxm_texture {
|
||||
typedef struct fragment_programs {
|
||||
SceGxmFragmentProgram *color;
|
||||
SceGxmFragmentProgram *texture;
|
||||
SceGxmFragmentProgram *textureTint;
|
||||
} fragment_programs;
|
||||
|
||||
typedef struct blend_fragment_programs {
|
||||
@@ -103,7 +101,6 @@ typedef struct
|
||||
SDL_Texture *texture;
|
||||
SDL_Texture *target;
|
||||
Uint32 color;
|
||||
Uint32 texture_color;
|
||||
SceGxmFragmentProgram *fragment_program;
|
||||
SceGxmVertexProgram *vertex_program;
|
||||
int last_command;
|
||||
@@ -162,11 +159,9 @@ typedef struct
|
||||
SceGxmFragmentProgram *colorFragmentProgram;
|
||||
SceGxmVertexProgram *textureVertexProgram;
|
||||
SceGxmFragmentProgram *textureFragmentProgram;
|
||||
SceGxmFragmentProgram *textureTintFragmentProgram;
|
||||
SceGxmProgramParameter *clearClearColorParam;
|
||||
SceGxmProgramParameter *colorWvpParam;
|
||||
SceGxmProgramParameter *textureWvpParam;
|
||||
SceGxmProgramParameter *textureTintColorParam;
|
||||
|
||||
SceGxmShaderPatcher *shaderPatcher;
|
||||
SceGxmVertexProgram *clearVertexProgram;
|
||||
@@ -178,7 +173,6 @@ typedef struct
|
||||
SceGxmShaderPatcherId colorFragmentProgramId;
|
||||
SceGxmShaderPatcherId textureVertexProgramId;
|
||||
SceGxmShaderPatcherId textureFragmentProgramId;
|
||||
SceGxmShaderPatcherId textureTintFragmentProgramId;
|
||||
|
||||
SceUID patcherBufferUid;
|
||||
SceUID patcherVertexUsseUid;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
void main(
|
||||
float3 aPosition,
|
||||
float2 aPosition,
|
||||
float4 aColor,
|
||||
uniform float4x4 wvp,
|
||||
out float4 vPosition : POSITION,
|
||||
@@ -7,7 +7,7 @@ void main(
|
||||
out float pSize : PSIZE
|
||||
)
|
||||
{
|
||||
vPosition = mul(float4(aPosition, 1.f), wvp);
|
||||
vPosition = mul(float4(aPosition, 1.f, 0.5f), wvp);
|
||||
vColor = aColor;
|
||||
pSize = 1.f;
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
float4 main(float2 vTexcoord : TEXCOORD0, uniform sampler2D tex)
|
||||
float4 main(float2 vTexcoord : TEXCOORD0, float4 vColor : COLOR, uniform sampler2D tex)
|
||||
{
|
||||
return tex2D(tex, vTexcoord);
|
||||
return tex2D(tex, vTexcoord) * vColor;
|
||||
}
|
||||
|
@@ -1,11 +1,14 @@
|
||||
void main(
|
||||
float3 aPosition,
|
||||
float2 aPosition,
|
||||
float2 aTexcoord,
|
||||
float4 aColor,
|
||||
uniform float4x4 wvp,
|
||||
out float4 vPosition : POSITION,
|
||||
out float4 vColor : COLOR,
|
||||
out float2 vTexcoord : TEXCOORD0
|
||||
)
|
||||
{
|
||||
vPosition = mul(float4(aPosition, 1.f), wvp);
|
||||
vPosition = mul(float4(aPosition, 1.f, 0.5f), wvp);
|
||||
vTexcoord = aTexcoord;
|
||||
vColor = aColor;
|
||||
}
|
||||
|
Reference in New Issue
Block a user