2006-07-10 21:04:37 +00:00
|
|
|
/*
|
|
|
|
SDL - Simple DirectMedia Layer
|
2008-12-08 00:27:32 +00:00
|
|
|
Copyright (C) 1997-2009 Sam Lantinga
|
2006-07-10 21:04:37 +00:00
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Lesser General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Lesser General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
|
|
License along with this library; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
|
|
|
|
Sam Lantinga
|
|
|
|
slouken@libsdl.org
|
|
|
|
*/
|
|
|
|
#include "SDL_config.h"
|
|
|
|
|
|
|
|
#if SDL_VIDEO_RENDER_D3D
|
|
|
|
|
|
|
|
#include "SDL_win32video.h"
|
2009-01-03 05:42:18 +00:00
|
|
|
#include "../SDL_yuv_sw_c.h"
|
2006-07-10 21:04:37 +00:00
|
|
|
|
|
|
|
/* Direct3D renderer implementation */
|
|
|
|
|
2008-11-25 02:21:53 +00:00
|
|
|
#if 1 /* This takes more memory but you won't lose your texture data */
|
2008-12-31 06:17:24 +00:00
|
|
|
#define D3DPOOL_SDL D3DPOOL_MANAGED
|
2008-11-25 00:29:44 +00:00
|
|
|
#define SDL_MEMORY_POOL_MANAGED
|
|
|
|
#else
|
2008-12-31 06:17:24 +00:00
|
|
|
#define D3DPOOL_SDL D3DPOOL_DEFAULT
|
2008-11-25 00:29:44 +00:00
|
|
|
#define SDL_MEMORY_POOL_DEFAULT
|
|
|
|
#endif
|
|
|
|
|
2006-07-17 06:47:33 +00:00
|
|
|
static SDL_Renderer *D3D_CreateRenderer(SDL_Window * window, Uint32 flags);
|
2006-08-07 05:24:13 +00:00
|
|
|
static int D3D_DisplayModeChanged(SDL_Renderer * renderer);
|
2006-07-17 06:47:33 +00:00
|
|
|
static int D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
|
2009-01-04 17:14:27 +00:00
|
|
|
static int D3D_QueryTexturePixels(SDL_Renderer * renderer,
|
|
|
|
SDL_Texture * texture, void **pixels,
|
|
|
|
int *pitch);
|
2006-07-17 06:47:33 +00:00
|
|
|
static int D3D_SetTexturePalette(SDL_Renderer * renderer,
|
|
|
|
SDL_Texture * texture,
|
|
|
|
const SDL_Color * colors, int firstcolor,
|
|
|
|
int ncolors);
|
|
|
|
static int D3D_GetTexturePalette(SDL_Renderer * renderer,
|
|
|
|
SDL_Texture * texture, SDL_Color * colors,
|
|
|
|
int firstcolor, int ncolors);
|
2006-08-28 03:17:39 +00:00
|
|
|
static int D3D_SetTextureColorMod(SDL_Renderer * renderer,
|
|
|
|
SDL_Texture * texture);
|
|
|
|
static int D3D_SetTextureAlphaMod(SDL_Renderer * renderer,
|
|
|
|
SDL_Texture * texture);
|
|
|
|
static int D3D_SetTextureBlendMode(SDL_Renderer * renderer,
|
|
|
|
SDL_Texture * texture);
|
|
|
|
static int D3D_SetTextureScaleMode(SDL_Renderer * renderer,
|
|
|
|
SDL_Texture * texture);
|
2006-07-17 06:47:33 +00:00
|
|
|
static int D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
|
|
|
const SDL_Rect * rect, const void *pixels,
|
|
|
|
int pitch);
|
|
|
|
static int D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
|
|
|
const SDL_Rect * rect, int markDirty,
|
|
|
|
void **pixels, int *pitch);
|
|
|
|
static void D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
|
|
|
|
static void D3D_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
|
|
|
int numrects, const SDL_Rect * rects);
|
2008-12-31 06:17:24 +00:00
|
|
|
static int D3D_RenderPoint(SDL_Renderer * renderer, int x, int y);
|
|
|
|
static int D3D_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2,
|
|
|
|
int y2);
|
2008-12-25 05:16:18 +00:00
|
|
|
static int D3D_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect);
|
2006-07-17 06:47:33 +00:00
|
|
|
static int D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
|
2006-08-28 03:17:39 +00:00
|
|
|
const SDL_Rect * srcrect, const SDL_Rect * dstrect);
|
2009-11-09 05:20:11 +00:00
|
|
|
static int D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
2009-11-22 06:37:43 +00:00
|
|
|
Uint32 format, void * pixels, int pitch);
|
|
|
|
static int D3D_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
|
|
|
Uint32 format, const void * pixels, int pitch);
|
2006-07-17 06:47:33 +00:00
|
|
|
static void D3D_RenderPresent(SDL_Renderer * renderer);
|
|
|
|
static void D3D_DestroyTexture(SDL_Renderer * renderer,
|
|
|
|
SDL_Texture * texture);
|
|
|
|
static void D3D_DestroyRenderer(SDL_Renderer * renderer);
|
|
|
|
|
|
|
|
|
|
|
|
SDL_RenderDriver D3D_RenderDriver = {
|
|
|
|
D3D_CreateRenderer,
|
2006-07-10 21:04:37 +00:00
|
|
|
{
|
|
|
|
"d3d",
|
2006-08-05 17:09:42 +00:00
|
|
|
(SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY |
|
2006-08-07 05:24:13 +00:00
|
|
|
SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 |
|
2006-08-05 17:09:42 +00:00
|
|
|
SDL_RENDERER_PRESENTDISCARD | SDL_RENDERER_PRESENTVSYNC |
|
|
|
|
SDL_RENDERER_ACCELERATED),
|
2006-08-28 03:17:39 +00:00
|
|
|
(SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR |
|
|
|
|
SDL_TEXTUREMODULATE_ALPHA),
|
Date: Fri, 19 Dec 2008 20:17:35 +0100
From: Couriersud
Subject: Re: Aw: Experience using SDL1.3 in sdlmame/Proposal for api additions
> For consistency you'd probably want:
> SDL_SetRenderDrawColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a);
> SDL_SetRenderDrawBlendMode(SDL_BlendMode blendMode);
> SDL_RenderLine(int x1, int y1, int x2, int y2);
> SDL_RenderFill(SDL_Rect *rect);
>
> You probably also want to add API functions query the current state.
>
I have implemented the above api for the opengl, x11, directfb and
software renderers. I have also renamed *TEXTUREBLENDMODE* constants to
BLENDMODE*. The unix build compiles. The windows renderer still needs to
be updated, but I have no windows development machine at hand. Have a
look at the x11 renderer for a sample.
Vector games now run at 90% both on opengl and directfb in comparison to
sdlmame's own opengl renderer. The same applies to raster games.
The diff also includes
a) Changed XDrawRect to XFillRect in x11 renderer
b) A number of changes to fix blending and modulation issues in the
directfb renderer.
--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%403346
2008-12-20 12:00:00 +00:00
|
|
|
(SDL_BLENDMODE_NONE | SDL_BLENDMODE_MASK |
|
|
|
|
SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD),
|
2006-08-05 17:09:42 +00:00
|
|
|
(SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_FAST |
|
|
|
|
SDL_TEXTURESCALEMODE_SLOW | SDL_TEXTURESCALEMODE_BEST),
|
2009-01-03 04:33:19 +00:00
|
|
|
0,
|
|
|
|
{0},
|
2006-07-10 21:04:37 +00:00
|
|
|
0,
|
|
|
|
0}
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
2009-01-03 05:42:18 +00:00
|
|
|
IDirect3D9 *d3d;
|
2006-07-10 21:04:37 +00:00
|
|
|
IDirect3DDevice9 *device;
|
2006-08-07 05:24:13 +00:00
|
|
|
D3DPRESENT_PARAMETERS pparams;
|
2006-07-12 09:25:17 +00:00
|
|
|
SDL_bool beginScene;
|
2006-07-17 06:47:33 +00:00
|
|
|
} D3D_RenderData;
|
2006-07-10 21:04:37 +00:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
2009-01-03 05:42:18 +00:00
|
|
|
SDL_SW_YUVTexture *yuv;
|
|
|
|
Uint32 format;
|
2006-07-14 06:40:53 +00:00
|
|
|
IDirect3DTexture9 *texture;
|
2006-07-17 06:47:33 +00:00
|
|
|
} D3D_TextureData;
|
2006-07-10 21:04:37 +00:00
|
|
|
|
2006-07-14 06:40:53 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
float x, y, z;
|
2006-07-14 07:41:16 +00:00
|
|
|
float rhw;
|
2006-08-28 04:03:32 +00:00
|
|
|
DWORD color;
|
2006-07-14 07:41:16 +00:00
|
|
|
float u, v;
|
2006-07-14 06:40:53 +00:00
|
|
|
} Vertex;
|
|
|
|
|
2006-07-12 09:25:17 +00:00
|
|
|
static void
|
|
|
|
D3D_SetError(const char *prefix, HRESULT result)
|
|
|
|
{
|
|
|
|
const char *error;
|
|
|
|
|
|
|
|
switch (result) {
|
|
|
|
case D3DERR_WRONGTEXTUREFORMAT:
|
|
|
|
error = "WRONGTEXTUREFORMAT";
|
|
|
|
break;
|
|
|
|
case D3DERR_UNSUPPORTEDCOLOROPERATION:
|
|
|
|
error = "UNSUPPORTEDCOLOROPERATION";
|
|
|
|
break;
|
|
|
|
case D3DERR_UNSUPPORTEDCOLORARG:
|
|
|
|
error = "UNSUPPORTEDCOLORARG";
|
|
|
|
break;
|
|
|
|
case D3DERR_UNSUPPORTEDALPHAOPERATION:
|
|
|
|
error = "UNSUPPORTEDALPHAOPERATION";
|
|
|
|
break;
|
|
|
|
case D3DERR_UNSUPPORTEDALPHAARG:
|
|
|
|
error = "UNSUPPORTEDALPHAARG";
|
|
|
|
break;
|
|
|
|
case D3DERR_TOOMANYOPERATIONS:
|
|
|
|
error = "TOOMANYOPERATIONS";
|
|
|
|
break;
|
|
|
|
case D3DERR_CONFLICTINGTEXTUREFILTER:
|
|
|
|
error = "CONFLICTINGTEXTUREFILTER";
|
|
|
|
break;
|
|
|
|
case D3DERR_UNSUPPORTEDFACTORVALUE:
|
|
|
|
error = "UNSUPPORTEDFACTORVALUE";
|
|
|
|
break;
|
|
|
|
case D3DERR_CONFLICTINGRENDERSTATE:
|
|
|
|
error = "CONFLICTINGRENDERSTATE";
|
|
|
|
break;
|
|
|
|
case D3DERR_UNSUPPORTEDTEXTUREFILTER:
|
|
|
|
error = "UNSUPPORTEDTEXTUREFILTER";
|
|
|
|
break;
|
|
|
|
case D3DERR_CONFLICTINGTEXTUREPALETTE:
|
|
|
|
error = "CONFLICTINGTEXTUREPALETTE";
|
|
|
|
break;
|
|
|
|
case D3DERR_DRIVERINTERNALERROR:
|
|
|
|
error = "DRIVERINTERNALERROR";
|
|
|
|
break;
|
|
|
|
case D3DERR_NOTFOUND:
|
|
|
|
error = "NOTFOUND";
|
|
|
|
break;
|
|
|
|
case D3DERR_MOREDATA:
|
|
|
|
error = "MOREDATA";
|
|
|
|
break;
|
|
|
|
case D3DERR_DEVICELOST:
|
|
|
|
error = "DEVICELOST";
|
|
|
|
break;
|
|
|
|
case D3DERR_DEVICENOTRESET:
|
|
|
|
error = "DEVICENOTRESET";
|
|
|
|
break;
|
|
|
|
case D3DERR_NOTAVAILABLE:
|
|
|
|
error = "NOTAVAILABLE";
|
|
|
|
break;
|
|
|
|
case D3DERR_OUTOFVIDEOMEMORY:
|
|
|
|
error = "OUTOFVIDEOMEMORY";
|
|
|
|
break;
|
|
|
|
case D3DERR_INVALIDDEVICE:
|
|
|
|
error = "INVALIDDEVICE";
|
|
|
|
break;
|
|
|
|
case D3DERR_INVALIDCALL:
|
|
|
|
error = "INVALIDCALL";
|
|
|
|
break;
|
|
|
|
case D3DERR_DRIVERINVALIDCALL:
|
|
|
|
error = "DRIVERINVALIDCALL";
|
|
|
|
break;
|
|
|
|
case D3DERR_WASSTILLDRAWING:
|
|
|
|
error = "WASSTILLDRAWING";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
error = "UNKNOWN";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
SDL_SetError("%s: %s", prefix, error);
|
|
|
|
}
|
|
|
|
|
2006-07-14 06:40:53 +00:00
|
|
|
static D3DFORMAT
|
|
|
|
PixelFormatToD3DFMT(Uint32 format)
|
2006-07-10 21:04:37 +00:00
|
|
|
{
|
2006-07-14 06:40:53 +00:00
|
|
|
switch (format) {
|
2006-08-05 17:09:42 +00:00
|
|
|
case SDL_PIXELFORMAT_INDEX8:
|
2006-07-14 06:40:53 +00:00
|
|
|
return D3DFMT_P8;
|
2006-08-05 17:09:42 +00:00
|
|
|
case SDL_PIXELFORMAT_RGB332:
|
2006-07-14 06:40:53 +00:00
|
|
|
return D3DFMT_R3G3B2;
|
2006-08-05 17:09:42 +00:00
|
|
|
case SDL_PIXELFORMAT_RGB444:
|
2006-07-14 06:40:53 +00:00
|
|
|
return D3DFMT_X4R4G4B4;
|
2006-08-05 17:09:42 +00:00
|
|
|
case SDL_PIXELFORMAT_RGB555:
|
2006-07-14 06:40:53 +00:00
|
|
|
return D3DFMT_X1R5G5B5;
|
2006-08-05 17:09:42 +00:00
|
|
|
case SDL_PIXELFORMAT_ARGB4444:
|
2006-07-14 06:40:53 +00:00
|
|
|
return D3DFMT_A4R4G4B4;
|
2006-08-05 17:09:42 +00:00
|
|
|
case SDL_PIXELFORMAT_ARGB1555:
|
2006-07-14 06:40:53 +00:00
|
|
|
return D3DFMT_A1R5G5B5;
|
2006-08-05 17:09:42 +00:00
|
|
|
case SDL_PIXELFORMAT_RGB565:
|
2006-07-14 06:40:53 +00:00
|
|
|
return D3DFMT_R5G6B5;
|
2006-08-05 17:09:42 +00:00
|
|
|
case SDL_PIXELFORMAT_RGB888:
|
2006-07-14 06:40:53 +00:00
|
|
|
return D3DFMT_X8R8G8B8;
|
2006-08-05 17:09:42 +00:00
|
|
|
case SDL_PIXELFORMAT_ARGB8888:
|
2006-07-14 06:40:53 +00:00
|
|
|
return D3DFMT_A8R8G8B8;
|
2006-08-05 17:09:42 +00:00
|
|
|
case SDL_PIXELFORMAT_ARGB2101010:
|
2006-07-14 06:40:53 +00:00
|
|
|
return D3DFMT_A2R10G10B10;
|
2009-11-27 03:11:26 +00:00
|
|
|
case SDL_PIXELFORMAT_YV12:
|
|
|
|
return MAKEFOURCC('Y','V','1','2');
|
|
|
|
case SDL_PIXELFORMAT_IYUV:
|
|
|
|
return MAKEFOURCC('I','4','2','0');
|
2006-08-05 17:09:42 +00:00
|
|
|
case SDL_PIXELFORMAT_UYVY:
|
2006-07-14 06:40:53 +00:00
|
|
|
return D3DFMT_UYVY;
|
2006-08-05 17:09:42 +00:00
|
|
|
case SDL_PIXELFORMAT_YUY2:
|
2006-07-14 06:40:53 +00:00
|
|
|
return D3DFMT_YUY2;
|
|
|
|
default:
|
|
|
|
return D3DFMT_UNKNOWN;
|
|
|
|
}
|
2006-07-10 21:04:37 +00:00
|
|
|
}
|
|
|
|
|
2009-01-03 05:42:18 +00:00
|
|
|
static SDL_bool
|
2009-01-04 17:14:27 +00:00
|
|
|
D3D_IsTextureFormatAvailable(IDirect3D9 * d3d, Uint32 display_format,
|
|
|
|
Uint32 texture_format)
|
2009-01-03 05:42:18 +00:00
|
|
|
{
|
|
|
|
HRESULT result;
|
|
|
|
|
2009-01-04 17:14:27 +00:00
|
|
|
result = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, /* FIXME */
|
2009-01-03 05:42:18 +00:00
|
|
|
D3DDEVTYPE_HAL,
|
|
|
|
PixelFormatToD3DFMT(display_format),
|
|
|
|
0,
|
|
|
|
D3DRTYPE_TEXTURE,
|
2009-01-04 17:14:27 +00:00
|
|
|
PixelFormatToD3DFMT
|
|
|
|
(texture_format));
|
2009-01-03 05:42:18 +00:00
|
|
|
return FAILED(result) ? SDL_FALSE : SDL_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
UpdateYUVTextureData(SDL_Texture * texture)
|
|
|
|
{
|
|
|
|
D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
|
|
|
|
SDL_Rect rect;
|
|
|
|
RECT d3drect;
|
|
|
|
D3DLOCKED_RECT locked;
|
|
|
|
HRESULT result;
|
|
|
|
|
|
|
|
d3drect.left = 0;
|
|
|
|
d3drect.right = texture->w;
|
|
|
|
d3drect.top = 0;
|
|
|
|
d3drect.bottom = texture->h;
|
|
|
|
|
2009-01-04 17:14:27 +00:00
|
|
|
result =
|
|
|
|
IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect, 0);
|
2009-01-03 05:42:18 +00:00
|
|
|
if (FAILED(result)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
rect.x = 0;
|
|
|
|
rect.y = 0;
|
|
|
|
rect.w = texture->w;
|
|
|
|
rect.h = texture->h;
|
|
|
|
SDL_SW_CopyYUVToRGB(data->yuv, &rect, data->format, texture->w,
|
|
|
|
texture->h, locked.pBits, locked.Pitch);
|
|
|
|
|
|
|
|
IDirect3DTexture9_UnlockRect(data->texture, 0);
|
|
|
|
}
|
|
|
|
|
2006-07-10 21:04:37 +00:00
|
|
|
void
|
|
|
|
D3D_AddRenderDriver(_THIS)
|
|
|
|
{
|
|
|
|
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
|
2009-01-03 04:33:19 +00:00
|
|
|
SDL_RendererInfo *info = &D3D_RenderDriver.info;
|
|
|
|
SDL_DisplayMode *mode = &SDL_CurrentDisplay.desktop_mode;
|
2006-07-10 21:04:37 +00:00
|
|
|
|
|
|
|
if (data->d3d) {
|
2009-01-03 04:33:19 +00:00
|
|
|
int i;
|
|
|
|
int formats[] = {
|
2009-01-04 17:14:27 +00:00
|
|
|
SDL_PIXELFORMAT_INDEX8,
|
|
|
|
SDL_PIXELFORMAT_RGB332,
|
|
|
|
SDL_PIXELFORMAT_RGB444,
|
|
|
|
SDL_PIXELFORMAT_RGB555,
|
|
|
|
SDL_PIXELFORMAT_ARGB4444,
|
|
|
|
SDL_PIXELFORMAT_ARGB1555,
|
|
|
|
SDL_PIXELFORMAT_RGB565,
|
|
|
|
SDL_PIXELFORMAT_RGB888,
|
|
|
|
SDL_PIXELFORMAT_ARGB8888,
|
|
|
|
SDL_PIXELFORMAT_ARGB2101010,
|
2009-01-03 04:33:19 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
for (i = 0; i < SDL_arraysize(formats); ++i) {
|
2009-01-04 17:14:27 +00:00
|
|
|
if (D3D_IsTextureFormatAvailable
|
|
|
|
(data->d3d, mode->format, formats[i])) {
|
|
|
|
info->texture_formats[info->num_texture_formats++] =
|
|
|
|
formats[i];
|
2009-01-03 04:33:19 +00:00
|
|
|
}
|
|
|
|
}
|
2009-01-04 17:14:27 +00:00
|
|
|
info->texture_formats[info->num_texture_formats++] =
|
|
|
|
SDL_PIXELFORMAT_YV12;
|
|
|
|
info->texture_formats[info->num_texture_formats++] =
|
|
|
|
SDL_PIXELFORMAT_IYUV;
|
|
|
|
info->texture_formats[info->num_texture_formats++] =
|
|
|
|
SDL_PIXELFORMAT_YUY2;
|
|
|
|
info->texture_formats[info->num_texture_formats++] =
|
|
|
|
SDL_PIXELFORMAT_UYVY;
|
|
|
|
info->texture_formats[info->num_texture_formats++] =
|
|
|
|
SDL_PIXELFORMAT_YVYU;
|
2009-01-03 04:33:19 +00:00
|
|
|
|
2006-07-17 06:47:33 +00:00
|
|
|
SDL_AddRenderDriver(0, &D3D_RenderDriver);
|
2006-07-10 21:04:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_Renderer *
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
|
2006-07-10 21:04:37 +00:00
|
|
|
{
|
|
|
|
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
|
|
|
|
SDL_VideoData *videodata = (SDL_VideoData *) display->device->driverdata;
|
|
|
|
SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata;
|
|
|
|
SDL_Renderer *renderer;
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_RenderData *data;
|
2006-07-12 09:25:17 +00:00
|
|
|
HRESULT result;
|
|
|
|
D3DPRESENT_PARAMETERS pparams;
|
2006-07-15 09:46:36 +00:00
|
|
|
IDirect3DSwapChain9 *chain;
|
2006-07-22 21:17:37 +00:00
|
|
|
D3DCAPS9 caps;
|
2006-07-10 21:04:37 +00:00
|
|
|
|
2006-07-22 08:33:18 +00:00
|
|
|
renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
|
2006-07-10 21:04:37 +00:00
|
|
|
if (!renderer) {
|
|
|
|
SDL_OutOfMemory();
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2006-07-22 08:33:18 +00:00
|
|
|
data = (D3D_RenderData *) SDL_calloc(1, sizeof(*data));
|
2006-07-10 21:04:37 +00:00
|
|
|
if (!data) {
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_DestroyRenderer(renderer);
|
2006-07-10 21:04:37 +00:00
|
|
|
SDL_OutOfMemory();
|
|
|
|
return NULL;
|
|
|
|
}
|
2009-01-03 05:42:18 +00:00
|
|
|
data->d3d = videodata->d3d;
|
2006-07-10 21:04:37 +00:00
|
|
|
|
2006-08-07 05:24:13 +00:00
|
|
|
renderer->DisplayModeChanged = D3D_DisplayModeChanged;
|
2006-07-17 06:47:33 +00:00
|
|
|
renderer->CreateTexture = D3D_CreateTexture;
|
2009-01-03 05:42:18 +00:00
|
|
|
renderer->QueryTexturePixels = D3D_QueryTexturePixels;
|
2006-07-17 06:47:33 +00:00
|
|
|
renderer->SetTexturePalette = D3D_SetTexturePalette;
|
|
|
|
renderer->GetTexturePalette = D3D_GetTexturePalette;
|
2006-08-28 03:17:39 +00:00
|
|
|
renderer->SetTextureColorMod = D3D_SetTextureColorMod;
|
|
|
|
renderer->SetTextureAlphaMod = D3D_SetTextureAlphaMod;
|
|
|
|
renderer->SetTextureBlendMode = D3D_SetTextureBlendMode;
|
|
|
|
renderer->SetTextureScaleMode = D3D_SetTextureScaleMode;
|
2006-07-17 06:47:33 +00:00
|
|
|
renderer->UpdateTexture = D3D_UpdateTexture;
|
|
|
|
renderer->LockTexture = D3D_LockTexture;
|
|
|
|
renderer->UnlockTexture = D3D_UnlockTexture;
|
|
|
|
renderer->DirtyTexture = D3D_DirtyTexture;
|
2008-12-31 06:17:24 +00:00
|
|
|
renderer->RenderPoint = D3D_RenderPoint;
|
|
|
|
renderer->RenderLine = D3D_RenderLine;
|
2006-07-17 06:47:33 +00:00
|
|
|
renderer->RenderFill = D3D_RenderFill;
|
|
|
|
renderer->RenderCopy = D3D_RenderCopy;
|
2009-11-09 05:20:11 +00:00
|
|
|
renderer->RenderReadPixels = D3D_RenderReadPixels;
|
2009-11-22 06:37:43 +00:00
|
|
|
renderer->RenderWritePixels = D3D_RenderWritePixels;
|
2006-07-17 06:47:33 +00:00
|
|
|
renderer->RenderPresent = D3D_RenderPresent;
|
|
|
|
renderer->DestroyTexture = D3D_DestroyTexture;
|
|
|
|
renderer->DestroyRenderer = D3D_DestroyRenderer;
|
|
|
|
renderer->info = D3D_RenderDriver.info;
|
2006-07-10 21:04:37 +00:00
|
|
|
renderer->window = window->id;
|
|
|
|
renderer->driverdata = data;
|
|
|
|
|
2006-08-05 17:09:42 +00:00
|
|
|
renderer->info.flags = SDL_RENDERER_ACCELERATED;
|
2006-07-10 21:04:37 +00:00
|
|
|
|
2006-07-12 09:25:17 +00:00
|
|
|
SDL_zero(pparams);
|
|
|
|
pparams.BackBufferWidth = window->w;
|
|
|
|
pparams.BackBufferHeight = window->h;
|
2006-07-14 06:40:53 +00:00
|
|
|
if (window->flags & SDL_WINDOW_FULLSCREEN) {
|
|
|
|
pparams.BackBufferFormat =
|
2009-12-04 08:26:32 +00:00
|
|
|
PixelFormatToD3DFMT(window->fullscreen_mode.format);
|
2006-07-14 06:40:53 +00:00
|
|
|
} else {
|
|
|
|
pparams.BackBufferFormat = D3DFMT_UNKNOWN;
|
|
|
|
}
|
2006-08-05 17:09:42 +00:00
|
|
|
if (flags & SDL_RENDERER_PRESENTFLIP2) {
|
2006-07-12 09:25:17 +00:00
|
|
|
pparams.BackBufferCount = 2;
|
|
|
|
pparams.SwapEffect = D3DSWAPEFFECT_FLIP;
|
2006-08-05 17:09:42 +00:00
|
|
|
} else if (flags & SDL_RENDERER_PRESENTFLIP3) {
|
2006-07-12 09:25:17 +00:00
|
|
|
pparams.BackBufferCount = 3;
|
|
|
|
pparams.SwapEffect = D3DSWAPEFFECT_FLIP;
|
2006-08-05 17:09:42 +00:00
|
|
|
} else if (flags & SDL_RENDERER_PRESENTCOPY) {
|
2006-07-12 09:25:17 +00:00
|
|
|
pparams.BackBufferCount = 1;
|
|
|
|
pparams.SwapEffect = D3DSWAPEFFECT_COPY;
|
|
|
|
} else {
|
|
|
|
pparams.BackBufferCount = 1;
|
|
|
|
pparams.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
|
|
|
}
|
|
|
|
if (window->flags & SDL_WINDOW_FULLSCREEN) {
|
|
|
|
pparams.Windowed = FALSE;
|
2006-07-14 06:40:53 +00:00
|
|
|
pparams.FullScreen_RefreshRateInHz =
|
2009-12-04 08:26:32 +00:00
|
|
|
window->fullscreen_mode.refresh_rate;
|
2006-07-12 09:25:17 +00:00
|
|
|
} else {
|
|
|
|
pparams.Windowed = TRUE;
|
2006-07-14 06:40:53 +00:00
|
|
|
pparams.FullScreen_RefreshRateInHz = 0;
|
2006-07-12 09:25:17 +00:00
|
|
|
}
|
2006-08-05 17:09:42 +00:00
|
|
|
if (flags & SDL_RENDERER_PRESENTVSYNC) {
|
2006-07-15 09:46:36 +00:00
|
|
|
pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
|
|
|
|
} else {
|
|
|
|
pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
|
|
|
}
|
2006-07-12 09:25:17 +00:00
|
|
|
|
2009-06-16 14:34:15 +00:00
|
|
|
IDirect3D9_GetDeviceCaps(videodata->d3d, D3DADAPTER_DEFAULT,
|
|
|
|
D3DDEVTYPE_HAL, &caps);
|
|
|
|
|
2006-07-12 09:25:17 +00:00
|
|
|
result = IDirect3D9_CreateDevice(videodata->d3d, D3DADAPTER_DEFAULT, /* FIXME */
|
|
|
|
D3DDEVTYPE_HAL,
|
|
|
|
windowdata->hwnd,
|
2009-06-16 14:34:15 +00:00
|
|
|
(caps.
|
|
|
|
DevCaps &
|
|
|
|
D3DDEVCAPS_HWTRANSFORMANDLIGHT) ?
|
|
|
|
D3DCREATE_HARDWARE_VERTEXPROCESSING :
|
2006-07-12 09:25:17 +00:00
|
|
|
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
|
|
|
|
&pparams, &data->device);
|
|
|
|
if (FAILED(result)) {
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_DestroyRenderer(renderer);
|
2006-07-12 09:25:17 +00:00
|
|
|
D3D_SetError("CreateDevice()", result);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
data->beginScene = SDL_TRUE;
|
|
|
|
|
2006-07-15 09:46:36 +00:00
|
|
|
/* Get presentation parameters to fill info */
|
|
|
|
result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain);
|
|
|
|
if (FAILED(result)) {
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_DestroyRenderer(renderer);
|
2006-07-15 09:46:36 +00:00
|
|
|
D3D_SetError("GetSwapChain()", result);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams);
|
|
|
|
if (FAILED(result)) {
|
|
|
|
IDirect3DSwapChain9_Release(chain);
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_DestroyRenderer(renderer);
|
2006-07-15 09:46:36 +00:00
|
|
|
D3D_SetError("GetPresentParameters()", result);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
IDirect3DSwapChain9_Release(chain);
|
|
|
|
switch (pparams.SwapEffect) {
|
|
|
|
case D3DSWAPEFFECT_COPY:
|
2006-08-05 17:09:42 +00:00
|
|
|
renderer->info.flags |= SDL_RENDERER_PRESENTCOPY;
|
2006-07-15 09:46:36 +00:00
|
|
|
break;
|
|
|
|
case D3DSWAPEFFECT_FLIP:
|
|
|
|
switch (pparams.BackBufferCount) {
|
|
|
|
case 2:
|
2006-08-05 17:09:42 +00:00
|
|
|
renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
|
2006-07-15 09:46:36 +00:00
|
|
|
break;
|
|
|
|
case 3:
|
2006-08-05 17:09:42 +00:00
|
|
|
renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3;
|
2006-07-15 09:46:36 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case D3DSWAPEFFECT_DISCARD:
|
2006-08-05 17:09:42 +00:00
|
|
|
renderer->info.flags |= SDL_RENDERER_PRESENTDISCARD;
|
2006-07-15 09:46:36 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) {
|
2006-08-05 17:09:42 +00:00
|
|
|
renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
|
2006-07-15 09:46:36 +00:00
|
|
|
}
|
2006-08-07 05:24:13 +00:00
|
|
|
data->pparams = pparams;
|
2006-07-15 09:46:36 +00:00
|
|
|
|
2006-07-22 21:17:37 +00:00
|
|
|
IDirect3DDevice9_GetDeviceCaps(data->device, &caps);
|
|
|
|
renderer->info.max_texture_width = caps.MaxTextureWidth;
|
|
|
|
renderer->info.max_texture_height = caps.MaxTextureHeight;
|
2006-07-19 07:18:45 +00:00
|
|
|
|
2006-07-14 06:40:53 +00:00
|
|
|
/* Set up parameters for rendering */
|
2006-07-14 07:41:16 +00:00
|
|
|
IDirect3DDevice9_SetVertexShader(data->device, NULL);
|
2006-08-28 04:03:32 +00:00
|
|
|
IDirect3DDevice9_SetFVF(data->device,
|
|
|
|
D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
|
2006-08-28 04:39:37 +00:00
|
|
|
IDirect3DDevice9_SetRenderState(data->device, D3DRS_ZENABLE, D3DZB_FALSE);
|
2006-07-14 06:40:53 +00:00
|
|
|
IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE,
|
|
|
|
D3DCULL_NONE);
|
2006-07-14 07:41:16 +00:00
|
|
|
IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE);
|
2006-08-28 04:39:37 +00:00
|
|
|
/* Enable color modulation by diffuse color */
|
|
|
|
IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLOROP,
|
|
|
|
D3DTOP_MODULATE);
|
|
|
|
IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG1,
|
|
|
|
D3DTA_TEXTURE);
|
|
|
|
IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_COLORARG2,
|
|
|
|
D3DTA_DIFFUSE);
|
|
|
|
/* Enable alpha modulation by diffuse alpha */
|
|
|
|
IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAOP,
|
|
|
|
D3DTOP_MODULATE);
|
|
|
|
IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG1,
|
|
|
|
D3DTA_TEXTURE);
|
|
|
|
IDirect3DDevice9_SetTextureStageState(data->device, 0, D3DTSS_ALPHAARG2,
|
|
|
|
D3DTA_DIFFUSE);
|
2006-08-28 17:35:15 +00:00
|
|
|
/* Disable second texture stage, since we're done */
|
|
|
|
IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_COLOROP,
|
|
|
|
D3DTOP_DISABLE);
|
|
|
|
IDirect3DDevice9_SetTextureStageState(data->device, 1, D3DTSS_ALPHAOP,
|
|
|
|
D3DTOP_DISABLE);
|
2006-07-14 06:40:53 +00:00
|
|
|
|
2006-07-10 21:04:37 +00:00
|
|
|
return renderer;
|
|
|
|
}
|
|
|
|
|
2006-08-07 05:24:13 +00:00
|
|
|
static int
|
|
|
|
D3D_Reset(SDL_Renderer * renderer)
|
|
|
|
{
|
|
|
|
D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
|
|
|
|
HRESULT result;
|
|
|
|
|
|
|
|
result = IDirect3DDevice9_Reset(data->device, &data->pparams);
|
|
|
|
if (FAILED(result)) {
|
|
|
|
if (result == D3DERR_DEVICELOST) {
|
|
|
|
/* Don't worry about it, we'll reset later... */
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
D3D_SetError("Reset()", result);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
IDirect3DDevice9_SetVertexShader(data->device, NULL);
|
2006-08-28 04:03:32 +00:00
|
|
|
IDirect3DDevice9_SetFVF(data->device,
|
|
|
|
D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
|
2006-08-07 05:24:13 +00:00
|
|
|
IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE,
|
|
|
|
D3DCULL_NONE);
|
|
|
|
IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
D3D_DisplayModeChanged(SDL_Renderer * renderer)
|
|
|
|
{
|
|
|
|
D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
|
|
|
|
SDL_Window *window = SDL_GetWindowFromID(renderer->window);
|
|
|
|
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
|
|
|
|
|
|
|
|
data->pparams.BackBufferWidth = window->w;
|
|
|
|
data->pparams.BackBufferHeight = window->h;
|
|
|
|
if (window->flags & SDL_WINDOW_FULLSCREEN) {
|
|
|
|
data->pparams.BackBufferFormat =
|
2009-12-04 08:26:32 +00:00
|
|
|
PixelFormatToD3DFMT(window->fullscreen_mode.format);
|
2006-08-07 05:24:13 +00:00
|
|
|
} else {
|
|
|
|
data->pparams.BackBufferFormat = D3DFMT_UNKNOWN;
|
|
|
|
}
|
|
|
|
return D3D_Reset(renderer);
|
|
|
|
}
|
|
|
|
|
2006-07-10 21:04:37 +00:00
|
|
|
static int
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
2006-07-10 21:04:37 +00:00
|
|
|
{
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata;
|
2006-07-10 21:04:37 +00:00
|
|
|
SDL_Window *window = SDL_GetWindowFromID(renderer->window);
|
|
|
|
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
|
2009-01-03 05:42:18 +00:00
|
|
|
Uint32 display_format = display->current_mode.format;
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_TextureData *data;
|
2006-07-14 06:40:53 +00:00
|
|
|
HRESULT result;
|
2006-07-10 21:04:37 +00:00
|
|
|
|
2006-07-22 08:33:18 +00:00
|
|
|
data = (D3D_TextureData *) SDL_calloc(1, sizeof(*data));
|
2006-07-10 21:04:37 +00:00
|
|
|
if (!data) {
|
|
|
|
SDL_OutOfMemory();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
texture->driverdata = data;
|
|
|
|
|
2009-01-03 05:42:18 +00:00
|
|
|
if (SDL_ISPIXELFORMAT_FOURCC(texture->format) &&
|
|
|
|
(texture->format != SDL_PIXELFORMAT_YUY2 ||
|
2009-01-04 17:14:27 +00:00
|
|
|
!D3D_IsTextureFormatAvailable(renderdata->d3d, display_format,
|
|
|
|
texture->format))
|
|
|
|
&& (texture->format != SDL_PIXELFORMAT_YVYU
|
|
|
|
|| !D3D_IsTextureFormatAvailable(renderdata->d3d, display_format,
|
|
|
|
texture->format))) {
|
2009-01-03 05:42:18 +00:00
|
|
|
data->yuv =
|
|
|
|
SDL_SW_CreateYUVTexture(texture->format, texture->w, texture->h);
|
|
|
|
if (!data->yuv) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
data->format = display->current_mode.format;
|
|
|
|
} else {
|
|
|
|
data->format = texture->format;
|
|
|
|
}
|
|
|
|
|
2006-07-14 06:40:53 +00:00
|
|
|
result =
|
|
|
|
IDirect3DDevice9_CreateTexture(renderdata->device, texture->w,
|
|
|
|
texture->h, 1, 0,
|
2009-01-03 05:42:18 +00:00
|
|
|
PixelFormatToD3DFMT(data->format),
|
2008-11-25 00:29:44 +00:00
|
|
|
D3DPOOL_SDL, &data->texture, NULL);
|
2006-07-14 06:40:53 +00:00
|
|
|
if (FAILED(result)) {
|
|
|
|
D3D_SetError("CreateTexture()", result);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2006-07-10 21:04:37 +00:00
|
|
|
}
|
|
|
|
|
2009-01-03 05:42:18 +00:00
|
|
|
static int
|
|
|
|
D3D_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
|
|
|
|
void **pixels, int *pitch)
|
|
|
|
{
|
|
|
|
D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
|
|
|
|
|
|
|
|
if (data->yuv) {
|
|
|
|
return SDL_SW_QueryYUVTexturePixels(data->yuv, pixels, pitch);
|
|
|
|
} else {
|
|
|
|
/* D3D textures don't have their pixels hanging out */
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-07-10 21:04:37 +00:00
|
|
|
static int
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
|
|
|
|
const SDL_Color * colors, int firstcolor, int ncolors)
|
2006-07-10 21:04:37 +00:00
|
|
|
{
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata;
|
|
|
|
D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
|
2006-07-10 21:04:37 +00:00
|
|
|
|
2006-07-14 06:40:53 +00:00
|
|
|
return 0;
|
2006-07-10 21:04:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
|
|
|
|
SDL_Color * colors, int firstcolor, int ncolors)
|
2006-07-10 21:04:37 +00:00
|
|
|
{
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
|
2006-07-10 21:04:37 +00:00
|
|
|
|
2006-07-14 06:40:53 +00:00
|
|
|
return 0;
|
2006-07-10 21:04:37 +00:00
|
|
|
}
|
|
|
|
|
2006-08-28 03:17:39 +00:00
|
|
|
static int
|
|
|
|
D3D_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
|
|
|
|
{
|
2006-08-28 04:03:32 +00:00
|
|
|
return 0;
|
2006-08-28 03:17:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
D3D_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture)
|
|
|
|
{
|
2006-08-28 04:03:32 +00:00
|
|
|
return 0;
|
2006-08-28 03:17:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
D3D_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture)
|
|
|
|
{
|
|
|
|
switch (texture->blendMode) {
|
Date: Fri, 19 Dec 2008 20:17:35 +0100
From: Couriersud
Subject: Re: Aw: Experience using SDL1.3 in sdlmame/Proposal for api additions
> For consistency you'd probably want:
> SDL_SetRenderDrawColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a);
> SDL_SetRenderDrawBlendMode(SDL_BlendMode blendMode);
> SDL_RenderLine(int x1, int y1, int x2, int y2);
> SDL_RenderFill(SDL_Rect *rect);
>
> You probably also want to add API functions query the current state.
>
I have implemented the above api for the opengl, x11, directfb and
software renderers. I have also renamed *TEXTUREBLENDMODE* constants to
BLENDMODE*. The unix build compiles. The windows renderer still needs to
be updated, but I have no windows development machine at hand. Have a
look at the x11 renderer for a sample.
Vector games now run at 90% both on opengl and directfb in comparison to
sdlmame's own opengl renderer. The same applies to raster games.
The diff also includes
a) Changed XDrawRect to XFillRect in x11 renderer
b) A number of changes to fix blending and modulation issues in the
directfb renderer.
--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%403346
2008-12-20 12:00:00 +00:00
|
|
|
case SDL_BLENDMODE_NONE:
|
|
|
|
case SDL_BLENDMODE_MASK:
|
|
|
|
case SDL_BLENDMODE_BLEND:
|
|
|
|
case SDL_BLENDMODE_ADD:
|
|
|
|
case SDL_BLENDMODE_MOD:
|
2006-08-28 03:17:39 +00:00
|
|
|
return 0;
|
|
|
|
default:
|
|
|
|
SDL_Unsupported();
|
Date: Fri, 19 Dec 2008 20:17:35 +0100
From: Couriersud
Subject: Re: Aw: Experience using SDL1.3 in sdlmame/Proposal for api additions
> For consistency you'd probably want:
> SDL_SetRenderDrawColor(Uint8 r, Uint8 g, Uint8 b, Uint8 a);
> SDL_SetRenderDrawBlendMode(SDL_BlendMode blendMode);
> SDL_RenderLine(int x1, int y1, int x2, int y2);
> SDL_RenderFill(SDL_Rect *rect);
>
> You probably also want to add API functions query the current state.
>
I have implemented the above api for the opengl, x11, directfb and
software renderers. I have also renamed *TEXTUREBLENDMODE* constants to
BLENDMODE*. The unix build compiles. The windows renderer still needs to
be updated, but I have no windows development machine at hand. Have a
look at the x11 renderer for a sample.
Vector games now run at 90% both on opengl and directfb in comparison to
sdlmame's own opengl renderer. The same applies to raster games.
The diff also includes
a) Changed XDrawRect to XFillRect in x11 renderer
b) A number of changes to fix blending and modulation issues in the
directfb renderer.
--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%403346
2008-12-20 12:00:00 +00:00
|
|
|
texture->blendMode = SDL_BLENDMODE_NONE;
|
2006-08-28 03:17:39 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
D3D_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture)
|
|
|
|
{
|
|
|
|
switch (texture->scaleMode) {
|
|
|
|
case SDL_TEXTURESCALEMODE_NONE:
|
|
|
|
case SDL_TEXTURESCALEMODE_FAST:
|
|
|
|
case SDL_TEXTURESCALEMODE_SLOW:
|
|
|
|
case SDL_TEXTURESCALEMODE_BEST:
|
|
|
|
return 0;
|
|
|
|
default:
|
|
|
|
SDL_Unsupported();
|
|
|
|
texture->scaleMode = SDL_TEXTURESCALEMODE_NONE;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-07-10 21:04:37 +00:00
|
|
|
static int
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
|
|
|
const SDL_Rect * rect, const void *pixels, int pitch)
|
2006-07-10 21:04:37 +00:00
|
|
|
{
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
|
|
|
|
D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata;
|
2006-07-10 21:04:37 +00:00
|
|
|
|
2009-01-03 05:42:18 +00:00
|
|
|
if (data->yuv) {
|
|
|
|
if (SDL_SW_UpdateYUVTexture(data->yuv, rect, pixels, pitch) < 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
UpdateYUVTextureData(texture);
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
#ifdef SDL_MEMORY_POOL_DEFAULT
|
|
|
|
IDirect3DTexture9 *temp;
|
|
|
|
RECT d3drect;
|
|
|
|
D3DLOCKED_RECT locked;
|
|
|
|
const Uint8 *src;
|
|
|
|
Uint8 *dst;
|
|
|
|
int row, length;
|
|
|
|
HRESULT result;
|
2006-07-14 06:40:53 +00:00
|
|
|
|
2009-01-03 05:42:18 +00:00
|
|
|
result =
|
|
|
|
IDirect3DDevice9_CreateTexture(renderdata->device, texture->w,
|
|
|
|
texture->h, 1, 0,
|
2009-01-10 21:50:26 +00:00
|
|
|
PixelFormatToD3DFMT(texture->
|
|
|
|
format),
|
2009-01-03 05:42:18 +00:00
|
|
|
D3DPOOL_SYSTEMMEM, &temp, NULL);
|
|
|
|
if (FAILED(result)) {
|
|
|
|
D3D_SetError("CreateTexture()", result);
|
|
|
|
return -1;
|
|
|
|
}
|
2006-07-14 06:40:53 +00:00
|
|
|
|
2009-01-03 05:42:18 +00:00
|
|
|
d3drect.left = rect->x;
|
|
|
|
d3drect.right = rect->x + rect->w;
|
|
|
|
d3drect.top = rect->y;
|
|
|
|
d3drect.bottom = rect->y + rect->h;
|
2006-07-10 21:04:37 +00:00
|
|
|
|
2009-01-03 05:42:18 +00:00
|
|
|
result = IDirect3DTexture9_LockRect(temp, 0, &locked, &d3drect, 0);
|
|
|
|
if (FAILED(result)) {
|
|
|
|
IDirect3DTexture9_Release(temp);
|
|
|
|
D3D_SetError("LockRect()", result);
|
|
|
|
return -1;
|
|
|
|
}
|
2006-07-14 06:40:53 +00:00
|
|
|
|
2009-01-03 05:42:18 +00:00
|
|
|
src = pixels;
|
|
|
|
dst = locked.pBits;
|
|
|
|
length = rect->w * SDL_BYTESPERPIXEL(texture->format);
|
|
|
|
for (row = 0; row < rect->h; ++row) {
|
|
|
|
SDL_memcpy(dst, src, length);
|
|
|
|
src += pitch;
|
|
|
|
dst += locked.Pitch;
|
|
|
|
}
|
|
|
|
IDirect3DTexture9_UnlockRect(temp, 0);
|
|
|
|
|
|
|
|
result =
|
|
|
|
IDirect3DDevice9_UpdateTexture(renderdata->device,
|
|
|
|
(IDirect3DBaseTexture9 *) temp,
|
|
|
|
(IDirect3DBaseTexture9 *)
|
|
|
|
data->texture);
|
|
|
|
IDirect3DTexture9_Release(temp);
|
|
|
|
if (FAILED(result)) {
|
|
|
|
D3D_SetError("UpdateTexture()", result);
|
|
|
|
return -1;
|
|
|
|
}
|
2008-11-25 00:29:44 +00:00
|
|
|
#else
|
2009-01-03 05:42:18 +00:00
|
|
|
RECT d3drect;
|
|
|
|
D3DLOCKED_RECT locked;
|
|
|
|
const Uint8 *src;
|
|
|
|
Uint8 *dst;
|
|
|
|
int row, length;
|
|
|
|
HRESULT result;
|
2008-11-25 00:29:44 +00:00
|
|
|
|
2009-01-03 05:42:18 +00:00
|
|
|
d3drect.left = rect->x;
|
|
|
|
d3drect.right = rect->x + rect->w;
|
|
|
|
d3drect.top = rect->y;
|
|
|
|
d3drect.bottom = rect->y + rect->h;
|
2008-11-25 00:29:44 +00:00
|
|
|
|
2009-01-03 05:42:18 +00:00
|
|
|
result =
|
2009-01-04 17:14:27 +00:00
|
|
|
IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect,
|
|
|
|
0);
|
2009-01-03 05:42:18 +00:00
|
|
|
if (FAILED(result)) {
|
|
|
|
D3D_SetError("LockRect()", result);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
src = pixels;
|
|
|
|
dst = locked.pBits;
|
|
|
|
length = rect->w * SDL_BYTESPERPIXEL(texture->format);
|
|
|
|
for (row = 0; row < rect->h; ++row) {
|
|
|
|
SDL_memcpy(dst, src, length);
|
|
|
|
src += pitch;
|
|
|
|
dst += locked.Pitch;
|
|
|
|
}
|
|
|
|
IDirect3DTexture9_UnlockRect(data->texture, 0);
|
|
|
|
#endif // SDL_MEMORY_POOL_DEFAULT
|
2008-11-25 00:29:44 +00:00
|
|
|
|
2009-01-03 05:42:18 +00:00
|
|
|
return 0;
|
2008-11-25 00:29:44 +00:00
|
|
|
}
|
|
|
|
}
|
2006-07-10 21:04:37 +00:00
|
|
|
|
|
|
|
static int
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
|
|
|
const SDL_Rect * rect, int markDirty, void **pixels,
|
|
|
|
int *pitch)
|
2006-07-10 21:04:37 +00:00
|
|
|
{
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
|
2006-07-10 21:04:37 +00:00
|
|
|
|
2009-01-03 05:42:18 +00:00
|
|
|
if (data->yuv) {
|
|
|
|
return SDL_SW_LockYUVTexture(data->yuv, rect, markDirty, pixels,
|
|
|
|
pitch);
|
|
|
|
} else {
|
|
|
|
RECT d3drect;
|
|
|
|
D3DLOCKED_RECT locked;
|
|
|
|
HRESULT result;
|
2006-07-14 06:40:53 +00:00
|
|
|
|
2009-01-03 05:42:18 +00:00
|
|
|
d3drect.left = rect->x;
|
|
|
|
d3drect.right = rect->x + rect->w;
|
|
|
|
d3drect.top = rect->y;
|
|
|
|
d3drect.bottom = rect->y + rect->h;
|
|
|
|
|
|
|
|
result =
|
|
|
|
IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect,
|
2009-01-04 17:14:27 +00:00
|
|
|
markDirty ? 0 :
|
|
|
|
D3DLOCK_NO_DIRTY_UPDATE);
|
2009-01-03 05:42:18 +00:00
|
|
|
if (FAILED(result)) {
|
|
|
|
D3D_SetError("LockRect()", result);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
*pixels = locked.pBits;
|
|
|
|
*pitch = locked.Pitch;
|
|
|
|
return 0;
|
2006-07-10 21:04:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
2006-07-10 21:04:37 +00:00
|
|
|
{
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
|
2006-07-10 21:04:37 +00:00
|
|
|
|
2009-01-03 05:42:18 +00:00
|
|
|
if (data->yuv) {
|
|
|
|
SDL_SW_UnlockYUVTexture(data->yuv);
|
|
|
|
UpdateYUVTextureData(texture);
|
|
|
|
} else {
|
|
|
|
IDirect3DTexture9_UnlockRect(data->texture, 0);
|
|
|
|
}
|
2006-07-10 21:04:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, int numrects,
|
|
|
|
const SDL_Rect * rects)
|
2006-07-10 21:04:37 +00:00
|
|
|
{
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
|
2006-07-14 06:40:53 +00:00
|
|
|
RECT d3drect;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < numrects; ++i) {
|
|
|
|
const SDL_Rect *rect = &rects[i];
|
|
|
|
|
|
|
|
d3drect.left = rect->x;
|
|
|
|
d3drect.right = rect->x + rect->w;
|
|
|
|
d3drect.top = rect->y;
|
|
|
|
d3drect.bottom = rect->y + rect->h;
|
|
|
|
|
|
|
|
IDirect3DTexture9_AddDirtyRect(data->texture, &d3drect);
|
|
|
|
}
|
2006-07-10 21:04:37 +00:00
|
|
|
}
|
|
|
|
|
2008-12-31 06:17:24 +00:00
|
|
|
static void
|
2008-12-31 06:18:33 +00:00
|
|
|
D3D_SetBlendMode(D3D_RenderData * data, int blendMode)
|
2008-12-31 06:17:24 +00:00
|
|
|
{
|
|
|
|
switch (blendMode) {
|
|
|
|
case SDL_BLENDMODE_NONE:
|
|
|
|
IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
|
|
|
|
FALSE);
|
|
|
|
break;
|
|
|
|
case SDL_BLENDMODE_MASK:
|
|
|
|
case SDL_BLENDMODE_BLEND:
|
|
|
|
IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
|
|
|
|
TRUE);
|
|
|
|
IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLEND,
|
|
|
|
D3DBLEND_SRCALPHA);
|
|
|
|
IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
|
|
|
|
D3DBLEND_INVSRCALPHA);
|
|
|
|
break;
|
|
|
|
case SDL_BLENDMODE_ADD:
|
|
|
|
IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
|
|
|
|
TRUE);
|
|
|
|
IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLEND,
|
|
|
|
D3DBLEND_SRCALPHA);
|
|
|
|
IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
|
|
|
|
D3DBLEND_ONE);
|
|
|
|
break;
|
|
|
|
case SDL_BLENDMODE_MOD:
|
|
|
|
IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
|
|
|
|
TRUE);
|
|
|
|
IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLEND,
|
|
|
|
D3DBLEND_ZERO);
|
|
|
|
IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
|
|
|
|
D3DBLEND_SRCCOLOR);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
D3D_RenderPoint(SDL_Renderer * renderer, int x, int y)
|
|
|
|
{
|
|
|
|
D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
|
|
|
|
DWORD color;
|
|
|
|
Vertex vertices[1];
|
|
|
|
HRESULT result;
|
|
|
|
|
|
|
|
if (data->beginScene) {
|
|
|
|
IDirect3DDevice9_BeginScene(data->device);
|
|
|
|
data->beginScene = SDL_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b);
|
|
|
|
|
2009-09-19 05:47:54 +00:00
|
|
|
vertices[0].x = (float) x;
|
|
|
|
vertices[0].y = (float) y;
|
2008-12-31 06:17:24 +00:00
|
|
|
vertices[0].z = 0.0f;
|
|
|
|
vertices[0].rhw = 1.0f;
|
|
|
|
vertices[0].color = color;
|
|
|
|
vertices[0].u = 0.0f;
|
|
|
|
vertices[0].v = 0.0f;
|
|
|
|
|
|
|
|
D3D_SetBlendMode(data, renderer->blendMode);
|
|
|
|
|
2008-12-31 06:18:33 +00:00
|
|
|
result =
|
|
|
|
IDirect3DDevice9_SetTexture(data->device, 0,
|
|
|
|
(IDirect3DBaseTexture9 *) 0);
|
2008-12-31 06:17:24 +00:00
|
|
|
if (FAILED(result)) {
|
|
|
|
D3D_SetError("SetTexture()", result);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
result =
|
|
|
|
IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_POINTLIST, 1,
|
|
|
|
vertices, sizeof(*vertices));
|
|
|
|
if (FAILED(result)) {
|
|
|
|
D3D_SetError("DrawPrimitiveUP()", result);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
D3D_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2)
|
|
|
|
{
|
|
|
|
D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
|
|
|
|
DWORD color;
|
|
|
|
Vertex vertices[2];
|
|
|
|
HRESULT result;
|
|
|
|
|
|
|
|
if (data->beginScene) {
|
|
|
|
IDirect3DDevice9_BeginScene(data->device);
|
|
|
|
data->beginScene = SDL_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b);
|
|
|
|
|
2009-09-19 05:47:54 +00:00
|
|
|
vertices[0].x = (float) x1;
|
|
|
|
vertices[0].y = (float) y1;
|
2008-12-31 06:17:24 +00:00
|
|
|
vertices[0].z = 0.0f;
|
|
|
|
vertices[0].rhw = 1.0f;
|
|
|
|
vertices[0].color = color;
|
|
|
|
vertices[0].u = 0.0f;
|
|
|
|
vertices[0].v = 0.0f;
|
|
|
|
|
2009-09-19 05:47:54 +00:00
|
|
|
vertices[1].x = (float) x2;
|
|
|
|
vertices[1].y = (float) y2;
|
2008-12-31 06:17:24 +00:00
|
|
|
vertices[1].z = 0.0f;
|
|
|
|
vertices[1].rhw = 1.0f;
|
|
|
|
vertices[1].color = color;
|
|
|
|
vertices[1].u = 0.0f;
|
|
|
|
vertices[1].v = 0.0f;
|
|
|
|
|
|
|
|
D3D_SetBlendMode(data, renderer->blendMode);
|
|
|
|
|
2008-12-31 06:18:33 +00:00
|
|
|
result =
|
|
|
|
IDirect3DDevice9_SetTexture(data->device, 0,
|
|
|
|
(IDirect3DBaseTexture9 *) 0);
|
2008-12-31 06:17:24 +00:00
|
|
|
if (FAILED(result)) {
|
|
|
|
D3D_SetError("SetTexture()", result);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
result =
|
|
|
|
IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_LINELIST, 1,
|
|
|
|
vertices, sizeof(*vertices));
|
|
|
|
if (FAILED(result)) {
|
|
|
|
D3D_SetError("DrawPrimitiveUP()", result);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-07-10 21:04:37 +00:00
|
|
|
static int
|
2008-12-25 05:16:18 +00:00
|
|
|
D3D_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect)
|
2006-07-10 21:04:37 +00:00
|
|
|
{
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
|
2008-12-31 06:17:24 +00:00
|
|
|
float minx, miny, maxx, maxy;
|
|
|
|
DWORD color;
|
|
|
|
Vertex vertices[4];
|
2006-07-12 09:25:17 +00:00
|
|
|
HRESULT result;
|
2006-07-10 21:04:37 +00:00
|
|
|
|
2006-07-12 09:25:17 +00:00
|
|
|
if (data->beginScene) {
|
|
|
|
IDirect3DDevice9_BeginScene(data->device);
|
|
|
|
data->beginScene = SDL_FALSE;
|
|
|
|
}
|
2006-07-10 21:04:37 +00:00
|
|
|
|
2009-09-19 05:47:54 +00:00
|
|
|
minx = (float) rect->x;
|
|
|
|
miny = (float) rect->y;
|
|
|
|
maxx = (float) rect->x + rect->w;
|
|
|
|
maxy = (float) rect->y + rect->h;
|
2008-12-31 06:17:24 +00:00
|
|
|
|
|
|
|
color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b);
|
2006-07-13 08:13:02 +00:00
|
|
|
|
2008-12-31 06:17:24 +00:00
|
|
|
vertices[0].x = minx;
|
|
|
|
vertices[0].y = miny;
|
|
|
|
vertices[0].z = 0.0f;
|
|
|
|
vertices[0].rhw = 1.0f;
|
|
|
|
vertices[0].color = color;
|
|
|
|
vertices[0].u = 0.0f;
|
|
|
|
vertices[0].v = 0.0f;
|
|
|
|
|
|
|
|
vertices[1].x = maxx;
|
|
|
|
vertices[1].y = miny;
|
|
|
|
vertices[1].z = 0.0f;
|
|
|
|
vertices[1].rhw = 1.0f;
|
|
|
|
vertices[1].color = color;
|
|
|
|
vertices[1].u = 0.0f;
|
|
|
|
vertices[1].v = 0.0f;
|
|
|
|
|
|
|
|
vertices[2].x = maxx;
|
|
|
|
vertices[2].y = maxy;
|
|
|
|
vertices[2].z = 0.0f;
|
|
|
|
vertices[2].rhw = 1.0f;
|
|
|
|
vertices[2].color = color;
|
|
|
|
vertices[2].u = 0.0f;
|
|
|
|
vertices[2].v = 0.0f;
|
|
|
|
|
|
|
|
vertices[3].x = minx;
|
|
|
|
vertices[3].y = maxy;
|
|
|
|
vertices[3].z = 0.0f;
|
|
|
|
vertices[3].rhw = 1.0f;
|
|
|
|
vertices[3].color = color;
|
|
|
|
vertices[3].u = 0.0f;
|
|
|
|
vertices[3].v = 0.0f;
|
|
|
|
|
|
|
|
D3D_SetBlendMode(data, renderer->blendMode);
|
|
|
|
|
2008-12-31 06:18:33 +00:00
|
|
|
result =
|
|
|
|
IDirect3DDevice9_SetTexture(data->device, 0,
|
|
|
|
(IDirect3DBaseTexture9 *) 0);
|
2008-12-31 06:17:24 +00:00
|
|
|
if (FAILED(result)) {
|
|
|
|
D3D_SetError("SetTexture()", result);
|
|
|
|
return -1;
|
|
|
|
}
|
2006-07-14 06:40:53 +00:00
|
|
|
result =
|
2008-12-31 06:17:24 +00:00
|
|
|
IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2,
|
|
|
|
vertices, sizeof(*vertices));
|
2006-07-12 09:25:17 +00:00
|
|
|
if (FAILED(result)) {
|
2008-12-31 06:17:24 +00:00
|
|
|
D3D_SetError("DrawPrimitiveUP()", result);
|
2006-07-12 09:25:17 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2006-07-10 21:04:37 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
|
2006-08-28 03:17:39 +00:00
|
|
|
const SDL_Rect * srcrect, const SDL_Rect * dstrect)
|
2006-07-10 21:04:37 +00:00
|
|
|
{
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
|
|
|
|
D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata;
|
2006-07-14 06:40:53 +00:00
|
|
|
float minx, miny, maxx, maxy;
|
2006-07-14 07:41:16 +00:00
|
|
|
float minu, maxu, minv, maxv;
|
2006-08-28 04:03:32 +00:00
|
|
|
DWORD color;
|
2006-07-14 06:40:53 +00:00
|
|
|
Vertex vertices[4];
|
|
|
|
HRESULT result;
|
2006-07-10 21:04:37 +00:00
|
|
|
|
2006-07-12 09:25:17 +00:00
|
|
|
if (data->beginScene) {
|
|
|
|
IDirect3DDevice9_BeginScene(data->device);
|
|
|
|
data->beginScene = SDL_FALSE;
|
|
|
|
}
|
2006-07-14 06:40:53 +00:00
|
|
|
|
2009-09-19 12:48:52 +00:00
|
|
|
minx = (float) dstrect->x - 0.5f;
|
|
|
|
miny = (float) dstrect->y - 0.5f;
|
|
|
|
maxx = (float) dstrect->x + dstrect->w - 0.5f;
|
|
|
|
maxy = (float) dstrect->y + dstrect->h - 0.5f;
|
2006-07-14 06:40:53 +00:00
|
|
|
|
2006-07-14 07:41:16 +00:00
|
|
|
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;
|
2006-07-14 06:40:53 +00:00
|
|
|
|
2006-08-28 04:03:32 +00:00
|
|
|
color = D3DCOLOR_ARGB(texture->a, texture->r, texture->g, texture->b);
|
|
|
|
|
2006-07-14 06:40:53 +00:00
|
|
|
vertices[0].x = minx;
|
|
|
|
vertices[0].y = miny;
|
|
|
|
vertices[0].z = 0.0f;
|
2006-07-14 07:41:16 +00:00
|
|
|
vertices[0].rhw = 1.0f;
|
2006-08-28 04:03:32 +00:00
|
|
|
vertices[0].color = color;
|
2006-07-14 07:41:16 +00:00
|
|
|
vertices[0].u = minu;
|
|
|
|
vertices[0].v = minv;
|
|
|
|
|
2006-07-14 06:40:53 +00:00
|
|
|
vertices[1].x = maxx;
|
|
|
|
vertices[1].y = miny;
|
|
|
|
vertices[1].z = 0.0f;
|
2006-07-14 07:41:16 +00:00
|
|
|
vertices[1].rhw = 1.0f;
|
2006-08-28 04:03:32 +00:00
|
|
|
vertices[1].color = color;
|
2006-07-14 07:41:16 +00:00
|
|
|
vertices[1].u = maxu;
|
|
|
|
vertices[1].v = minv;
|
|
|
|
|
2006-07-14 06:40:53 +00:00
|
|
|
vertices[2].x = maxx;
|
|
|
|
vertices[2].y = maxy;
|
|
|
|
vertices[2].z = 0.0f;
|
2006-07-14 07:41:16 +00:00
|
|
|
vertices[2].rhw = 1.0f;
|
2006-08-28 04:03:32 +00:00
|
|
|
vertices[2].color = color;
|
2006-07-14 07:41:16 +00:00
|
|
|
vertices[2].u = maxu;
|
|
|
|
vertices[2].v = maxv;
|
|
|
|
|
2006-07-14 06:40:53 +00:00
|
|
|
vertices[3].x = minx;
|
|
|
|
vertices[3].y = maxy;
|
|
|
|
vertices[3].z = 0.0f;
|
2006-07-14 07:41:16 +00:00
|
|
|
vertices[3].rhw = 1.0f;
|
2006-08-28 04:03:32 +00:00
|
|
|
vertices[3].color = color;
|
2006-07-14 07:41:16 +00:00
|
|
|
vertices[3].u = minu;
|
|
|
|
vertices[3].v = maxv;
|
2006-07-14 06:40:53 +00:00
|
|
|
|
2008-12-31 06:17:24 +00:00
|
|
|
D3D_SetBlendMode(data, texture->blendMode);
|
2006-07-19 05:03:21 +00:00
|
|
|
|
2006-08-28 03:17:39 +00:00
|
|
|
switch (texture->scaleMode) {
|
2006-08-05 17:09:42 +00:00
|
|
|
case SDL_TEXTURESCALEMODE_NONE:
|
|
|
|
case SDL_TEXTURESCALEMODE_FAST:
|
2006-07-19 05:45:42 +00:00
|
|
|
IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MINFILTER,
|
|
|
|
D3DTEXF_POINT);
|
|
|
|
IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MAGFILTER,
|
|
|
|
D3DTEXF_POINT);
|
|
|
|
break;
|
2006-08-05 17:09:42 +00:00
|
|
|
case SDL_TEXTURESCALEMODE_SLOW:
|
2006-07-19 05:45:42 +00:00
|
|
|
IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MINFILTER,
|
|
|
|
D3DTEXF_LINEAR);
|
|
|
|
IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MAGFILTER,
|
|
|
|
D3DTEXF_LINEAR);
|
|
|
|
break;
|
2006-08-05 17:09:42 +00:00
|
|
|
case SDL_TEXTURESCALEMODE_BEST:
|
2006-07-19 05:45:42 +00:00
|
|
|
IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MINFILTER,
|
|
|
|
D3DTEXF_GAUSSIANQUAD);
|
|
|
|
IDirect3DDevice9_SetSamplerState(data->device, 0, D3DSAMP_MAGFILTER,
|
|
|
|
D3DTEXF_GAUSSIANQUAD);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-07-14 06:40:53 +00:00
|
|
|
result =
|
2008-08-27 15:10:03 +00:00
|
|
|
IDirect3DDevice9_SetTexture(data->device, 0, (IDirect3DBaseTexture9 *)
|
|
|
|
texturedata->texture);
|
2006-07-14 06:40:53 +00:00
|
|
|
if (FAILED(result)) {
|
|
|
|
D3D_SetError("SetTexture()", result);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
result =
|
|
|
|
IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2,
|
|
|
|
vertices, sizeof(*vertices));
|
|
|
|
if (FAILED(result)) {
|
|
|
|
D3D_SetError("DrawPrimitiveUP()", result);
|
|
|
|
return -1;
|
|
|
|
}
|
2006-07-10 21:04:37 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-11-09 05:20:11 +00:00
|
|
|
static int
|
|
|
|
D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
2009-11-22 06:37:43 +00:00
|
|
|
Uint32 format, void * pixels, int pitch)
|
2009-11-09 05:20:11 +00:00
|
|
|
{
|
|
|
|
BYTE * pBytes;
|
|
|
|
D3DLOCKED_RECT lockedRect;
|
|
|
|
BYTE b, g, r, a;
|
|
|
|
unsigned long index;
|
|
|
|
int cur_mouse;
|
|
|
|
int x, y;
|
|
|
|
|
|
|
|
LPDIRECT3DSURFACE9 backBuffer;
|
|
|
|
LPDIRECT3DSURFACE9 pickOffscreenSurface;
|
|
|
|
D3DSURFACE_DESC desc;
|
|
|
|
|
|
|
|
D3D_RenderData * data = (D3D_RenderData *) renderer->driverdata;
|
|
|
|
|
|
|
|
IDirect3DDevice9_GetBackBuffer(data->device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer);
|
|
|
|
|
|
|
|
|
|
|
|
IDirect3DSurface9_GetDesc(backBuffer, &desc);
|
|
|
|
|
|
|
|
IDirect3DDevice9_CreateOffscreenPlainSurface(data->device, desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &pickOffscreenSurface, NULL);
|
|
|
|
|
|
|
|
IDirect3DDevice9_GetRenderTargetData(data->device, backBuffer, pickOffscreenSurface);
|
|
|
|
|
|
|
|
IDirect3DSurface9_LockRect(pickOffscreenSurface, &lockedRect, NULL, D3DLOCK_READONLY);
|
|
|
|
pBytes = (BYTE*)lockedRect.pBits;
|
|
|
|
IDirect3DSurface9_UnlockRect(pickOffscreenSurface);
|
|
|
|
|
|
|
|
// just to debug -->
|
|
|
|
cur_mouse = SDL_SelectMouse(-1);
|
|
|
|
SDL_GetMouseState(cur_mouse, &x, &y);
|
|
|
|
index = (x * 4 + (y * lockedRect.Pitch));
|
|
|
|
|
|
|
|
b = pBytes[index];
|
|
|
|
g = pBytes[index+1];
|
|
|
|
r = pBytes[index+2];
|
|
|
|
a = pBytes[index+3];
|
|
|
|
// <--
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-11-22 06:37:43 +00:00
|
|
|
static int
|
|
|
|
D3D_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
|
|
|
Uint32 format, const void * pixels, int pitch)
|
|
|
|
{
|
|
|
|
/* Work in progress */
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2006-07-10 21:04:37 +00:00
|
|
|
static void
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_RenderPresent(SDL_Renderer * renderer)
|
2006-07-10 21:04:37 +00:00
|
|
|
{
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
|
2006-07-12 09:25:17 +00:00
|
|
|
HRESULT result;
|
|
|
|
|
|
|
|
if (!data->beginScene) {
|
|
|
|
IDirect3DDevice9_EndScene(data->device);
|
|
|
|
data->beginScene = SDL_TRUE;
|
|
|
|
}
|
|
|
|
|
2006-08-07 05:24:13 +00:00
|
|
|
result = IDirect3DDevice9_TestCooperativeLevel(data->device);
|
|
|
|
if (result == D3DERR_DEVICELOST) {
|
|
|
|
/* We'll reset later */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (result == D3DERR_DEVICENOTRESET) {
|
|
|
|
D3D_Reset(renderer);
|
|
|
|
}
|
2006-07-12 09:25:17 +00:00
|
|
|
result = IDirect3DDevice9_Present(data->device, NULL, NULL, NULL, NULL);
|
|
|
|
if (FAILED(result)) {
|
|
|
|
D3D_SetError("Present()", result);
|
|
|
|
}
|
2006-07-10 21:04:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
2006-07-10 21:04:37 +00:00
|
|
|
{
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
|
2006-07-10 21:04:37 +00:00
|
|
|
|
|
|
|
if (!data) {
|
|
|
|
return;
|
|
|
|
}
|
2009-01-03 05:42:18 +00:00
|
|
|
if (data->yuv) {
|
|
|
|
SDL_SW_DestroyYUVTexture(data->yuv);
|
|
|
|
}
|
2006-07-14 06:40:53 +00:00
|
|
|
if (data->texture) {
|
|
|
|
IDirect3DTexture9_Release(data->texture);
|
|
|
|
}
|
2006-07-10 21:04:37 +00:00
|
|
|
SDL_free(data);
|
|
|
|
texture->driverdata = NULL;
|
|
|
|
}
|
|
|
|
|
2006-08-07 05:24:13 +00:00
|
|
|
static void
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_DestroyRenderer(SDL_Renderer * renderer)
|
2006-07-10 21:04:37 +00:00
|
|
|
{
|
2006-07-17 06:47:33 +00:00
|
|
|
D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
|
2006-07-10 21:04:37 +00:00
|
|
|
|
|
|
|
if (data) {
|
2006-07-12 09:25:17 +00:00
|
|
|
if (data->device) {
|
|
|
|
IDirect3DDevice9_Release(data->device);
|
|
|
|
}
|
2006-07-10 21:04:37 +00:00
|
|
|
SDL_free(data);
|
|
|
|
}
|
|
|
|
SDL_free(renderer);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* SDL_VIDEO_RENDER_D3D */
|
|
|
|
|
|
|
|
/* vi: set ts=4 sw=4 expandtab: */
|