SDL_Renderer * D3D_CreateRenderer(SDL_Window * window, Uint32 flags) { SDL_VideoDisplay *display = window->display; SDL_VideoData *videodata = (SDL_VideoData *) display->device->driverdata; SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; SDL_Renderer *renderer; D3D_RenderData *data; HRESULT result; D3DPRESENT_PARAMETERS pparams; IDirect3DSwapChain9 *chain; D3DCAPS9 caps; renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); if (!renderer) { SDL_OutOfMemory(); return NULL; } data = (D3D_RenderData *) SDL_calloc(1, sizeof(*data)); if (!data) { D3D_DestroyRenderer(renderer); SDL_OutOfMemory(); return NULL; } data->d3d = videodata->d3d; videodata->render = RENDER_D3D; renderer->DisplayModeChanged = D3D_DisplayModeChanged; renderer->CreateTexture = D3D_CreateTexture; renderer->QueryTexturePixels = D3D_QueryTexturePixels; renderer->SetTexturePalette = D3D_SetTexturePalette; renderer->GetTexturePalette = D3D_GetTexturePalette; renderer->SetTextureColorMod = D3D_SetTextureColorMod; renderer->SetTextureAlphaMod = D3D_SetTextureAlphaMod; renderer->SetTextureBlendMode = D3D_SetTextureBlendMode; renderer->SetTextureScaleMode = D3D_SetTextureScaleMode; renderer->UpdateTexture = D3D_UpdateTexture; renderer->LockTexture = D3D_LockTexture; renderer->UnlockTexture = D3D_UnlockTexture; renderer->DirtyTexture = D3D_DirtyTexture; renderer->RenderDrawPoints = D3D_RenderDrawPoints; renderer->RenderDrawLines = D3D_RenderDrawLines; renderer->RenderDrawRects = D3D_RenderDrawRects; renderer->RenderFillRects = D3D_RenderFillRects; renderer->RenderCopy = D3D_RenderCopy; renderer->RenderReadPixels = D3D_RenderReadPixels; renderer->RenderWritePixels = D3D_RenderWritePixels; renderer->RenderPresent = D3D_RenderPresent; renderer->DestroyTexture = D3D_DestroyTexture; renderer->DestroyRenderer = D3D_DestroyRenderer; renderer->info = D3D_RenderDriver.info; renderer->window = window; renderer->driverdata = data; renderer->info.flags = SDL_RENDERER_ACCELERATED; SDL_zero(pparams); pparams.BackBufferWidth = window->w; pparams.BackBufferHeight = window->h; if (window->flags & SDL_WINDOW_FULLSCREEN) { pparams.BackBufferFormat = PixelFormatToD3DFMT(window->fullscreen_mode.format); } else { pparams.BackBufferFormat = D3DFMT_UNKNOWN; } 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; pparams.FullScreen_RefreshRateInHz = window->fullscreen_mode.refresh_rate; } else { pparams.Windowed = TRUE; pparams.FullScreen_RefreshRateInHz = 0; } if (flags & SDL_RENDERER_PRESENTVSYNC) { pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE; } else { pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; } data->adapter = D3D_FindAdapter(videodata->d3d, display); IDirect3D9_GetDeviceCaps(videodata->d3d, data->adapter, D3DDEVTYPE_HAL, &caps); result = IDirect3D9_CreateDevice(videodata->d3d, data->adapter, D3DDEVTYPE_HAL, windowdata->hwnd, (caps. DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) ? D3DCREATE_HARDWARE_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING, &pparams, &data->device); if (FAILED(result)) { D3D_DestroyRenderer(renderer); D3D_SetError("CreateDevice()", result); return NULL; } data->beginScene = SDL_TRUE; /* Get presentation parameters to fill info */ result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain); if (FAILED(result)) { D3D_DestroyRenderer(renderer); D3D_SetError("GetSwapChain()", result); return NULL; } result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams); if (FAILED(result)) { IDirect3DSwapChain9_Release(chain); D3D_DestroyRenderer(renderer); D3D_SetError("GetPresentParameters()", result); return NULL; } IDirect3DSwapChain9_Release(chain); switch (pparams.SwapEffect) { case D3DSWAPEFFECT_COPY: renderer->info.flags |= SDL_RENDERER_PRESENTCOPY; break; case D3DSWAPEFFECT_FLIP: switch (pparams.BackBufferCount) { case 2: renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2; break; case 3: renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3; break; } break; case D3DSWAPEFFECT_DISCARD: renderer->info.flags |= SDL_RENDERER_PRESENTDISCARD; break; } if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) { renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; } data->pparams = pparams; IDirect3DDevice9_GetDeviceCaps(data->device, &caps); renderer->info.max_texture_width = caps.MaxTextureWidth; renderer->info.max_texture_height = caps.MaxTextureHeight; /* Set up parameters for rendering */ IDirect3DDevice9_SetVertexShader(data->device, NULL); IDirect3DDevice9_SetFVF(data->device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); IDirect3DDevice9_SetRenderState(data->device, D3DRS_ZENABLE, D3DZB_FALSE); IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE, D3DCULL_NONE); IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE); /* 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); /* 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); { #ifdef ASSEMBLE_SHADER const char *shader_text = "ps_1_1\n" "def c0, 0, 0, 0, 0.496\n" "def c1, 0, 0, 0, 1\n" "def c2, 0, 0, 0, -1\n" "tex t0\n" "mul r1, t0, v0\n" "add r0, r1, c0\n" "cnd r0, r0.a, c1, c2\n" "add r0, r0, r1\n"; LPD3DXBUFFER pCode; // buffer with the assembled shader code LPD3DXBUFFER pErrorMsgs; // buffer with error messages LPDWORD shader_data; DWORD shader_size; result = D3DXAssembleShader( shader_text, SDL_strlen(shader_text), NULL, NULL, 0, &pCode, &pErrorMsgs ); if (FAILED(result)) { D3D_SetError("D3DXAssembleShader()", result); } shader_data = (DWORD*)pCode->lpVtbl->GetBufferPointer(pCode); shader_size = pCode->lpVtbl->GetBufferSize(pCode); #else const DWORD shader_data[] = { 0xffff0101,0x00000051,0xa00f0000,0x00000000,0x00000000,0x00000000, 0x3efdf3b6,0x00000051,0xa00f0001,0x00000000,0x00000000,0x00000000, 0x3f800000,0x00000051,0xa00f0002,0x00000000,0x00000000,0x00000000, 0xbf800000,0x00000042,0xb00f0000,0x00000005,0x800f0001,0xb0e40000, 0x90e40000,0x00000002,0x800f0000,0x80e40001,0xa0e40000,0x00000050, 0x800f0000,0x80ff0000,0xa0e40001,0xa0e40002,0x00000002,0x800f0000, 0x80e40000,0x80e40001,0x0000ffff }; #endif result = IDirect3DDevice9_CreatePixelShader(data->device, shader_data, &data->ps_mask); if (FAILED(result)) { D3D_SetError("CreatePixelShader()", result); } } return renderer; }
SDL_Renderer * D3D_CreateRenderer(SDL_Window * window, Uint32 flags) { SDL_Renderer *renderer; D3D_RenderData *data; SDL_SysWMinfo windowinfo; HRESULT result; D3DPRESENT_PARAMETERS pparams; IDirect3DSwapChain9 *chain; D3DCAPS9 caps; Uint32 window_flags; int w, h; SDL_DisplayMode fullscreen_mode; D3DMATRIX matrix; renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); if (!renderer) { SDL_OutOfMemory(); return NULL; } data = (D3D_RenderData *) SDL_calloc(1, sizeof(*data)); if (!data) { SDL_free(renderer); SDL_OutOfMemory(); return NULL; } data->d3dDLL = SDL_LoadObject("D3D9.DLL"); if (data->d3dDLL) { IDirect3D9 *(WINAPI * D3DCreate) (UINT SDKVersion); D3DCreate = (IDirect3D9 * (WINAPI *) (UINT)) SDL_LoadFunction(data->d3dDLL, "Direct3DCreate9"); if (D3DCreate) { data->d3d = D3DCreate(D3D_SDK_VERSION); } if (!data->d3d) { SDL_UnloadObject(data->d3dDLL); data->d3dDLL = NULL; } } if (!data->d3d) { SDL_free(renderer); SDL_free(data); SDL_SetError("Unable to create Direct3D interface"); return NULL; } renderer->WindowEvent = D3D_WindowEvent; renderer->CreateTexture = D3D_CreateTexture; renderer->UpdateTexture = D3D_UpdateTexture; renderer->LockTexture = D3D_LockTexture; renderer->UnlockTexture = D3D_UnlockTexture; renderer->SetRenderTarget = D3D_SetRenderTarget; 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->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_VERSION(&windowinfo.version); SDL_GetWindowWMInfo(window, &windowinfo); window_flags = SDL_GetWindowFlags(window); SDL_GetWindowSize(window, &w, &h); SDL_GetWindowDisplayMode(window, &fullscreen_mode); SDL_zero(pparams); pparams.hDeviceWindow = windowinfo.info.win.window; pparams.BackBufferWidth = w; pparams.BackBufferHeight = h; if (window_flags & SDL_WINDOW_FULLSCREEN) { pparams.BackBufferFormat = PixelFormatToD3DFMT(fullscreen_mode.format); } else { pparams.BackBufferFormat = D3DFMT_UNKNOWN; } pparams.BackBufferCount = 1; pparams.SwapEffect = D3DSWAPEFFECT_DISCARD; if (window_flags & SDL_WINDOW_FULLSCREEN) { pparams.Windowed = FALSE; pparams.FullScreen_RefreshRateInHz = fullscreen_mode.refresh_rate; } else { pparams.Windowed = TRUE; pparams.FullScreen_RefreshRateInHz = 0; } if (flags & SDL_RENDERER_PRESENTVSYNC) { pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE; } else { pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; } /* FIXME: Which adapter? */ data->adapter = D3DADAPTER_DEFAULT; IDirect3D9_GetDeviceCaps(data->d3d, data->adapter, D3DDEVTYPE_HAL, &caps); result = IDirect3D9_CreateDevice(data->d3d, data->adapter, D3DDEVTYPE_HAL, pparams.hDeviceWindow, D3DCREATE_FPU_PRESERVE | ((caps. DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) ? D3DCREATE_HARDWARE_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING), &pparams, &data->device); if (FAILED(result)) { D3D_DestroyRenderer(renderer); D3D_SetError("CreateDevice()", result); return NULL; } data->beginScene = SDL_TRUE; data->scaleMode = D3DTEXF_FORCE_DWORD; /* Get presentation parameters to fill info */ result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain); if (FAILED(result)) { D3D_DestroyRenderer(renderer); D3D_SetError("GetSwapChain()", result); return NULL; } result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams); if (FAILED(result)) { IDirect3DSwapChain9_Release(chain); D3D_DestroyRenderer(renderer); D3D_SetError("GetPresentParameters()", result); return NULL; } IDirect3DSwapChain9_Release(chain); if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) { renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; } data->pparams = pparams; 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; } /* Set up parameters for rendering */ IDirect3DDevice9_SetVertexShader(data->device, NULL); IDirect3DDevice9_SetFVF(data->device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1); IDirect3DDevice9_SetRenderState(data->device, D3DRS_ZENABLE, D3DZB_FALSE); IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE, D3DCULL_NONE); IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE); /* 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); /* 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); /* Store the default render target */ IDirect3DDevice9_GetRenderTarget(data->device, 0, &data->defaultRenderTarget ); data->currentRenderTarget = NULL; /* Set 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; IDirect3DDevice9_SetTransform(data->device, D3DTS_WORLD, &matrix); IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, &matrix); return renderer; }
SDL_Renderer * D3D_CreateRenderer(SDL_Window * window, Uint32 flags) { SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); SDL_VideoData *videodata = (SDL_VideoData *) display->device->driverdata; SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; SDL_Renderer *renderer; D3D_RenderData *data; HRESULT result; D3DPRESENT_PARAMETERS pparams; IDirect3DSwapChain9 *chain; D3DCAPS9 caps; renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); if (!renderer) { SDL_OutOfMemory(); return NULL; } data = (D3D_RenderData *) SDL_calloc(1, sizeof(*data)); if (!data) { D3D_DestroyRenderer(renderer); SDL_OutOfMemory(); return NULL; } data->d3d = videodata->d3d; renderer->DisplayModeChanged = D3D_DisplayModeChanged; renderer->CreateTexture = D3D_CreateTexture; renderer->QueryTexturePixels = D3D_QueryTexturePixels; renderer->SetTexturePalette = D3D_SetTexturePalette; renderer->GetTexturePalette = D3D_GetTexturePalette; renderer->SetTextureColorMod = D3D_SetTextureColorMod; renderer->SetTextureAlphaMod = D3D_SetTextureAlphaMod; renderer->SetTextureBlendMode = D3D_SetTextureBlendMode; renderer->SetTextureScaleMode = D3D_SetTextureScaleMode; renderer->UpdateTexture = D3D_UpdateTexture; renderer->LockTexture = D3D_LockTexture; renderer->UnlockTexture = D3D_UnlockTexture; renderer->DirtyTexture = D3D_DirtyTexture; renderer->RenderPoint = D3D_RenderPoint; renderer->RenderLine = D3D_RenderLine; renderer->RenderFill = D3D_RenderFill; renderer->RenderCopy = D3D_RenderCopy; renderer->RenderPresent = D3D_RenderPresent; renderer->DestroyTexture = D3D_DestroyTexture; renderer->DestroyRenderer = D3D_DestroyRenderer; renderer->info = D3D_RenderDriver.info; renderer->window = window->id; renderer->driverdata = data; renderer->info.flags = SDL_RENDERER_ACCELERATED; SDL_zero(pparams); pparams.BackBufferWidth = window->w; pparams.BackBufferHeight = window->h; if (window->flags & SDL_WINDOW_FULLSCREEN) { pparams.BackBufferFormat = PixelFormatToD3DFMT(display->fullscreen_mode.format); } else { pparams.BackBufferFormat = D3DFMT_UNKNOWN; } 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; pparams.FullScreen_RefreshRateInHz = display->fullscreen_mode.refresh_rate; } else { pparams.Windowed = TRUE; pparams.FullScreen_RefreshRateInHz = 0; } if (flags & SDL_RENDERER_PRESENTVSYNC) { pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE; } else { pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; } IDirect3D9_GetDeviceCaps(videodata->d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps); result = IDirect3D9_CreateDevice(videodata->d3d, D3DADAPTER_DEFAULT, /* FIXME */ D3DDEVTYPE_HAL, windowdata->hwnd, (caps. DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) ? D3DCREATE_HARDWARE_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING, &pparams, &data->device); if (FAILED(result)) { D3D_DestroyRenderer(renderer); D3D_SetError("CreateDevice()", result); return NULL; } data->beginScene = SDL_TRUE; /* Get presentation parameters to fill info */ result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain); if (FAILED(result)) { D3D_DestroyRenderer(renderer); D3D_SetError("GetSwapChain()", result); return NULL; } result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams); if (FAILED(result)) { IDirect3DSwapChain9_Release(chain); D3D_DestroyRenderer(renderer); D3D_SetError("GetPresentParameters()", result); return NULL; } IDirect3DSwapChain9_Release(chain); switch (pparams.SwapEffect) { case D3DSWAPEFFECT_COPY: renderer->info.flags |= SDL_RENDERER_PRESENTCOPY; break; case D3DSWAPEFFECT_FLIP: switch (pparams.BackBufferCount) { case 2: renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2; break; case 3: renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3; break; } break; case D3DSWAPEFFECT_DISCARD: renderer->info.flags |= SDL_RENDERER_PRESENTDISCARD; break; } if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) { renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; } data->pparams = pparams; IDirect3DDevice9_GetDeviceCaps(data->device, &caps); renderer->info.max_texture_width = caps.MaxTextureWidth; renderer->info.max_texture_height = caps.MaxTextureHeight; /* Set up parameters for rendering */ IDirect3DDevice9_SetVertexShader(data->device, NULL); IDirect3DDevice9_SetFVF(data->device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); IDirect3DDevice9_SetRenderState(data->device, D3DRS_ZENABLE, D3DZB_FALSE); IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE, D3DCULL_NONE); IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE); /* 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); /* 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); return renderer; }