diff src/video/win32/SDL_d3drender.c @ 1900:5c6bdbf3aadf

First stab at a D3D renderer, only 30FPS so far... ?
author Sam Lantinga <slouken@libsdl.org>
date Wed, 12 Jul 2006 09:25:17 +0000
parents f89e49e51e89
children f1828a500391
line wrap: on
line diff
--- a/src/video/win32/SDL_d3drender.c	Wed Jul 12 08:09:57 2006 +0000
+++ b/src/video/win32/SDL_d3drender.c	Wed Jul 12 09:25:17 2006 +0000
@@ -78,10 +78,10 @@
     SDL_D3D_CreateRenderer,
     {
      "d3d",
-     (SDL_Renderer_Minimal |
-      SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy |
-      SDL_Renderer_PresentFlip2 | SDL_Renderer_PresentFlip3 |
-      SDL_Renderer_PresentDiscard | SDL_Renderer_RenderTarget),
+     (                          //SDL_Renderer_Minimal |
+         SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy |
+         SDL_Renderer_PresentFlip2 | SDL_Renderer_PresentFlip3 |
+         SDL_Renderer_PresentDiscard | SDL_Renderer_RenderTarget),
      (SDL_TextureBlendMode_None |
       SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend),
      (SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast),
@@ -105,6 +105,7 @@
 typedef struct
 {
     IDirect3DDevice9 *device;
+    SDL_bool beginScene;
 } SDL_D3D_RenderData;
 
 typedef struct
@@ -113,6 +114,85 @@
 } SDL_D3D_TextureData;
 
 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);
+}
+
+static void
 UpdateYUVTextureData(SDL_Texture * texture)
 {
     SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata;
@@ -144,6 +224,8 @@
     SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata;
     SDL_Renderer *renderer;
     SDL_D3D_RenderData *data;
+    HRESULT result;
+    D3DPRESENT_PARAMETERS pparams;
 
     renderer = (SDL_Renderer *) SDL_malloc(sizeof(*renderer));
     if (!renderer) {
@@ -160,8 +242,6 @@
     }
     SDL_zerop(data);
 
-    //data->device = IDirect3D9_CreateDevice(videodata->d3d,
-
     renderer->CreateTexture = SDL_D3D_CreateTexture;
     renderer->QueryTexturePixels = SDL_D3D_QueryTexturePixels;
     renderer->SetTexturePalette = SDL_D3D_SetTexturePalette;
@@ -184,6 +264,42 @@
 
     renderer->info.flags = SDL_Renderer_RenderTarget;
 
+    SDL_zero(pparams);
+    pparams.BackBufferWidth = window->w;
+    pparams.BackBufferHeight = window->h;
+    pparams.BackBufferFormat = D3DFMT_UNKNOWN;  /* FIXME */
+    if (flags & SDL_Renderer_PresentFlip2) {
+        pparams.BackBufferCount = 2;
+        pparams.SwapEffect = D3DSWAPEFFECT_FLIP;
+    } else if (flags & SDL_Renderer_PresentFlip3) {
+        pparams.BackBufferCount = 3;
+        pparams.SwapEffect = D3DSWAPEFFECT_FLIP;
+    } else if (flags & SDL_Renderer_PresentCopy) {
+        pparams.BackBufferCount = 1;
+        pparams.SwapEffect = D3DSWAPEFFECT_COPY;
+    } else {
+        pparams.BackBufferCount = 1;
+        pparams.SwapEffect = D3DSWAPEFFECT_DISCARD;
+    }
+    if (window->flags & SDL_WINDOW_FULLSCREEN) {
+        pparams.Windowed = FALSE;
+    } else {
+        pparams.Windowed = TRUE;
+    }
+    pparams.FullScreen_RefreshRateInHz = 0;     /* FIXME */
+
+    result = IDirect3D9_CreateDevice(videodata->d3d, D3DADAPTER_DEFAULT,        /* FIXME */
+                                     D3DDEVTYPE_HAL,
+                                     windowdata->hwnd,
+                                     D3DCREATE_SOFTWARE_VERTEXPROCESSING,
+                                     &pparams, &data->device);
+    if (FAILED(result)) {
+        SDL_D3D_DestroyRenderer(renderer);
+        D3D_SetError("CreateDevice()", result);
+        return NULL;
+    }
+    data->beginScene = SDL_TRUE;
+
     return renderer;
 }
 
@@ -283,7 +399,7 @@
         return SDL_SW_LockYUVTexture(data->yuv, rect, markDirty, pixels,
                                      pitch);
     } else {
-        return 0;
+        return -1;
     }
 }
 
@@ -315,12 +431,20 @@
                    Uint32 color)
 {
     SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata;
-    Uint8 r, g, b;
+    HRESULT result;
+
+    if (data->beginScene) {
+        IDirect3DDevice9_BeginScene(data->device);
+        data->beginScene = SDL_FALSE;
+    }
 
-    r = (Uint8) ((color >> 16) & 0xFF);
-    g = (Uint8) ((color >> 8) & 0xFF);
-    b = (Uint8) (color & 0xFF);
-
+    result =
+        IDirect3DDevice9_Clear(data->device, 0, NULL, D3DCLEAR_TARGET,
+                               (D3DCOLOR) color, 1.0f, 0);
+    if (FAILED(result)) {
+        D3D_SetError("Clear()", result);
+        return -1;
+    }
     return 0;
 }
 
@@ -333,6 +457,10 @@
     SDL_D3D_TextureData *texturedata =
         (SDL_D3D_TextureData *) texture->driverdata;
 
+    if (data->beginScene) {
+        IDirect3DDevice9_BeginScene(data->device);
+        data->beginScene = SDL_FALSE;
+    }
     return 0;
 }
 
@@ -357,6 +485,18 @@
 static void
 SDL_D3D_RenderPresent(SDL_Renderer * renderer)
 {
+    SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata;
+    HRESULT result;
+
+    if (!data->beginScene) {
+        IDirect3DDevice9_EndScene(data->device);
+        data->beginScene = SDL_TRUE;
+    }
+
+    result = IDirect3DDevice9_Present(data->device, NULL, NULL, NULL, NULL);
+    if (FAILED(result)) {
+        D3D_SetError("Present()", result);
+    }
 }
 
 static void
@@ -377,6 +517,9 @@
     SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata;
 
     if (data) {
+        if (data->device) {
+            IDirect3DDevice9_Release(data->device);
+        }
         SDL_free(data);
     }
     SDL_free(renderer);