hardcoded and only the fractal demo uses it, but everything will eventually switch.legacy
@@ -50,6 +50,7 @@ liblol_a_SOURCES = \ | |||||
gpu/indexbuffer.cpp gpu/indexbuffer.h \ | gpu/indexbuffer.cpp gpu/indexbuffer.h \ | ||||
gpu/vertexbuffer.cpp gpu/vertexbuffer.h \ | gpu/vertexbuffer.cpp gpu/vertexbuffer.h \ | ||||
gpu/framebuffer.cpp gpu/framebuffer.h \ | gpu/framebuffer.cpp gpu/framebuffer.h \ | ||||
gpu/texture.cpp gpu/texture.h \ | |||||
\ | \ | ||||
gpu/defaultmaterial.lolfx \ | gpu/defaultmaterial.lolfx \ | ||||
gpu/tile.lolfx \ | gpu/tile.lolfx \ | ||||
@@ -115,6 +115,7 @@ static inline int isnan(float f) | |||||
#include "layer.h" | #include "layer.h" | ||||
#include "gpu/lolfx.h" | #include "gpu/lolfx.h" | ||||
#include "gpu/shader.h" | #include "gpu/shader.h" | ||||
#include "gpu/texture.h" | |||||
#include "gpu/indexbuffer.h" | #include "gpu/indexbuffer.h" | ||||
#include "gpu/vertexbuffer.h" | #include "gpu/vertexbuffer.h" | ||||
#include "gpu/framebuffer.h" | #include "gpu/framebuffer.h" | ||||
@@ -0,0 +1,176 @@ | |||||
// | |||||
// Lol Engine | |||||
// | |||||
// Copyright: (c) 2010-2012 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://sam.zoy.org/projects/COPYING.WTFPL for more details. | |||||
// | |||||
#if defined HAVE_CONFIG_H | |||||
# include "config.h" | |||||
#endif | |||||
#include "core.h" | |||||
#include "lolgl.h" | |||||
#if defined _WIN32 && defined USE_D3D9 | |||||
# define FAR | |||||
# define NEAR | |||||
# include <d3d9.h> | |||||
#endif | |||||
using namespace std; | |||||
#if defined USE_D3D9 | |||||
extern IDirect3DDevice9 *g_d3ddevice; | |||||
#elif defined _XBOX | |||||
extern D3DDevice *g_d3ddevice; | |||||
#endif | |||||
namespace lol | |||||
{ | |||||
// | |||||
// The TextureData class | |||||
// --------------------- | |||||
// | |||||
class TextureData | |||||
{ | |||||
friend class Texture; | |||||
ivec2 m_size; | |||||
#if defined USE_D3D9 | |||||
IDirect3DTexture9 *m_tex; | |||||
#elif defined _XBOX | |||||
D3DTexture *m_tex; | |||||
#else | |||||
GLuint m_texid; | |||||
#endif | |||||
}; | |||||
// | |||||
// The Texture class | |||||
// ----------------- | |||||
// | |||||
/* FIXME: this is all hardcoded over the place */ | |||||
#if __CELLOS_LV2__ | |||||
static GLint const INTERNAL_FORMAT = GL_ARGB_SCE; | |||||
static GLenum const TEXTURE_FORMAT = GL_BGRA; | |||||
static GLenum const TEXTURE_TYPE = GL_UNSIGNED_INT_8_8_8_8_REV; | |||||
#elif defined __native_client__ || defined HAVE_GLES_2X | |||||
static GLint const INTERNAL_FORMAT = GL_RGBA; | |||||
static GLenum const TEXTURE_FORMAT = GL_RGBA; | |||||
static GLenum const TEXTURE_TYPE = GL_UNSIGNED_BYTE; | |||||
#else | |||||
/* Seems efficient for little endian textures */ | |||||
static GLint const INTERNAL_FORMAT = GL_RGBA; | |||||
static GLenum const TEXTURE_FORMAT = GL_BGRA; | |||||
static GLenum const TEXTURE_TYPE = GL_UNSIGNED_INT_8_8_8_8_REV; | |||||
#endif | |||||
Texture::Texture(ivec2 size) | |||||
: m_data(new TextureData) | |||||
{ | |||||
m_data->m_size = size; | |||||
#if defined USE_D3D9 | |||||
g_d3ddevice->CreateTexture(m_data->m_size.x, m_data->m_size.y, 1, | |||||
D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, | |||||
D3DPOOL_SYSTEMMEM, &m_tex, NULL); | |||||
#elif defined _XBOX | |||||
/* By default the X360 will swizzle the texture. Ask for linear. */ | |||||
g_d3ddevice->CreateTexture(m_data->m_size.x, m_data->m_size.y, 1, | |||||
D3DUSAGE_WRITEONLY, D3DFMT_LIN_A8R8G8B8, | |||||
D3DPOOL_DEFAULT, &m_tex, NULL); | |||||
#else | |||||
glGenTextures(1, &m_data->m_texid); | |||||
glBindTexture(GL_TEXTURE_2D, m_data->m_texid); | |||||
# if defined __CELLOS_LV2__ | |||||
/* We need this hint because by default the storage type is | |||||
* GL_TEXTURE_SWIZZLED_GPU_SCE. */ | |||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_ALLOCATION_HINT_SCE, | |||||
GL_TEXTURE_TILED_GPU_SCE); | |||||
# endif | |||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |||||
#endif | |||||
} | |||||
void Texture::Bind() | |||||
{ | |||||
#if defined _XBOX || defined USE_D3D9 | |||||
g_d3ddevice->SetTexture(0, m_data->m_tex); | |||||
#else | |||||
# if !defined HAVE_GLES_2X | |||||
glEnable(GL_TEXTURE_2D); | |||||
# endif | |||||
glBindTexture(GL_TEXTURE_2D, m_data->m_texid); | |||||
#endif | |||||
} | |||||
void Texture::SetData(void *data) | |||||
{ | |||||
#if defined _XBOX || defined USE_D3D9 | |||||
D3DLOCKED_RECT rect; | |||||
# if defined _XBOX | |||||
m_data->m_tex->LockRect(0, &rect, NULL, D3DLOCK_NOOVERWRITE); | |||||
# else | |||||
m_data->m_tex->LockRect(0, &rect, NULL, | |||||
D3DLOCK_DISCARD | D3DLOCK_NOOVERWRITE); | |||||
# endif | |||||
memcpy(rect.pBits, data, rect.Pitch * rect.Height); | |||||
m_data->m_tex->UnlockRect(0); | |||||
#else | |||||
glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, | |||||
m_data->m_size.x, m_data->m_size.y, 0, | |||||
TEXTURE_FORMAT, TEXTURE_TYPE, data); | |||||
#endif | |||||
} | |||||
void Texture::SetSubData(ivec2 origin, ivec2 size, void *data) | |||||
{ | |||||
#if defined _XBOX || defined USE_D3D9 | |||||
D3DLOCKED_RECT rect; | |||||
# if defined _XBOX | |||||
m_data->m_tex->LockRect(0, &rect, NULL, D3DLOCK_NOOVERWRITE); | |||||
# else | |||||
m_data->m_tex->LockRect(0, &rect, NULL, | |||||
D3DLOCK_DISCARD | D3DLOCK_NOOVERWRITE); | |||||
# endif | |||||
for (int j = 0; j < size.y; j++) | |||||
{ | |||||
uint8_t *dst = (uint8_t *)rect.pBits + (origin.y + j) * rect.Pitch; | |||||
/* FIXME: the source or destination pitch isn't necessarily 4! */ | |||||
uint8_t *src = (uint8_t *)data + j * size.y * 4; | |||||
memcpy(dst, src, size.y * 4); | |||||
} | |||||
m_data->m_tex->UnlockRect(0); | |||||
#else | |||||
glTexSubImage2D(GL_TEXTURE_2D, 0, origin.x, origin.y, size.x, size.y, | |||||
TEXTURE_FORMAT, TEXTURE_TYPE, data); | |||||
#endif | |||||
} | |||||
Texture::~Texture() | |||||
{ | |||||
#if defined USE_D3D9 || defined _XBOX | |||||
m_data->m_tex->Release(); | |||||
#else | |||||
glDeleteTextures(1, &m_data->m_texid); | |||||
#endif | |||||
delete m_data; | |||||
} | |||||
} /* namespace lol */ | |||||
@@ -0,0 +1,39 @@ | |||||
// | |||||
// Lol Engine | |||||
// | |||||
// Copyright: (c) 2010-2012 Sam Hocevar <sam@hocevar.net> | |||||
// This program is free software; you can redistribute it and/or | |||||
// modify it under the terms of the Do What The Fuck You Want To | |||||
// Public License, Version 2, as published by Sam Hocevar. See | |||||
// http://sam.zoy.org/projects/COPYING.WTFPL for more details. | |||||
// | |||||
// | |||||
// The Texture class | |||||
// ----------------- | |||||
// | |||||
#if !defined __LOL_TEXTURE_H__ | |||||
#define __LOL_TEXTURE_H__ | |||||
namespace lol | |||||
{ | |||||
class Texture | |||||
{ | |||||
public: | |||||
Texture(ivec2 size); | |||||
~Texture(); | |||||
void Bind(); | |||||
void SetData(void *data); | |||||
void SetSubData(ivec2 origin, ivec2 size, void *data); | |||||
private: | |||||
class TextureData *m_data; | |||||
}; | |||||
} /* namespace lol */ | |||||
#endif // __LOL_TEXTURE_H__ | |||||
@@ -254,6 +254,7 @@ | |||||
<ClCompile Include="gpu\lolfx-compiler.cpp" /> | <ClCompile Include="gpu\lolfx-compiler.cpp" /> | ||||
<ClCompile Include="gpu\lolfx.cpp" /> | <ClCompile Include="gpu\lolfx.cpp" /> | ||||
<ClCompile Include="gpu\shader.cpp" /> | <ClCompile Include="gpu\shader.cpp" /> | ||||
<ClCompile Include="gpu\texture.cpp" /> | |||||
<ClCompile Include="gpu\vertexbuffer.cpp" /> | <ClCompile Include="gpu\vertexbuffer.cpp" /> | ||||
<ClCompile Include="gradient.cpp" /> | <ClCompile Include="gradient.cpp" /> | ||||
<ClCompile Include="hash.cpp" /> | <ClCompile Include="hash.cpp" /> | ||||
@@ -567,6 +568,7 @@ | |||||
<ClInclude Include="gpu\lolfx-compiler.h" /> | <ClInclude Include="gpu\lolfx-compiler.h" /> | ||||
<ClInclude Include="gpu\lolfx.h" /> | <ClInclude Include="gpu\lolfx.h" /> | ||||
<ClInclude Include="gpu\shader.h" /> | <ClInclude Include="gpu\shader.h" /> | ||||
<ClInclude Include="gpu\texture.h" /> | |||||
<ClInclude Include="gpu\vertexbuffer.h" /> | <ClInclude Include="gpu\vertexbuffer.h" /> | ||||
<ClInclude Include="gradient.h" /> | <ClInclude Include="gradient.h" /> | ||||
<ClInclude Include="hash.h" /> | <ClInclude Include="hash.h" /> | ||||
@@ -97,6 +97,9 @@ | |||||
<ClCompile Include="gpu\shader.cpp"> | <ClCompile Include="gpu\shader.cpp"> | ||||
<Filter>src\gpu</Filter> | <Filter>src\gpu</Filter> | ||||
</ClCompile> | </ClCompile> | ||||
<ClCompile Include="gpu\texture.cpp"> | |||||
<Filter>src\gpu</Filter> | |||||
</ClCompile> | |||||
<ClCompile Include="gpu\vertexbuffer.cpp"> | <ClCompile Include="gpu\vertexbuffer.cpp"> | ||||
<Filter>src\gpu</Filter> | <Filter>src\gpu</Filter> | ||||
</ClCompile> | </ClCompile> | ||||
@@ -669,6 +672,9 @@ | |||||
<ClInclude Include="gpu\shader.h"> | <ClInclude Include="gpu\shader.h"> | ||||
<Filter>src\gpu</Filter> | <Filter>src\gpu</Filter> | ||||
</ClInclude> | </ClInclude> | ||||
<ClInclude Include="gpu\texture.h"> | |||||
<Filter>src\gpu</Filter> | |||||
</ClInclude> | |||||
<ClInclude Include="gpu\vertexbuffer.h"> | <ClInclude Include="gpu\vertexbuffer.h"> | ||||
<Filter>src\gpu</Filter> | <Filter>src\gpu</Filter> | ||||
</ClInclude> | </ClInclude> | ||||
@@ -15,41 +15,12 @@ | |||||
#include <cstring> | #include <cstring> | ||||
#include "core.h" | #include "core.h" | ||||
#include "lolgl.h" | |||||
#include "loldebug.h" | #include "loldebug.h" | ||||
using namespace lol; | using namespace lol; | ||||
#if defined _WIN32 | |||||
# include <direct.h> | |||||
# if defined USE_D3D9 | |||||
# define FAR | |||||
# define NEAR | |||||
# include <d3d9.h> | |||||
# endif | |||||
#endif | |||||
extern char const *lolfx_11_fractal; | extern char const *lolfx_11_fractal; | ||||
#if defined USE_D3D9 | |||||
extern IDirect3DDevice9 *g_d3ddevice; | |||||
#elif defined _XBOX | |||||
extern D3DDevice *g_d3ddevice; | |||||
#elif __CELLOS_LV2__ | |||||
static GLint const INTERNAL_FORMAT = GL_ARGB_SCE; | |||||
static GLenum const TEXTURE_FORMAT = GL_BGRA; | |||||
static GLenum const TEXTURE_TYPE = GL_UNSIGNED_INT_8_8_8_8_REV; | |||||
#elif defined __native_client__ || defined HAVE_GLES_2X | |||||
static GLint const INTERNAL_FORMAT = GL_RGBA; | |||||
static GLenum const TEXTURE_FORMAT = GL_RGBA; | |||||
static GLenum const TEXTURE_TYPE = GL_UNSIGNED_BYTE; | |||||
#else | |||||
/* Seems efficient for little endian textures */ | |||||
static GLint const INTERNAL_FORMAT = GL_RGBA; | |||||
static GLenum const TEXTURE_FORMAT = GL_BGRA; | |||||
static GLenum const TEXTURE_TYPE = GL_UNSIGNED_INT_8_8_8_8_REV; | |||||
#endif | |||||
class Fractal : public WorldEntity | class Fractal : public WorldEntity | ||||
{ | { | ||||
public: | public: | ||||
@@ -467,32 +438,13 @@ public: | |||||
if (!m_ready) | if (!m_ready) | ||||
{ | { | ||||
#if !defined _XBOX && !defined USE_D3D9 | |||||
/* Create a texture of half the width and twice the height | /* Create a texture of half the width and twice the height | ||||
* so that we can upload four different subimages each frame. */ | * so that we can upload four different subimages each frame. */ | ||||
glGenTextures(1, &m_texid); | |||||
glBindTexture(GL_TEXTURE_2D, m_texid); | |||||
glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, | |||||
m_size.x / 2, m_size.y * 2, 0, | |||||
TEXTURE_FORMAT, TEXTURE_TYPE, &m_pixels[0]); | |||||
# if defined __CELLOS_LV2__ | |||||
/* We need this hint because by default the storage type is | |||||
* GL_TEXTURE_SWIZZLED_GPU_SCE. */ | |||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_ALLOCATION_HINT_SCE, | |||||
GL_TEXTURE_TILED_GPU_SCE); | |||||
# endif | |||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |||||
#elif defined _XBOX | |||||
/* By default the X360 will swizzle the texture. Ask for linear. */ | |||||
g_d3ddevice->CreateTexture(m_size.x / 2, m_size.y * 2, 1, | |||||
D3DUSAGE_WRITEONLY, D3DFMT_LIN_A8R8G8B8, | |||||
D3DPOOL_DEFAULT, &m_tex, NULL); | |||||
#else | |||||
g_d3ddevice->CreateTexture(m_size.x / 2, m_size.y * 2, 1, | |||||
D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, | |||||
D3DPOOL_SYSTEMMEM, &m_tex, NULL); | |||||
#endif | |||||
m_texture = new Texture(ivec2(m_size.x / 2, m_size.y * 2)); | |||||
/* Ensure the texture data is complete at least once, otherwise | |||||
* uploading subimages will not work. */ | |||||
m_texture->SetData(&m_pixels[0]); | |||||
m_shader = Shader::Create(lolfx_11_fractal); | m_shader = Shader::Create(lolfx_11_fractal); | ||||
@@ -520,14 +472,7 @@ public: | |||||
m_ready = true; | m_ready = true; | ||||
} | } | ||||
#if defined _XBOX || defined USE_D3D9 | |||||
#else | |||||
# if !defined HAVE_GLES_2X | |||||
glEnable(GL_TEXTURE_2D); | |||||
# endif | |||||
glBindTexture(GL_TEXTURE_2D, m_texid); | |||||
#endif | |||||
m_texture->Bind(); | |||||
if (m_dirty[m_frame]) | if (m_dirty[m_frame]) | ||||
{ | { | ||||
@@ -536,32 +481,14 @@ public: | |||||
m_dirty[m_frame]--; | m_dirty[m_frame]--; | ||||
#if defined _XBOX || defined USE_D3D9 | |||||
D3DLOCKED_RECT rect; | |||||
# if defined _XBOX | |||||
m_tex->LockRect(0, &rect, NULL, D3DLOCK_NOOVERWRITE); | |||||
# else | |||||
m_tex->LockRect(0, &rect, NULL, | |||||
D3DLOCK_DISCARD | D3DLOCK_NOOVERWRITE); | |||||
# endif | |||||
for (int j = 0; j < m_size.y * 2; j++) | |||||
{ | |||||
u8vec4 *line = (u8vec4 *)rect.pBits + j * rect.Pitch / 4; | |||||
for (int i = 0; i < m_size.x / 2; i++) | |||||
line[i] = m_pixels[m_size.x / 2 * j + i]; | |||||
} | |||||
m_tex->UnlockRect(0); | |||||
#elif defined __CELLOS_LV2__ | |||||
#if defined __CELLOS_LV2__ | |||||
/* glTexSubImage2D is extremely slow on the PS3, to the point | /* glTexSubImage2D is extremely slow on the PS3, to the point | ||||
* that uploading the whole texture is 40 times faster. */ | * that uploading the whole texture is 40 times faster. */ | ||||
glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, | |||||
m_size.x / 2, m_size.y * 2, 0, | |||||
TEXTURE_FORMAT, TEXTURE_TYPE, &m_pixels[0]); | |||||
m_texture->SetData(&m_pixels[0]); | |||||
#else | #else | ||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, m_frame * m_size.y / 2, | |||||
m_size.x / 2, m_size.y / 2, | |||||
TEXTURE_FORMAT, TEXTURE_TYPE, | |||||
&m_pixels[m_size.x * m_size.y / 4 * m_frame]); | |||||
m_texture->SetSubData(ivec2(0, m_frame * m_size.y / 2), | |||||
m_size / 2, | |||||
&m_pixels[m_size.x * m_size.y / 4 * m_frame]); | |||||
#endif | #endif | ||||
} | } | ||||
@@ -572,12 +499,7 @@ public: | |||||
m_vdecl->Bind(); | m_vdecl->Bind(); | ||||
m_vdecl->SetStream(m_vbo, m_vertexattrib); | m_vdecl->SetStream(m_vbo, m_vertexattrib); | ||||
m_vdecl->SetStream(m_tbo, m_texattrib); | m_vdecl->SetStream(m_tbo, m_texattrib); | ||||
#if defined _XBOX || defined USE_D3D9 | |||||
g_d3ddevice->SetTexture(0, m_tex); | |||||
g_d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); | |||||
#elif !defined __CELLOS_LV2__ && !defined __ANDROID__ | |||||
#else | |||||
#endif | |||||
m_texture->Bind(); | |||||
m_vdecl->DrawElements(MeshPrimitive::Triangles, 0, 6); | m_vdecl->DrawElements(MeshPrimitive::Triangles, 0, 6); | ||||
m_vdecl->Unbind(); | m_vdecl->Unbind(); | ||||
} | } | ||||
@@ -599,13 +521,8 @@ private: | |||||
VertexDeclaration *m_vdecl; | VertexDeclaration *m_vdecl; | ||||
VertexBuffer *m_vbo, *m_tbo; | VertexBuffer *m_vbo, *m_tbo; | ||||
#if defined USE_D3D9 | |||||
IDirect3DTexture9 *m_tex; | |||||
#elif defined _XBOX | |||||
D3DTexture *m_tex; | |||||
#else | |||||
GLuint m_texid; | |||||
#endif | |||||
Texture *m_texture; | |||||
int m_frame, m_slices, m_dirty[4]; | int m_frame, m_slices, m_dirty[4]; | ||||
bool m_ready, m_drag; | bool m_ready, m_drag; | ||||