From 532f679f8acd28a7d2c47ca22d2b545fc4adda6b Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Sun, 23 Jun 2013 10:18:31 +0000 Subject: [PATCH] gpu: get rid of the global D3D device pointer and move D3D initialisation code from the Video to the Renderer class. --- src/gpu/framebuffer.cpp | 26 ++++----- src/gpu/indexbuffer.cpp | 20 ++++--- src/gpu/renderer.cpp | 58 +++++++++++++++++-- src/gpu/shader.cpp | 70 +++++++++++------------ src/gpu/texture.cpp | 22 ++++---- src/gpu/vertexbuffer.cpp | 102 +++++++++++++++++++--------------- src/lol/gpu/renderer.h | 2 + src/lol/gpu/vertexbuffer.h | 3 +- src/platform/sdl/sdlapp.cpp | 16 +++--- src/platform/xbox/xboxapp.cpp | 7 +-- src/video.cpp | 73 ------------------------ 11 files changed, 198 insertions(+), 201 deletions(-) diff --git a/src/gpu/framebuffer.cpp b/src/gpu/framebuffer.cpp index dd22defe..a47d897a 100644 --- a/src/gpu/framebuffer.cpp +++ b/src/gpu/framebuffer.cpp @@ -23,12 +23,6 @@ using namespace std; -#if defined USE_D3D9 -extern IDirect3DDevice9 *g_d3ddevice; -#elif defined _XBOX -extern D3DDevice *g_d3ddevice; -#endif - namespace lol { @@ -46,9 +40,11 @@ class FramebufferData bool m_bound; #if defined USE_D3D9 + IDirect3DDevice9 *m_dev; IDirect3DTexture9 *m_texture; IDirect3DSurface9 *m_surface, *m_back_surface; #elif defined _XBOX + D3DDevice9 *m_dev; D3DTexture *m_texture; D3DSurface *m_surface, *m_back_surface; #else @@ -292,7 +288,9 @@ Framebuffer::Framebuffer(ivec2 size, FramebufferFormat fbo_format) m_data->m_size = size; m_data->m_bound = false; #if defined USE_D3D9 - if (FAILED(g_d3ddevice->CreateTexture(size.x, size.y, 1, + m_data->m_dev = (IDirect3DDevice9 *)g_renderer->GetDevice(); + + if (FAILED(m_data->m_dev->CreateTexture(size.x, size.y, 1, D3DUSAGE_RENDERTARGET, (D3DFORMAT)fbo_format.GetFormat(), D3DPOOL_DEFAULT, &m_data->m_texture, nullptr))) @@ -300,11 +298,13 @@ Framebuffer::Framebuffer(ivec2 size, FramebufferFormat fbo_format) if (FAILED(m_data->m_texture->GetSurfaceLevel(0, &m_data->m_surface))) Abort(); #elif defined _XBOX - if (FAILED(g_d3ddevice->CreateTexture(size.x, size.y, 1, 0, + m_data->m_dev = (D3DDevice9 *)g_renderer->GetDevice(); + + if (FAILED(m_data->m_dev->CreateTexture(size.x, size.y, 1, 0, fbo_format.GetFormat(), D3DPOOL_DEFAULT, &m_data->m_texture, nullptr))) Abort(); - if (FAILED(g_d3ddevice->CreateRenderTarget(size.x, size.y, + if (FAILED(m_data->m_dev->CreateRenderTarget(size.x, size.y, fbo_format.GetFormat(), D3DMULTISAMPLE_NONE, 0, 0, &m_data->m_surface, nullptr))) @@ -422,9 +422,9 @@ void Framebuffer::Bind() ASSERT(!m_data->m_bound, "trying to bind an already bound framebuffer"); #if defined USE_D3D9 || defined _XBOX - if (FAILED(g_d3ddevice->GetRenderTarget(0, &m_data->m_back_surface))) + if (FAILED(m_data->m_dev->GetRenderTarget(0, &m_data->m_back_surface))) Abort(); - if (FAILED(g_d3ddevice->SetRenderTarget(0, m_data->m_surface))) + if (FAILED(m_data->m_dev->SetRenderTarget(0, m_data->m_surface))) Abort(); #else # if GL_VERSION_1_1 || GL_ES_VERSION_2_0 @@ -448,12 +448,12 @@ void Framebuffer::Unbind() #if defined USE_D3D9 || defined _XBOX # if defined _XBOX - if (FAILED(g_d3ddevice->Resolve(D3DRESOLVE_RENDERTARGET0, nullptr, + if (FAILED(m_data->m_dev->Resolve(D3DRESOLVE_RENDERTARGET0, nullptr, m_data->m_texture, nullptr, 0, 0, nullptr, 0, 0, nullptr))) Abort(); # endif - if (FAILED(g_d3ddevice->SetRenderTarget(0, m_data->m_back_surface))) + if (FAILED(m_data->m_dev->SetRenderTarget(0, m_data->m_back_surface))) Abort(); m_data->m_back_surface->Release(); #else diff --git a/src/gpu/indexbuffer.cpp b/src/gpu/indexbuffer.cpp index 32c08042..f61e0ba8 100644 --- a/src/gpu/indexbuffer.cpp +++ b/src/gpu/indexbuffer.cpp @@ -23,12 +23,6 @@ using namespace std; -#if defined USE_D3D9 -extern IDirect3DDevice9 *g_d3ddevice; -#elif defined _XBOX -extern D3DDevice *g_d3ddevice; -#endif - namespace lol { @@ -44,8 +38,10 @@ class IndexBufferData size_t m_size; #if defined USE_D3D9 + IDirect3DDevice9 *m_dev; IDirect3DIndexBuffer9 *m_ibo; #elif defined _XBOX + D3DDevice9 *m_dev; D3DIndexBuffer *m_ibo; #else GLuint m_ibo; @@ -65,7 +61,13 @@ IndexBuffer::IndexBuffer(size_t size) if (!size) return; #if defined USE_D3D9 || defined _XBOX - if (FAILED(g_d3ddevice->CreateIndexBuffer(size, D3DUSAGE_WRITEONLY, +# if defined USE_D3D9 + m_data->m_dev = (IDirect3DDevice9 *)g_renderer->GetDevice(); +# elif defined _XBOX + m_data->m_dev = (D3DDevice9 *)g_renderer->GetDevice(); +# endif + + if (FAILED(m_data->m_dev->CreateIndexBuffer(size, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_data->m_ibo, nullptr))) Abort(); @@ -126,7 +128,7 @@ void IndexBuffer::Bind() return; #if defined USE_D3D9 || defined _XBOX - if (FAILED(g_d3ddevice->SetIndices(m_data->m_ibo))) + if (FAILED(m_data->m_dev->SetIndices(m_data->m_ibo))) Abort(); #else glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_data->m_ibo); @@ -142,7 +144,7 @@ void IndexBuffer::Unbind() return; #if defined USE_D3D9 || defined _XBOX - if (FAILED(g_d3ddevice->SetIndices(nullptr))) + if (FAILED(m_data->m_dev->SetIndices(nullptr))) Abort(); #else glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); diff --git a/src/gpu/renderer.cpp b/src/gpu/renderer.cpp index 95c2f008..2fc3480f 100644 --- a/src/gpu/renderer.cpp +++ b/src/gpu/renderer.cpp @@ -31,10 +31,11 @@ #include "core.h" #include "lolgl.h" +/* FIXME: find a way to pass g_hwnd from the windowing system */ #if defined USE_D3D9 -extern IDirect3DDevice9 *g_d3ddevice; +extern HWND g_hwnd; #elif defined _XBOX -extern D3DDevice *g_d3ddevice; +HWND g_hwnd = 0; #endif namespace lol @@ -62,9 +63,12 @@ private: DepthFunc m_depth_func; CullMode m_face_culling; +private: #if defined USE_D3D9 + IDirect3D9 *m_d3d_ctx; IDirect3DDevice9 *m_d3d_dev; #elif defined _XBOX + Direct3D *m_d3d_ctx; D3DDevice *m_d3d_dev; #endif }; @@ -77,8 +81,45 @@ Renderer::Renderer(ivec2 size) : m_data(new RendererData()) { #if defined USE_D3D9 || defined _XBOX - /* FIXME: we should be in charge of creating this */ - m_data->m_d3d_dev = g_d3ddevice; + /* Create Direct3D context */ + m_data->m_d3d_ctx = Direct3DCreate9(D3D_SDK_VERSION); + if (!m_data->m_d3d_ctx) + { + Log::Error("cannot initialise D3D\n"); + exit(EXIT_FAILURE); + } + + /* Create Direct3D device */ +# if defined _XBOX + XVIDEO_MODE VideoMode; + XGetVideoMode(&VideoMode); + size = lol::min(size, ivec2(VideoMode.dwDisplayWidth, + VideoMode.dwDisplayHeight); +# endif + D3DPRESENT_PARAMETERS d3dpp; + memset(&d3dpp, 0, sizeof(d3dpp)); + d3dpp.BackBufferWidth = size.x; + d3dpp.BackBufferHeight = size.y; + d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; + d3dpp.BackBufferCount = 1; + d3dpp.hDeviceWindow = g_hwnd; +# if defined USE_SDL + d3dpp.Windowed = TRUE; +# endif + d3dpp.EnableAutoDepthStencil = TRUE; + d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; + + HRESULT hr = VideoData::d3d_ctx->CreateDevice(0, D3DDEVTYPE_HAL, g_hwnd, + D3DCREATE_HARDWARE_VERTEXPROCESSING, + &d3dpp, &m_data->m_d3d_dev); + if (FAILED(hr)) + { + Log::Error("cannot create D3D device\n"); + exit(EXIT_FAILURE); + } + #else # if defined USE_GLEW && !defined __APPLE__ /* Initialise GLEW if necessary */ @@ -130,6 +171,15 @@ Renderer::~Renderer() delete m_data; } +void *Renderer::GetDevice() +{ +#if defined USE_D3D9 || defined _XBOX + return m_data->m_d3d_dev; +#else + return nullptr; +#endif +} + /* * Buffer clearing */ diff --git a/src/gpu/shader.cpp b/src/gpu/shader.cpp index 0f09b438..762f3e72 100644 --- a/src/gpu/shader.cpp +++ b/src/gpu/shader.cpp @@ -32,12 +32,6 @@ using namespace std; -#if defined USE_D3D9 -extern IDirect3DDevice9 *g_d3ddevice; -#elif defined _XBOX -extern D3DDevice *g_d3ddevice; -#endif - namespace lol { @@ -51,10 +45,12 @@ class ShaderData private: #if defined USE_D3D9 + IDirect3DDevice9 *m_dev; IDirect3DVertexShader9 *vert_shader; IDirect3DPixelShader9 *frag_shader; ID3DXConstantTable *vert_table, *frag_table; #elif defined _XBOX + D3DDevice9 *m_dev; D3DVertexShader *vert_shader; D3DPixelShader *frag_shader; ID3DXConstantTable *vert_table, *frag_table; @@ -193,6 +189,12 @@ Shader::Shader(char const *vert, char const *frag) /* Compile vertex shader */ data->vert_crc = ShaderData::hash(vert); #if defined USE_D3D9 || defined _XBOX +# if defined USE_D3D9 + data->m_dev = (IDirect3DDevice9 *)g_renderer->GetDevice(); +# elif defined _XBOX + data->m_dev = (D3DDevice9 *)g_renderer->GetDevice(); +# endif + hr = D3DXCompileShader(vert, (UINT)strlen(vert), macros, nullptr, "main", "vs_3_0", 0, &shader_code, &error_msg, &data->vert_table); @@ -202,7 +204,7 @@ Shader::Shader(char const *vert, char const *frag) error_msg ? error_msg->GetBufferPointer() : "error"); Log::Error("shader source:\n%s\n", vert); } - g_d3ddevice->CreateVertexShader((DWORD *)shader_code->GetBufferPointer(), + data->m_dev->CreateVertexShader((DWORD *)shader_code->GetBufferPointer(), &data->vert_shader); shader_code->Release(); #elif !defined __CELLOS_LV2__ @@ -246,7 +248,7 @@ Shader::Shader(char const *vert, char const *frag) error_msg ? error_msg->GetBufferPointer() : "error"); Log::Error("shader source:\n%s\n", frag); } - g_d3ddevice->CreatePixelShader((DWORD *)shader_code->GetBufferPointer(), + data->m_dev->CreatePixelShader((DWORD *)shader_code->GetBufferPointer(), &data->frag_shader); shader_code->Release(); #elif !defined __CELLOS_LV2__ @@ -419,9 +421,9 @@ void Shader::SetUniform(ShaderUniform const &uni, ivec4 const &v) { #if defined USE_D3D9 || defined _XBOX if (uni.flags & 1) - g_d3ddevice->SetPixelShaderConstantI((UINT)uni.frag, &v[0], 1); + data->m_dev->SetPixelShaderConstantI((UINT)uni.frag, &v[0], 1); if (uni.flags & 2) - g_d3ddevice->SetVertexShaderConstantI((UINT)uni.vert, &v[0], 1); + data->m_dev->SetVertexShaderConstantI((UINT)uni.vert, &v[0], 1); #elif !defined __CELLOS_LV2__ glUniform4i(uni.frag, v.x, v.y, v.z, v.w); #else @@ -475,9 +477,9 @@ void Shader::SetUniform(ShaderUniform const &uni, vec4 const &v) { #if defined USE_D3D9 || defined _XBOX if (uni.flags & 1) - g_d3ddevice->SetPixelShaderConstantF((UINT)uni.frag, &v[0], 1); + data->m_dev->SetPixelShaderConstantF((UINT)uni.frag, &v[0], 1); if (uni.flags & 2) - g_d3ddevice->SetVertexShaderConstantF((UINT)uni.vert, &v[0], 1); + data->m_dev->SetVertexShaderConstantF((UINT)uni.vert, &v[0], 1); #elif !defined __CELLOS_LV2__ glUniform4fv(uni.frag, 1, &v[0]); #else @@ -493,9 +495,9 @@ void Shader::SetUniform(ShaderUniform const &uni, mat2 const &m) #if defined USE_D3D9 || defined _XBOX /* FIXME: do we need padding here like for the mat3 version? */ if (uni.flags & 1) - g_d3ddevice->SetPixelShaderConstantF((UINT)uni.frag, &m[0][0], 1); + data->m_dev->SetPixelShaderConstantF((UINT)uni.frag, &m[0][0], 1); if (uni.flags & 2) - g_d3ddevice->SetVertexShaderConstantF((UINT)uni.vert, &m[0][0], 1); + data->m_dev->SetVertexShaderConstantF((UINT)uni.vert, &m[0][0], 1); #elif !defined __CELLOS_LV2__ glUniformMatrix2fv(uni.frag, 1, GL_FALSE, &m[0][0]); #else @@ -514,9 +516,9 @@ void Shader::SetUniform(ShaderUniform const &uni, mat3 const &m) * a new data structure; a 4×4 matrix will do. */ mat4 tmp(m, 1.0f); if (uni.flags & 1) - g_d3ddevice->SetPixelShaderConstantF((UINT)uni.frag, &tmp[0][0], 3); + data->m_dev->SetPixelShaderConstantF((UINT)uni.frag, &tmp[0][0], 3); if (uni.flags & 2) - g_d3ddevice->SetVertexShaderConstantF((UINT)uni.vert, &tmp[0][0], 3); + data->m_dev->SetVertexShaderConstantF((UINT)uni.vert, &tmp[0][0], 3); #elif !defined __CELLOS_LV2__ glUniformMatrix3fv(uni.frag, 1, GL_FALSE, &m[0][0]); #else @@ -533,9 +535,9 @@ void Shader::SetUniform(ShaderUniform const &uni, mat4 const &m) { #if defined USE_D3D9 || defined _XBOX if (uni.flags & 1) - g_d3ddevice->SetPixelShaderConstantF((UINT)uni.frag, &m[0][0], 4); + data->m_dev->SetPixelShaderConstantF((UINT)uni.frag, &m[0][0], 4); if (uni.flags & 2) - g_d3ddevice->SetVertexShaderConstantF((UINT)uni.vert, &m[0][0], 4); + data->m_dev->SetVertexShaderConstantF((UINT)uni.vert, &m[0][0], 4); #elif !defined __CELLOS_LV2__ glUniformMatrix4fv(uni.frag, 1, GL_FALSE, &m[0][0]); #else @@ -549,10 +551,10 @@ void Shader::SetUniform(ShaderUniform const &uni, mat4 const &m) void Shader::SetUniform(ShaderUniform const &uni, ShaderTexture tex, int index) { #if defined USE_D3D9 || defined _XBOX - g_d3ddevice->SetTexture(index, (LPDIRECT3DTEXTURE9)tex.m_flags); - g_d3ddevice->SetSamplerState(index, D3DSAMP_MAGFILTER, tex.m_attrib & 0xff); - g_d3ddevice->SetSamplerState(index, D3DSAMP_MINFILTER, (tex.m_attrib >> 8) & 0xff); - g_d3ddevice->SetSamplerState(index, D3DSAMP_MIPFILTER, (tex.m_attrib >> 16) & 0xff); + data->m_dev->SetTexture(index, (LPDIRECT3DTEXTURE9)tex.m_flags); + data->m_dev->SetSamplerState(index, D3DSAMP_MAGFILTER, tex.m_attrib & 0xff); + data->m_dev->SetSamplerState(index, D3DSAMP_MINFILTER, (tex.m_attrib >> 8) & 0xff); + data->m_dev->SetSamplerState(index, D3DSAMP_MIPFILTER, (tex.m_attrib >> 16) & 0xff); #elif !defined __CELLOS_LV2__ glActiveTexture(GL_TEXTURE0 + index); //glEnable(GL_TEXTURE_2D); @@ -573,10 +575,10 @@ void Shader::SetUniform(ShaderUniform const &uni, Array const &v) /* FIXME: this will not work properly because we don't know how tell DX9 * it's a bunch of floats instead of vec4. */ if (uni.flags & 1) - g_d3ddevice->SetPixelShaderConstantF((UINT)uni.frag, + data->m_dev->SetPixelShaderConstantF((UINT)uni.frag, &v[0], v.Count() / 4); if (uni.flags & 2) - g_d3ddevice->SetVertexShaderConstantF((UINT)uni.vert, + data->m_dev->SetVertexShaderConstantF((UINT)uni.vert, &v[0], v.Count() / 4); #elif !defined __CELLOS_LV2__ glUniform1fv(uni.frag, v.Count(), &v[0]); @@ -596,10 +598,10 @@ void Shader::SetUniform(ShaderUniform const &uni, Array const &v) /* FIXME: this will not work properly because we don't know how tell DX9 * it's a bunch of vec2 instead of vec4. */ if (uni.flags & 1) - g_d3ddevice->SetPixelShaderConstantF((UINT)uni.frag, + data->m_dev->SetPixelShaderConstantF((UINT)uni.frag, &v[0][0], v.Count() / 2); if (uni.flags & 2) - g_d3ddevice->SetVertexShaderConstantF((UINT)uni.vert, + data->m_dev->SetVertexShaderConstantF((UINT)uni.vert, &v[0][0], v.Count() / 2); #elif !defined __CELLOS_LV2__ glUniform2fv(uni.frag, v.Count(), &v[0][0]); @@ -619,10 +621,10 @@ void Shader::SetUniform(ShaderUniform const &uni, Array const &v) /* FIXME: this will not work properly because we don't know how tell DX9 * it's a bunch of vec3 instead of vec4. */ if (uni.flags & 1) - g_d3ddevice->SetPixelShaderConstantF((UINT)uni.frag, + data->m_dev->SetPixelShaderConstantF((UINT)uni.frag, &v[0][0], v.Count()); if (uni.flags & 2) - g_d3ddevice->SetVertexShaderConstantF((UINT)uni.vert, + data->m_dev->SetVertexShaderConstantF((UINT)uni.vert, &v[0][0], v.Count()); #elif !defined __CELLOS_LV2__ glUniform3fv(uni.frag, v.Count(), &v[0][0]); @@ -640,10 +642,10 @@ void Shader::SetUniform(ShaderUniform const &uni, Array const &v) { #if defined USE_D3D9 || defined _XBOX if (uni.flags & 1) - g_d3ddevice->SetPixelShaderConstantF((UINT)uni.frag, + data->m_dev->SetPixelShaderConstantF((UINT)uni.frag, &v[0][0], v.Count()); if (uni.flags & 2) - g_d3ddevice->SetVertexShaderConstantF((UINT)uni.vert, + data->m_dev->SetVertexShaderConstantF((UINT)uni.vert, &v[0][0], v.Count()); #elif !defined __CELLOS_LV2__ glUniform4fv(uni.frag, v.Count(), &v[0][0]); @@ -661,8 +663,8 @@ void Shader::Bind() const { #if defined USE_D3D9 || defined _XBOX HRESULT hr; - hr = g_d3ddevice->SetVertexShader(data->vert_shader); - hr = g_d3ddevice->SetPixelShader(data->frag_shader); + hr = data->m_dev->SetVertexShader(data->vert_shader); + hr = data->m_dev->SetPixelShader(data->frag_shader); #elif !defined __CELLOS_LV2__ glUseProgram(data->prog_id); #else @@ -677,8 +679,8 @@ void Shader::Unbind() const { #if defined USE_D3D9 || defined _XBOX HRESULT hr; - hr = g_d3ddevice->SetVertexShader(nullptr); - hr = g_d3ddevice->SetPixelShader(nullptr); + hr = data->m_dev->SetVertexShader(nullptr); + hr = data->m_dev->SetPixelShader(nullptr); #elif !defined __CELLOS_LV2__ /* FIXME: untested */ glUseProgram(0); diff --git a/src/gpu/texture.cpp b/src/gpu/texture.cpp index 88794a74..6b143b00 100644 --- a/src/gpu/texture.cpp +++ b/src/gpu/texture.cpp @@ -23,12 +23,6 @@ using namespace std; -#if defined USE_D3D9 -extern IDirect3DDevice9 *g_d3ddevice; -#elif defined _XBOX -extern D3DDevice *g_d3ddevice; -#endif - namespace lol { @@ -45,11 +39,13 @@ class TextureData PixelFormat m_format; #if defined USE_D3D9 + IDirect3DDevice9 *m_dev; IDirect3DTexture9 *m_texture; D3DTEXTUREFILTERTYPE m_mag_filter; - D3DTEXTUREFILTERTYPE m_min_filter; - D3DTEXTUREFILTERTYPE m_mip_filter; + D3DTEXTUREFILTERTYPE m_min_filter; + D3DTEXTUREFILTERTYPE m_mip_filter; #elif defined _XBOX + D3DDevice9 *m_dev; D3DTexture *m_texture; #else GLuint m_texture; @@ -75,6 +71,12 @@ Texture::Texture(ivec2 size, PixelFormat format) m_data->m_format = format; #if defined USE_D3D9 || defined _XBOX +# if defined USE_D3D9 + m_data->m_dev = (IDirect3DDevice9 *)g_renderer->GetDevice(); +# elif defined _XBOX + m_data->m_dev = (D3DDevice9 *)g_renderer->GetDevice(); +# endif + static struct { D3DFORMAT format; @@ -109,7 +111,7 @@ Texture::Texture(ivec2 size, PixelFormat format) int d3d_usage = D3DUSAGE_WRITEONLY; # endif - g_d3ddevice->CreateTexture(m_data->m_size.x, m_data->m_size.y, 1, + m_data->m_dev->CreateTexture(m_data->m_size.x, m_data->m_size.y, 1, d3d_usage, d3d_format, D3DPOOL_DEFAULT, &m_data->m_texture, nullptr); m_data->m_bytes_per_elem = GET_CLAMPED(d3d_formats, format).bytes; @@ -185,7 +187,7 @@ ShaderTexture Texture::GetTexture() const void Texture::Bind() { #if defined _XBOX || defined USE_D3D9 - g_d3ddevice->SetTexture(0, m_data->m_texture); + m_data->m_dev->SetTexture(0, m_data->m_texture); #else # if !defined HAVE_GLES_2X glEnable(GL_TEXTURE_2D); diff --git a/src/gpu/vertexbuffer.cpp b/src/gpu/vertexbuffer.cpp index b325502d..19f0e41c 100644 --- a/src/gpu/vertexbuffer.cpp +++ b/src/gpu/vertexbuffer.cpp @@ -23,12 +23,6 @@ using namespace std; -#if defined USE_D3D9 -extern IDirect3DDevice9 *g_d3ddevice; -#elif defined _XBOX -extern D3DDevice *g_d3ddevice; -#endif - namespace lol { @@ -45,8 +39,10 @@ class VertexBufferData size_t m_size; #if defined USE_D3D9 + IDirect3DDevice9 *m_dev; IDirect3DVertexBuffer9 *m_vbo; #elif defined _XBOX + D3DDevice9 *m_dev; D3DVertexBuffer *m_vbo; #else GLuint m_vbo; @@ -54,6 +50,26 @@ class VertexBufferData #endif }; +// +// The VertexDeclarationData class +// ------------------------------- +// + +class VertexDeclarationData +{ + friend class VertexBuffer; + friend class VertexDeclaration; + +#if defined USE_D3D9 + IDirect3DDevice9 *m_dev; + IDirect3DVertexDeclaration9 *m_vdecl; +#elif defined _XBOX + D3DDevice9 *m_dev; + D3DVertexDeclaration *m_vdecl; +#else +#endif +}; + // // The VertexDeclaration class // --------------------------- @@ -72,7 +88,9 @@ VertexDeclaration::VertexDeclaration(VertexStreamBase const &s1, VertexStreamBase const &s9, VertexStreamBase const &s10, VertexStreamBase const &s11, - VertexStreamBase const &s12) : m_count(0) + VertexStreamBase const &s12) + : m_count(0), + m_data(new VertexDeclarationData()) { if (&s1 != &VertexStreamBase::Empty) AddStream(s1); if (&s2 != &VertexStreamBase::Empty) AddStream(s2); @@ -92,29 +110,19 @@ VertexDeclaration::VertexDeclaration(VertexStreamBase const &s1, VertexDeclaration::~VertexDeclaration() { #if defined _XBOX || defined USE_D3D9 -# if defined USE_D3D9 - IDirect3DVertexDeclaration9 *vdecl = (IDirect3DVertexDeclaration9 *)m_data; -# elif defined _XBOX - D3DVertexDeclaration *vdecl = (D3DVertexDeclaration *)m_data; -# endif - - if (FAILED(vdecl->Release())) + if (FAILED(m_data->m_vdecl->Release())) Abort(); #else #endif + + delete m_data; } void VertexDeclaration::Bind() { #if defined _XBOX || defined USE_D3D9 -# if defined USE_D3D9 - IDirect3DVertexDeclaration9 *vdecl = (IDirect3DVertexDeclaration9 *)m_data; -# elif defined _XBOX - D3DVertexDeclaration *vdecl = (D3DVertexDeclaration *)m_data; -# endif - - if (FAILED(g_d3ddevice->SetVertexDeclaration(vdecl))) + if (FAILED(m_data->m_dev->SetVertexDeclaration(m_data->m_vdecl))) Abort(); #else /* FIXME: Nothing to do? */ @@ -130,28 +138,28 @@ void VertexDeclaration::DrawElements(MeshPrimitive type, int skip, int count) switch (type) { case MeshPrimitive::Triangles: - if (FAILED(g_d3ddevice->DrawPrimitive(D3DPT_TRIANGLELIST, - skip, count))) + if (FAILED(m_data->m_dev->DrawPrimitive(D3DPT_TRIANGLELIST, + skip, count))) Abort(); break; case MeshPrimitive::TriangleStrips: - if (FAILED(g_d3ddevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, - skip, count))) + if (FAILED(m_data->m_dev->DrawPrimitive(D3DPT_TRIANGLESTRIP, + skip, count))) Abort(); break; case MeshPrimitive::TriangleFans: - if (FAILED(g_d3ddevice->DrawPrimitive(D3DPT_TRIANGLEFAN, - skip, count))) + if (FAILED(m_data->m_dev->DrawPrimitive(D3DPT_TRIANGLEFAN, + skip, count))) Abort(); break; case MeshPrimitive::Points: - if (FAILED(g_d3ddevice->DrawPrimitive(D3DPT_POINTLIST, - skip, count))) + if (FAILED(m_data->m_dev->DrawPrimitive(D3DPT_POINTLIST, + skip, count))) Abort(); break; case MeshPrimitive::Lines: - if (FAILED(g_d3ddevice->DrawPrimitive(D3DPT_LINELIST, - skip, count))) + if (FAILED(m_data->m_dev->DrawPrimitive(D3DPT_LINELIST, + skip, count))) Abort(); break; } @@ -190,29 +198,29 @@ void VertexDeclaration::DrawIndexedElements(MeshPrimitive type, int vbase, { case MeshPrimitive::Triangles: count = count / 3; - if (FAILED(g_d3ddevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, + if (FAILED(m_data->m_dev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, vbase, vskip, vcount, skip, count))) Abort(); break; case MeshPrimitive::TriangleStrips: count = count - 2; - if (FAILED(g_d3ddevice->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, + if (FAILED(m_data->m_dev->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, vbase, vskip, vcount, skip, count))) Abort(); break; case MeshPrimitive::TriangleFans: count = count - 2; - if (FAILED(g_d3ddevice->DrawIndexedPrimitive(D3DPT_TRIANGLEFAN, + if (FAILED(m_data->m_dev->DrawIndexedPrimitive(D3DPT_TRIANGLEFAN, vbase, vskip, vcount, skip, count))) Abort(); break; case MeshPrimitive::Points: - if (FAILED(g_d3ddevice->DrawIndexedPrimitive(D3DPT_POINTLIST, + if (FAILED(m_data->m_dev->DrawIndexedPrimitive(D3DPT_POINTLIST, vbase, vskip, vcount, skip, count))) Abort(); break; case MeshPrimitive::Lines: - if (FAILED(g_d3ddevice->DrawIndexedPrimitive(D3DPT_LINELIST, + if (FAILED(m_data->m_dev->DrawIndexedPrimitive(D3DPT_LINELIST, vbase, vskip, vcount, skip, count))) Abort(); break; @@ -258,7 +266,7 @@ void VertexDeclaration::Unbind() if (m_streams[i].index != stream) { stream = m_streams[i].index; - if (FAILED(g_d3ddevice->SetStreamSource(stream, 0, 0, 0))) + if (FAILED(m_data->m_dev->SetStreamSource(stream, 0, 0, 0))) Abort(); } /* "NULL is an invalid input to SetVertexDeclaration" (DX9 guide), so @@ -329,7 +337,8 @@ void VertexDeclaration::SetStream(VertexBuffer *vb, ShaderAttrib attr1, /* FIXME: precompute most of the crap above! */ if (stream >= 0) { - if (FAILED(g_d3ddevice->SetStreamSource(stream, vb->m_data->m_vbo, 0, stride))) + if (FAILED(m_data->m_dev->SetStreamSource(stream, vb->m_data->m_vbo, + 0, stride))) Abort(); } #else @@ -553,15 +562,14 @@ void VertexDeclaration::Initialize() elements[m_count] = end_element[0]; # if defined USE_D3D9 - IDirect3DVertexDeclaration9 *vdecl; + m_data->m_dev = (IDirect3DDevice9 *)g_renderer->GetDevice(); # elif defined _XBOX - D3DVertexDeclaration *vdecl; + m_data->m_dev = (D3DDevice9 *)g_renderer->GetDevice(); # endif - if (FAILED(g_d3ddevice->CreateVertexDeclaration(elements, &vdecl))) + if (FAILED(m_data->m_dev->CreateVertexDeclaration(elements, + &m_data->m_vdecl))) Abort(); - - m_data = vdecl; #else #endif @@ -636,7 +644,13 @@ VertexBuffer::VertexBuffer(size_t size) if (!size) return; #if defined USE_D3D9 || defined _XBOX - if (FAILED(g_d3ddevice->CreateVertexBuffer(size, D3DUSAGE_WRITEONLY, nullptr, +# if defined USE_D3D9 + m_data->m_dev = (IDirect3DDevice9 *)g_renderer->GetDevice(); +# elif defined _XBOX + m_data->m_dev = (D3DDevice9 *)g_renderer->GetDevice(); +# endif + + if (FAILED(m_data->m_dev->CreateVertexBuffer(size, D3DUSAGE_WRITEONLY, nullptr, D3DPOOL_MANAGED, &m_data->m_vbo, nullptr))) Abort(); #else diff --git a/src/lol/gpu/renderer.h b/src/lol/gpu/renderer.h index 5bb2f125..921ec4d6 100644 --- a/src/lol/gpu/renderer.h +++ b/src/lol/gpu/renderer.h @@ -138,6 +138,8 @@ private: Renderer(ivec2 size); ~Renderer(); + void *GetDevice(); + public: void Clear(ClearMask mask); diff --git a/src/lol/gpu/vertexbuffer.h b/src/lol/gpu/vertexbuffer.h index a69f4ba7..98b1383a 100644 --- a/src/lol/gpu/vertexbuffer.h +++ b/src/lol/gpu/vertexbuffer.h @@ -311,7 +311,8 @@ private: struct { uint8_t stream_type, index, usage, size; int reg; } m_streams[12 + 1]; int m_count; - void *m_data; +private: + class VertexDeclarationData *m_data; }; } /* namespace lol */ diff --git a/src/platform/sdl/sdlapp.cpp b/src/platform/sdl/sdlapp.cpp index dee374f2..57289083 100644 --- a/src/platform/sdl/sdlapp.cpp +++ b/src/platform/sdl/sdlapp.cpp @@ -34,7 +34,6 @@ #if defined USE_SDL && defined USE_D3D9 HWND g_hwnd = nullptr; -extern IDirect3DDevice9 *g_d3ddevice; #endif namespace lol @@ -115,24 +114,25 @@ void SdlApp::ShowPointer(bool show) void SdlApp::Tick() { #if defined USE_SDL && defined USE_D3D9 + IDirect3DDevice9 *d3d_dev = (IDirect3DDevice9 *)g_renderer->GetDevice(); HRESULT hr; - hr = g_d3ddevice->BeginScene(); + hr = d3d_dev->BeginScene(); if (FAILED(hr)) Abort(); #endif + /* Tick the renderer, show the frame and clamp to desired framerate. */ Ticker::TickDraw(); -#if defined USE_SDL -# if defined USE_D3D9 - hr = g_d3ddevice->EndScene(); + +#if defined USE_SDL && defined USE_D3D9 + hr = d3d_dev->EndScene(); if (FAILED(hr)) Abort(); - hr = g_d3ddevice->Present(nullptr, nullptr, nullptr, nullptr); + hr = d3d_dev->Present(nullptr, nullptr, nullptr, nullptr); if (FAILED(hr)) Abort(); -# else +#elif defined USE_SDL SDL_GL_SwapBuffers(); -# endif #endif } diff --git a/src/platform/xbox/xboxapp.cpp b/src/platform/xbox/xboxapp.cpp index 7d66cba6..9ec253bd 100644 --- a/src/platform/xbox/xboxapp.cpp +++ b/src/platform/xbox/xboxapp.cpp @@ -20,10 +20,6 @@ #include "xboxapp.h" #include "xboxinput.h" -#if defined _XBOX -extern D3DDevice *g_d3ddevice; -#endif - namespace lol { @@ -67,7 +63,8 @@ void XboxApp::Tick() Ticker::TickDraw(); #if defined _XBOX - g_d3ddevice->Present(nullptr, nullptr, nullptr, nullptr); + D3DDevice9 *d3d_dev = (D3DDevice9 *)g_renderer->GetDevice(); + d3d_dev->Present(nullptr, nullptr, nullptr, nullptr); #endif } diff --git a/src/video.cpp b/src/video.cpp index 3340f353..a9e12983 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -31,15 +31,6 @@ using namespace std; -/* FIXME: g_d3ddevice should never be exported */ -#if defined USE_D3D9 -IDirect3DDevice9 *g_d3ddevice; -extern HWND g_hwnd; -#elif defined _XBOX -D3DDevice *g_d3ddevice; -HWND g_hwnd = 0; -#endif - namespace lol { @@ -49,81 +40,17 @@ class VideoData private: static DebugRenderMode render_mode; -#if defined USE_D3D9 || defined _XBOX -# if defined USE_D3D9 - static IDirect3D9 *d3d_ctx; - static IDirect3DDevice9 *d3d_dev; -# elif defined _XBOX - static Direct3D *d3d_ctx; - static D3DDevice *d3d_dev; -# endif -#endif }; DebugRenderMode VideoData::render_mode = DebugRenderMode::Default; -#if defined USE_D3D9 || defined _XBOX -# if defined USE_D3D9 -IDirect3D9 *VideoData::d3d_ctx; -IDirect3DDevice9 *VideoData::d3d_dev; -# elif defined _XBOX -Direct3D *VideoData::d3d_ctx; -D3DDevice *VideoData::d3d_dev; -# endif -#endif - /* * Public Video class */ void Video::Setup(ivec2 size) { -#if defined USE_D3D9 || defined _XBOX - VideoData::d3d_ctx = Direct3DCreate9(D3D_SDK_VERSION); - if (!VideoData::d3d_ctx) - { - Log::Error("cannot initialise D3D\n"); - exit(EXIT_FAILURE); - } - - /* Choose best viewport size */ -# if defined _XBOX - XVIDEO_MODE VideoMode; - XGetVideoMode(&VideoMode); - size = lol::min(size, ivec2(VideoMode.dwDisplayWidth, - VideoMode.dwDisplayHeight); -# endif - D3DPRESENT_PARAMETERS d3dpp; - memset(&d3dpp, 0, sizeof(d3dpp)); - d3dpp.BackBufferWidth = size.x; - d3dpp.BackBufferHeight = size.y; - d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; - d3dpp.BackBufferCount = 1; - d3dpp.hDeviceWindow = g_hwnd; -# if defined USE_SDL - d3dpp.Windowed = TRUE; -# endif - d3dpp.EnableAutoDepthStencil = TRUE; - d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; - d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; - d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; - - HRESULT hr = VideoData::d3d_ctx->CreateDevice(0, D3DDEVTYPE_HAL, g_hwnd, - D3DCREATE_HARDWARE_VERTEXPROCESSING, - &d3dpp, &VideoData::d3d_dev); - if (FAILED(hr)) - { - Log::Error("cannot create D3D device\n"); - exit(EXIT_FAILURE); - } - - g_d3ddevice = VideoData::d3d_dev; - g_renderer = new Renderer(size); -#else - /* Initialise OpenGL */ - g_renderer = new Renderer(size); -#endif /* Initialise reasonable scene default properties */ SetDebugRenderMode(DebugRenderMode::Default);