From 57f393d0d394939e077333d99ac3a9e6d7a43223 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Thu, 12 Apr 2012 17:38:54 +0000 Subject: [PATCH] gpu: port the texture and scene handling code to Direct3D. Not functional. --- src/gpu/shader.cpp | 7 ++- src/scene.cpp | 131 ++++++++++++++++++++++++++++++--------------- src/tileset.cpp | 109 ++++++++++++++++++++----------------- 3 files changed, 153 insertions(+), 94 deletions(-) diff --git a/src/gpu/shader.cpp b/src/gpu/shader.cpp index e3522222..b10befe6 100644 --- a/src/gpu/shader.cpp +++ b/src/gpu/shader.cpp @@ -321,7 +321,10 @@ void Shader::SetUniform(ShaderUniform const &uni, ivec3 const &v) void Shader::SetUniform(ShaderUniform const &uni, ivec4 const &v) { #if defined USE_D3D9 || defined _XBOX - SetUniform(uni, v); + if (uni.flags & 1) + g_d3ddevice->SetPixelShaderConstantI((UINT)uni.frag, &v[0], 1); + if (uni.flags & 2) + g_d3ddevice->SetVertexShaderConstantI((UINT)uni.vert, &v[0], 1); #elif !defined __CELLOS_LV2__ glUniform4i(uni.frag, v.x, v.y, v.z, v.w); #else @@ -373,7 +376,6 @@ void Shader::SetUniform(ShaderUniform const &uni, vec3 const &v) void Shader::SetUniform(ShaderUniform const &uni, vec4 const &v) { - /* FIXME: use the array versions of these functions */ #if defined USE_D3D9 || defined _XBOX if (uni.flags & 1) g_d3ddevice->SetPixelShaderConstantF((UINT)uni.frag, &v[0], 1); @@ -382,6 +384,7 @@ void Shader::SetUniform(ShaderUniform const &uni, vec4 const &v) #elif !defined __CELLOS_LV2__ glUniform4f(uni.frag, v.x, v.y, v.z, v.w); #else + /* FIXME: use the array versions of these functions */ if (uni.frag) cgGLSetParameter4f((CGparameter)uni.frag, v.x, v.y, v.z, v.w); if (uni.vert) diff --git a/src/scene.cpp b/src/scene.cpp index 8080c72f..28745610 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -18,11 +18,22 @@ #ifdef WIN32 # define WIN32_LEAN_AND_MEAN # include +# if defined USE_D3D9 +# define FAR +# define NEAR +# include +# endif #endif #include "core.h" #include "lolgl.h" +#if defined USE_D3D9 +extern IDirect3DDevice9 *g_d3ddevice; +#elif defined _XBOX +extern D3DDevice *g_d3ddevice; +#endif + namespace lol { @@ -60,23 +71,19 @@ private: int ntiles; float angle; -#if defined USE_D3D9 || defined _XBOX -# if defined __GNUC__ -# warning Scene not implemented -# else -# define STR0(x) #x -# define STR(x) STR0(x) -# pragma message(__FILE__ "(" STR(__LINE__) "): warning: Scene not implemented") -# undef STR -# undef STR0 -# endif +#if defined USE_D3D9 + IDirect3DVertexDeclaration9 *m_vdecl; + IDirect3DVertexBuffer9 **bufs; +#elif defined _XBOX + D3DVertexDeclaration *m_vdecl; + D3DVertexBuffer **bufs; #else -#if defined HAVE_GL_2X && !defined __APPLE__ +# if defined HAVE_GL_2X && !defined __APPLE__ GLuint vao; -#endif +# endif GLuint *bufs; - int nbufs; #endif + int nbufs; static Scene *scene; }; @@ -94,12 +101,18 @@ Scene::Scene(float angle) data->ntiles = 0; data->angle = angle; -#if defined USE_D3D9 || defined _XBOX - /* TODO */ -#else data->bufs = 0; data->nbufs = 0; +#if defined _XBOX || defined USE_D3D9 + D3DVERTEXELEMENT9 const elements[] = + { + { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, + { 1, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, + D3DDECL_END() + }; + g_d3ddevice->CreateVertexDeclaration(elements, &data->m_vdecl); +#else # if defined HAVE_GL_2X && !defined __APPLE__ glGenVertexArrays(1, &data->vao); # endif @@ -109,7 +122,7 @@ Scene::Scene(float angle) Scene::~Scene() { #if defined USE_D3D9 || defined _XBOX - /* TODO */ + /* FIXME: TODO */ #else /* FIXME: this must be done while the GL context is still active. * Change the code architecture to make sure of that. */ @@ -140,7 +153,6 @@ void Scene::Reset() void Scene::AddTile(TileSet *tileset, int id, vec3 pos, int o, vec2 scale) { -#if !defined USE_D3D9 && !defined _XBOX if ((data->ntiles % 1024) == 0) data->tiles = (Tile *)realloc(data->tiles, (data->ntiles + 1024) * sizeof(Tile)); @@ -152,15 +164,13 @@ void Scene::AddTile(TileSet *tileset, int id, vec3 pos, int o, vec2 scale) data->tiles[data->ntiles].o = o; data->tiles[data->ntiles].scale = scale; data->ntiles++; -#endif } void Scene::Render() // XXX: rename to Blit() { -#if !defined USE_D3D9 && !defined _XBOX /* No WPOS on Xbox, what about Win32? */ if (!stdshader) { -#if !defined _XBOX && !defined __CELLOS_LV2__ +#if !defined _XBOX && !defined __CELLOS_LV2__ && !defined USE_D3D9 stdshader = Shader::Create( #if !defined HAVE_GLES_2X "#version 130\n" @@ -257,7 +267,9 @@ void Scene::Render() // XXX: rename to Blit() "}", "void main(float2 in_TexCoord : TEXCOORD0," +#if 0 " float4 in_FragCoord : WPOS," +#endif " uniform sampler2D tex," " out float4 out_FragColor : COLOR)" "{" @@ -297,7 +309,6 @@ void Scene::Render() // XXX: rename to Blit() #endif " out_FragColor = col;" "}"); -#endif } #if 0 @@ -325,10 +336,14 @@ void Scene::Render() // XXX: rename to Blit() // XXX: end of debug stuff ShaderUniform uni_mat, uni_tex; +#if defined USE_D3D9 || defined _XBOX + /* Nothing? */ +#else int attr_pos, attr_tex; #if !defined __CELLOS_LV2__ attr_pos = stdshader->GetAttribLocation("in_Position"); attr_tex = stdshader->GetAttribLocation("in_TexCoord"); +#endif #endif stdshader->Bind(); @@ -340,12 +355,14 @@ void Scene::Render() // XXX: rename to Blit() uni_mat = stdshader->GetUniformLocation("model_matrix"); stdshader->SetUniform(uni_mat, data->model_matrix); +#if defined USE_D3D9 || defined _XBOX + //g_d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); + g_d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + g_d3ddevice->SetVertexDeclaration(data->m_vdecl); +#else uni_tex = stdshader->GetUniformLocation("in_Texture"); stdshader->SetUniform(uni_tex, 0); -#if defined USE_D3D9 || defined _XBOX - /* TODO */ -#else #if !defined HAVE_GLES_2X glEnable(GL_TEXTURE_2D); #endif @@ -361,16 +378,25 @@ void Scene::Render() // XXX: rename to Blit() for (int buf = 0, i = 0, n; i < data->ntiles; i = n, buf += 2) { -#if defined USE_D3D9 || defined _XBOX - /* TODO */ -#else /* Generate new vertex / texture coord buffers if necessary */ if (buf + 2 > data->nbufs) { +#if defined USE_D3D9 + data->bufs = (IDirect3DVertexBuffer9 **)realloc(data->bufs, (buf + 2) * sizeof(IDirect3DVertexBuffer9 *)); +#elif defined _XBOX + data->bufs = (D3DVertexBuffer **)realloc(data->bufs, (buf + 2) * sizeof(D3DVertexBuffer *)); +#else data->bufs = (uint32_t *)realloc(data->bufs, (buf + 2) * sizeof(uint32_t)); glGenBuffers(buf + 2 - data->nbufs, data->bufs + data->nbufs); +#endif data->nbufs = buf + 2; } +#if defined USE_D3D9 || defined _XBOX + else + { + data->bufs[buf]->Release(); + data->bufs[buf + 1]->Release(); + } #endif /* Count how many quads will be needed */ @@ -379,8 +405,20 @@ void Scene::Render() // XXX: rename to Blit() break; /* Create a vertex array object */ - float *vertex = (float *)malloc(6 * 3 * (n - i) * sizeof(float)); - float *texture = (float *)malloc(6 * 2 * (n - i) * sizeof(float)); + float *vertex, *texture; +#if defined USE_D3D9 || defined _XBOX + if (FAILED(g_d3ddevice->CreateVertexBuffer(6 * 3 * (n - i) * sizeof(float), D3DUSAGE_WRITEONLY, NULL, D3DPOOL_MANAGED, &data->bufs[buf], NULL))) + exit(0); + if (FAILED(data->bufs[buf]->Lock(0, 0, (void **)&vertex, 0))) + exit(0); + if (FAILED(g_d3ddevice->CreateVertexBuffer(6 * 2 * (n - i) * sizeof(float), D3DUSAGE_WRITEONLY, NULL, D3DPOOL_MANAGED, &data->bufs[buf + 1], NULL))) + exit(0); + if (FAILED(data->bufs[buf + 1]->Lock(0, 0, (void **)&texture, 0))) + exit(0); +#else + vertex = (float *)malloc(6 * 3 * (n - i) * sizeof(float)); + texture = (float *)malloc(6 * 2 * (n - i) * sizeof(float)); +#endif for (int j = i; j < n; j++) { @@ -390,19 +428,26 @@ void Scene::Render() // XXX: rename to Blit() vertex + 18 * (j - i), texture + 12 * (j - i)); } +#if defined USE_D3D9 || defined _XBOX + data->bufs[buf]->Unlock(); + data->bufs[buf + 1]->Unlock(); +#endif + stdshader->Bind(); /* Bind texture */ data->tiles[i].tileset->Bind(); /* Bind vertex, color and texture coordinate buffers */ -#if defined HAVE_GL_2X && !defined __APPLE__ - glBindVertexArray(data->vao); -#endif #if defined USE_D3D9 || defined _XBOX - /* TODO */ + g_d3ddevice->SetStreamSource(0, data->bufs[data->nbufs - 2], 0, 6 * 3 * (n - i) * sizeof(float)); + g_d3ddevice->SetStreamSource(1, data->bufs[data->nbufs - 1], 0, 6 * 2 * (n - i) * sizeof(float)); + g_d3ddevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, (n - i) * 6); #else -#if !defined __CELLOS_LV2__ // Use cgGLEnableClientState etc. +# if defined HAVE_GL_2X && !defined __APPLE__ + glBindVertexArray(data->vao); +# endif +# if !defined __CELLOS_LV2__ // Use cgGLEnableClientState etc. glEnableVertexAttribArray(attr_pos); glEnableVertexAttribArray(attr_tex); @@ -415,31 +460,31 @@ void Scene::Render() // XXX: rename to Blit() glBufferData(GL_ARRAY_BUFFER, 12 * (n - i) * sizeof(GLfloat), texture, GL_STATIC_DRAW); glVertexAttribPointer(attr_tex, 2, GL_FLOAT, GL_FALSE, 0, 0); -#else +# else glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(3, GL_FLOAT, 0, vertex); glTexCoordPointer(2, GL_FLOAT, 0, texture); -#endif +# endif /* Draw arrays */ glDrawArrays(GL_TRIANGLES, 0, (n - i) * 6); -#if defined HAVE_GL_2X && !defined __APPLE__ +# if defined HAVE_GL_2X && !defined __APPLE__ glBindVertexArray(0); -#endif -#if !defined __CELLOS_LV2__ // Use cgGLEnableClientState etc. +# endif +# if !defined __CELLOS_LV2__ // Use cgGLEnableClientState etc. glDisableVertexAttribArray(attr_pos); glDisableVertexAttribArray(attr_tex); -#else +# else glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); -#endif -#endif +# endif free(vertex); free(texture); +#endif } free(data->tiles); diff --git a/src/tileset.cpp b/src/tileset.cpp index 92b79cb3..6accbc1a 100644 --- a/src/tileset.cpp +++ b/src/tileset.cpp @@ -20,6 +20,11 @@ #if defined WIN32 && !defined _XBOX # define WIN32_LEAN_AND_MEAN # include +# if defined USE_D3D9 +# define FAR +# define NEAR +# include +# endif #endif #include "core.h" @@ -27,6 +32,12 @@ using namespace std; +#if defined USE_D3D9 +extern IDirect3DDevice9 *g_d3ddevice; +#elif defined _XBOX +extern D3DDevice *g_d3ddevice; +#endif + namespace lol { @@ -46,14 +57,12 @@ private: float tx, ty; Image *img; -#if defined USE_D3D9 || defined _XBOX -# define STR0(x) #x -# define STR(x) STR0(x) -# pragma message(__FILE__ "(" STR(__LINE__) "): warning: TileSet not implemented") -# undef STR -# undef STR0 +#if defined USE_D3D9 + IDirect3DTexture9 *m_tex; +#elif defined _XBOX + D3DTexture *m_tex; #else - GLuint texture; + GLuint m_tex; #endif }; @@ -69,15 +78,7 @@ TileSet::TileSet(char const *path, ivec2 size, ivec2 count) sprintf(data->name, " %s", path); data->tiles = NULL; -#if defined USE_D3D9 || defined _XBOX -# define STR0(x) #x -# define STR(x) STR0(x) -# pragma message(__FILE__ "(" STR(__LINE__) "): warning: TileSet::TileSet() not implemented") -# undef STR -# undef STR0 -#else - data->texture = 0; -#endif + data->m_tex = 0; data->img = new Image(path); data->isize = data->img->GetSize(); @@ -118,38 +119,44 @@ void TileSet::TickDraw(float deltams) { if (data->img) delete data->img; + else #if defined USE_D3D9 || defined _XBOX -# define STR0(x) #x -# define STR(x) STR0(x) -# pragma message(__FILE__ "(" STR(__LINE__) "): warning: TileSet::TickDraw() not implemented") -# undef STR -# undef STR0 + /* FIXME: is it really the correct call? */ + data->m_tex->Release(); #else - else - glDeleteTextures(1, &data->texture); + glDeleteTextures(1, &data->m_tex); #endif } else if (data->img) { #if defined USE_D3D9 || defined _XBOX -# define STR0(x) #x -# define STR(x) STR0(x) -# pragma message(__FILE__ "(" STR(__LINE__) "): warning: TileSet::TickDraw() not implemented") -# undef STR -# undef STR0 + D3DFORMAT format; #else GLuint format; +#endif int planes; switch (data->img->GetFormat()) { case Image::FORMAT_RGB: +#if defined USE_D3D9 + format = D3DFMT_R8G8B8; +#elif defined _XBOX + format = D3DFMT_LIN_R8G8B8; /* FIXME */ +#else format = GL_RGB; +#endif planes = 3; break; case Image::FORMAT_RGBA: default: +#if defined USE_D3D9 + format = D3DFMT_A8R8G8B8; +#elif defined _XBOX + format = D3DFMT_LIN_A8R8G8B8; +#else format = GL_RGBA; +#endif planes = 4; break; } @@ -168,19 +175,35 @@ void TileSet::TickDraw(float deltams) pixels = tmp; } - glGenTextures(1, &data->texture); +#if defined USE_D3D9 || defined _XBOX + D3DLOCKED_RECT rect; +# if defined USE_D3D9 + g_d3ddevice->CreateTexture(w, h, 1, D3DUSAGE_DYNAMIC, format, + D3DPOOL_SYSTEMMEM, &data->m_tex, NULL); + data->m_tex->LockRect(0, &rect, NULL, D3DLOCK_DISCARD | D3DLOCK_NOOVERWRITE); +# elif defined _XBOX + /* By default the X360 will swizzle the texture. Ask for linear. */ + g_d3ddevice->CreateTexture(w, h, 1, D3DUSAGE_WRITEONLY, format, + D3DPOOL_DEFAULT, &data->m_tex, NULL); + data->m_tex->LockRect(0, &rect, NULL, D3DLOCK_NOOVERWRITE); +# endif + for (int j = 0; j < h; j++) + memcpy((uint8_t *)rect.pBits + j * rect.Pitch, pixels + w * j * 4, w * 4); + data->m_tex->UnlockRect(0); +#else + glGenTextures(1, &data->m_tex); glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, data->texture); + glBindTexture(GL_TEXTURE_2D, data->m_tex); glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format, GL_UNSIGNED_BYTE, pixels); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); +#endif if (pixels != data->img->GetData()) free(pixels); -#endif delete data->img; data->img = NULL; } @@ -203,19 +226,15 @@ ivec2 TileSet::GetSize(int tileid) const void TileSet::Bind() { + if (!data->img && data->m_tex) + { #if defined USE_D3D9 || defined _XBOX -# define STR0(x) #x -# define STR(x) STR0(x) -# pragma message(__FILE__ "(" STR(__LINE__) "): warning: TileSet::Bind() not implemented") -# undef STR -# undef STR0 + g_d3ddevice->SetTexture(0, data->m_tex); #else - if (!data->img && data->texture) - { glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, data->texture); - } + glBindTexture(GL_TEXTURE_2D, data->m_tex); #endif + } } void TileSet::BlitTile(uint32_t id, vec3 pos, int o, vec2 scale, @@ -228,14 +247,7 @@ void TileSet::BlitTile(uint32_t id, vec3 pos, int o, vec2 scale, int dy = o ? 0 : data->size.y * scale.y; int dz = o ? data->size.y * scale.y : 0; -#if defined USE_D3D9 || defined _XBOX -# define STR0(x) #x -# define STR(x) STR0(x) -# pragma message(__FILE__ "(" STR(__LINE__) "): warning: TileSet::TileSet() not implemented") -# undef STR -# undef STR0 -#else - if (!data->img && data->texture) + if (!data->img && data->m_tex) { float tmp[10]; @@ -280,7 +292,6 @@ void TileSet::BlitTile(uint32_t id, vec3 pos, int o, vec2 scale, memset(vertex, 0, 3 * sizeof(float)); memset(texture, 0, 2 * sizeof(float)); } -#endif } } /* namespace lol */