Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Reorganized the render target code, moving the viewport handling to t…
Browse files Browse the repository at this point in the history
…he general code and adding software implementation.
  • Loading branch information
slouken committed Jan 22, 2012
1 parent 552c832 commit 821f9b6
Show file tree
Hide file tree
Showing 7 changed files with 260 additions and 342 deletions.
110 changes: 76 additions & 34 deletions src/render/SDL_render.c
Expand Up @@ -106,11 +106,16 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
SDL_Rect viewport;

SDL_GetWindowSize(window, &w, &h);
viewport.x = (w - renderer->viewport.w) / 2;
viewport.y = (h - renderer->viewport.h) / 2;
viewport.w = renderer->viewport.w;
viewport.h = renderer->viewport.h;
SDL_RenderSetViewport(renderer, &viewport);
if (renderer->target) {
renderer->viewport_backup.x = (w - renderer->viewport_backup.w) / 2;
renderer->viewport_backup.y = (h - renderer->viewport_backup.h) / 2;
} else {
viewport.x = (w - renderer->viewport.w) / 2;
viewport.y = (h - renderer->viewport.h) / 2;
viewport.w = renderer->viewport.w;
viewport.h = renderer->viewport.h;
SDL_RenderSetViewport(renderer, &viewport);
}
} else if (event->window.event == SDL_WINDOWEVENT_MINIMIZED) {
renderer->minimized = SDL_TRUE;
} else if (event->window.event == SDL_WINDOWEVENT_RESTORED) {
Expand Down Expand Up @@ -796,6 +801,72 @@ SDL_UnlockTexture(SDL_Texture * texture)
}
}

SDL_bool
SDL_RenderTargetSupported(SDL_Renderer *renderer)
{
if (!renderer || !renderer->SetTargetTexture) {
return SDL_FALSE;
}
return (renderer->info.flags & SDL_RENDERER_TARGETTEXTURE) != 0;
}

int
SDL_SetTargetTexture(SDL_Renderer *renderer, SDL_Texture *texture)
{
SDL_Rect viewport;

if (!SDL_RenderTargetSupported(renderer)) {
SDL_Unsupported();
return -1;
}
if (texture == renderer->target) {
/* Nothing to do! */
return 0;
}

/* texture == NULL is valid and means reset the target to the window */
if (texture) {
CHECK_TEXTURE_MAGIC(texture, -1);
if (renderer != texture->renderer) {
SDL_SetError("Texture was not created with this renderer");
return -1;
}
if (!(texture->access & SDL_TEXTUREACCESS_TARGET)) {
SDL_SetError("Texture not created with SDL_TEXTUREACCESS_TARGET");
return -1;
}
if (texture->native) {
/* Always render to the native texture */
texture = texture->native;
}
}

if (texture && !renderer->target) {
/* Make a backup of the viewport */
renderer->viewport_backup = renderer->viewport;
}
renderer->target = texture;

if (renderer->SetTargetTexture(renderer, texture) < 0) {
return -1;
}

if (texture) {
viewport.x = 0;
viewport.y = 0;
viewport.w = texture->w;
viewport.h = texture->h;
} else {
viewport = renderer->viewport_backup;
}
if (SDL_RenderSetViewport(renderer, &viewport) < 0) {
return -1;
}

/* All set! */
return 0;
}

int
SDL_RenderSetViewport(SDL_Renderer * renderer, const SDL_Rect * rect)
{
Expand Down Expand Up @@ -1150,35 +1221,6 @@ SDL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
format, pixels, pitch);
}

SDL_bool
SDL_RenderTargetSupported(SDL_Renderer *renderer)
{
if (!renderer || !renderer->SetTargetTexture) {
return SDL_FALSE;
}
return (renderer->info.flags & SDL_RENDERER_TARGETTEXTURE) != 0;
}

int
SDL_SetTargetTexture(SDL_Renderer *renderer, SDL_Texture *texture)
{

if(!renderer) {
return -1;
}
if (!renderer->SetTargetTexture) {
SDL_Unsupported();
return -1;
}
// Warning: texture==NULL is a valid parameter
if( texture ) {
CHECK_TEXTURE_MAGIC(texture, -1);
if(renderer != texture->renderer) return -1;
}

return renderer->SetTargetTexture(renderer, texture);
}

void
SDL_RenderPresent(SDL_Renderer * renderer)
{
Expand Down
4 changes: 3 additions & 1 deletion src/render/SDL_sysrender.h
Expand Up @@ -77,6 +77,7 @@ struct SDL_Renderer
int (*LockTexture) (SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, void **pixels, int *pitch);
void (*UnlockTexture) (SDL_Renderer * renderer, SDL_Texture * texture);
int (*SetTargetTexture) (SDL_Renderer * renderer, SDL_Texture * texture);
int (*UpdateViewport) (SDL_Renderer * renderer);
int (*RenderClear) (SDL_Renderer * renderer);
int (*RenderDrawPoints) (SDL_Renderer * renderer, const SDL_Point * points,
Expand All @@ -87,7 +88,6 @@ struct SDL_Renderer
int count);
int (*RenderCopy) (SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_Rect * dstrect);
int (*SetTargetTexture) (SDL_Renderer * renderer, SDL_Texture * texture);
int (*RenderReadPixels) (SDL_Renderer * renderer, const SDL_Rect * rect,
Uint32 format, void * pixels, int pitch);
void (*RenderPresent) (SDL_Renderer * renderer);
Expand All @@ -104,9 +104,11 @@ struct SDL_Renderer

/* The drawable area within the window */
SDL_Rect viewport;
SDL_Rect viewport_backup;

/* The list of textures */
SDL_Texture *textures;
SDL_Texture *target;

Uint8 r, g, b, a; /**< Color for drawing operations values */
SDL_BlendMode blendMode; /**< The drawing blend mode */
Expand Down
130 changes: 44 additions & 86 deletions src/render/direct3d/SDL_render_d3d.c
Expand Up @@ -99,6 +99,7 @@ static int D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
static int D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, void **pixels, int *pitch);
static void D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
static int D3D_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture);
static int D3D_UpdateViewport(SDL_Renderer * renderer);
static int D3D_RenderClear(SDL_Renderer * renderer);
static int D3D_RenderDrawPoints(SDL_Renderer * renderer,
Expand All @@ -111,7 +112,6 @@ static int D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_Rect * dstrect);
static int D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
Uint32 format, void * pixels, int pitch);
static int D3D_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture);
static void D3D_RenderPresent(SDL_Renderer * renderer);
static void D3D_DestroyTexture(SDL_Renderer * renderer,
SDL_Texture * texture);
Expand Down Expand Up @@ -141,10 +141,6 @@ typedef struct
D3DTEXTUREFILTERTYPE scaleMode;
IDirect3DSurface9 *defaultRenderTarget;
IDirect3DSurface9 *currentRenderTarget;
SDL_bool renderTargetActive;
SDL_Rect viewport_copy;

Uint32 NumSimultaneousRTs;
} D3D_RenderData;

typedef struct
Expand Down Expand Up @@ -392,21 +388,21 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->UpdateTexture = D3D_UpdateTexture;
renderer->LockTexture = D3D_LockTexture;
renderer->UnlockTexture = D3D_UnlockTexture;
renderer->SetTargetTexture = D3D_SetTargetTexture;
renderer->UpdateViewport = D3D_UpdateViewport;
renderer->RenderClear = D3D_RenderClear;
renderer->RenderDrawPoints = D3D_RenderDrawPoints;
renderer->RenderDrawLines = D3D_RenderDrawLines;
renderer->RenderFillRects = D3D_RenderFillRects;
renderer->RenderCopy = D3D_RenderCopy;
renderer->RenderReadPixels = D3D_RenderReadPixels;
renderer->SetTargetTexture = D3D_SetTargetTexture;
renderer->RenderPresent = D3D_RenderPresent;
renderer->DestroyTexture = D3D_DestroyTexture;
renderer->DestroyRenderer = D3D_DestroyRenderer;
renderer->info = D3D_RenderDriver.info;
renderer->driverdata = data;

renderer->info.flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE;
renderer->info.flags = SDL_RENDERER_ACCELERATED;

SDL_VERSION(&windowinfo.version);
SDL_GetWindowWMInfo(window, &windowinfo);
Expand Down Expand Up @@ -486,7 +482,9 @@ 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;
data->NumSimultaneousRTs = caps.NumSimultaneousRTs;
if (caps.NumSimultaneousRTs >= 2) {
renderer->info.flags |= SDL_RENDERER_TARGETTEXTURE;
}

/* Set up parameters for rendering */
IDirect3DDevice9_SetVertexShader(data->device, NULL);
Expand Down Expand Up @@ -519,7 +517,6 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
/* Store the default render target */
IDirect3DDevice9_GetRenderTarget(data->device, 0, &data->defaultRenderTarget );
data->currentRenderTarget = NULL;
data->renderTargetActive = SDL_FALSE;

/* Set an identity world and view matrix */
matrix.m[0][0] = 1.0f;
Expand Down Expand Up @@ -568,79 +565,6 @@ GetScaleQuality(void)
}
}

static int
D3D_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
D3D_TextureData *texturedata;
D3DMATRIX matrix;
HRESULT result;

D3D_ActivateRenderer(renderer);

if (data->NumSimultaneousRTs < 2) {
SDL_Unsupported();
return -1;
}

// Release the previous render target if it wasn't the default one
if (data->currentRenderTarget != NULL) {
IDirect3DSurface9_Release(data->currentRenderTarget);
data->currentRenderTarget = NULL;
}

/* Prepare an identity world and view matrix */
matrix.m[0][0] = 1.0f;
matrix.m[0][1] = 0.0f;
matrix.m[0][2] = 0.0f;
matrix.m[0][3] = 0.0f;
matrix.m[1][0] = 0.0f;
matrix.m[1][1] = 1.0f;
matrix.m[1][2] = 0.0f;
matrix.m[1][3] = 0.0f;
matrix.m[2][0] = 0.0f;
matrix.m[2][1] = 0.0f;
matrix.m[2][2] = 1.0f;
matrix.m[2][3] = 0.0f;
matrix.m[3][0] = 0.0f;
matrix.m[3][1] = 0.0f;
matrix.m[3][2] = 0.0f;
matrix.m[3][3] = 1.0f;

if (texture == NULL) {
if (data->renderTargetActive) {
data->renderTargetActive = SDL_FALSE;
IDirect3DDevice9_SetRenderTarget(data->device, 0, data->defaultRenderTarget );
renderer->viewport = data->viewport_copy;
D3D_UpdateViewport(renderer);
}
return 0;
}
if (renderer != texture->renderer) return -1;

if ( !data->renderTargetActive ) {
data->viewport_copy = renderer->viewport;
}

texturedata = (D3D_TextureData *) texture->driverdata;
result = IDirect3DTexture9_GetSurfaceLevel(texturedata->texture, 0, &data->currentRenderTarget );
if(FAILED(result)) {
return -1;
}
result = IDirect3DDevice9_SetRenderTarget(data->device, 0, data->currentRenderTarget );
if(FAILED(result)) {
return -1;
}

data->renderTargetActive = SDL_TRUE;
renderer->viewport.x = 0;
renderer->viewport.y = 0;
renderer->viewport.w = texture->w;
renderer->viewport.h = texture->h;
D3D_UpdateViewport(renderer);
return 0;
}

static int
D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
Expand Down Expand Up @@ -668,11 +592,10 @@ D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
} else
#endif
if (texture->access == SDL_TEXTUREACCESS_TARGET) {
pool = D3DPOOL_DEFAULT; // D3DPOOL_MANAGED does not work with usage=D3DUSAGE_RENDERTARGET
/* D3DPOOL_MANAGED does not work with D3DUSAGE_RENDERTARGET */
pool = D3DPOOL_DEFAULT;
usage = D3DUSAGE_RENDERTARGET;
}
else
{
} else {
pool = D3DPOOL_MANAGED;
usage = 0;
}
Expand Down Expand Up @@ -810,6 +733,41 @@ D3D_UpdateViewport(SDL_Renderer * renderer)
return 0;
}

static int
D3D_SetTargetTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
D3D_TextureData *texturedata;
HRESULT result;

D3D_ActivateRenderer(renderer);

/* Release the previous render target if it wasn't the default one */
if (data->currentRenderTarget != NULL) {
IDirect3DSurface9_Release(data->currentRenderTarget);
data->currentRenderTarget = NULL;
}

if (texture == NULL) {
IDirect3DDevice9_SetRenderTarget(data->device, 0, data->defaultRenderTarget);
return 0;
}

texturedata = (D3D_TextureData *) texture->driverdata;
result = IDirect3DTexture9_GetSurfaceLevel(texturedata->texture, 0, &data->currentRenderTarget);
if(FAILED(result)) {
D3D_SetError("GetSurfaceLevel()", result);
return -1;
}
result = IDirect3DDevice9_SetRenderTarget(data->device, 0, data->currentRenderTarget);
if(FAILED(result)) {
D3D_SetError("SetRenderTarget()", result);
return -1;
}

return 0;
}

static int
D3D_RenderClear(SDL_Renderer * renderer)
{
Expand Down

0 comments on commit 821f9b6

Please sign in to comment.