Browse Source

gpu: support 1-component (luminance) textures.

legacy
Sam Hocevar sam 13 years ago
parent
commit
42fb9b6853
5 changed files with 52 additions and 42 deletions
  1. +38
    -29
      src/gpu/texture.cpp
  2. +4
    -3
      src/gpu/texture.h
  3. +2
    -2
      src/tileset.cpp
  4. +7
    -7
      tutorial/04_texture.cpp
  5. +1
    -1
      tutorial/11_fractal.cpp

+ 38
- 29
src/gpu/texture.cpp View File

@@ -53,6 +53,7 @@ class TextureData
GLint m_internal_format; GLint m_internal_format;
GLenum m_gl_format, m_gl_type; GLenum m_gl_format, m_gl_type;
#endif #endif
int m_bytes_per_elem;
}; };


// //
@@ -71,28 +72,41 @@ Texture::Texture(ivec2 size, PixelFormat format)
m_data->m_format = format; m_data->m_format = format;


#if defined USE_D3D9 || defined _XBOX #if defined USE_D3D9 || defined _XBOX
static D3DFORMAT const d3d_formats[] =
static struct
{
D3DFORMAT format;
int bytes;
}
const d3d_formats[] =
{ {
/* Unknown */ /* Unknown */
D3DFMT_UNKNOWN,
{ D3DFMT_UNKNOWN, 0 },


/* R8G8B8 */ /* R8G8B8 */
# if defined USE_D3D9 # if defined USE_D3D9
D3DFMT_R8G8B8,
{ D3DFMT_R8G8B8, 3 },
# else # else
D3DFMT_UNKNOWN,
{ D3DFMT_UNKNOWN, 0 },
# endif # endif


/* A8R8G8B8 */ /* A8R8G8B8 */
# if defined USE_D3D9 # if defined USE_D3D9
D3DFMT_A8R8G8B8,
{ D3DFMT_A8R8G8B8, 4 },
# else # else
/* By default the X360 will swizzle the texture. Ask for linear. */ /* By default the X360 will swizzle the texture. Ask for linear. */
D3DFMT_LIN_A8R8G8B8,
{ D3DFMT_LIN_A8R8G8B8, 4 },
# endif

/* Y8 */
# if defined USE_D3D9
{ D3DFMT_L8, 1 },
# else
/* By default the X360 will swizzle the texture. Ask for linear. */
{ D3DFMT_LIN_L8, 1 },
# endif # endif
}; };


D3DFORMAT d3d_format = GET_CLAMPED(d3d_formats, format);
D3DFORMAT d3d_format = GET_CLAMPED(d3d_formats, format).format;
# if defined USE_D3D9 # if defined USE_D3D9
int d3d_usage = D3DUSAGE_DYNAMIC; int d3d_usage = D3DUSAGE_DYNAMIC;
# else # else
@@ -102,46 +116,41 @@ Texture::Texture(ivec2 size, PixelFormat format)
g_d3ddevice->CreateTexture(m_data->m_size.x, m_data->m_size.y, 1, g_d3ddevice->CreateTexture(m_data->m_size.x, m_data->m_size.y, 1,
d3d_usage, d3d_format, d3d_usage, d3d_format,
D3DPOOL_DEFAULT, &m_data->m_texture, NULL); D3DPOOL_DEFAULT, &m_data->m_texture, NULL);
m_data->m_bytes_per_elem = GET_CLAMPED(d3d_formats, format).bytes;
#else #else
static struct static struct
{ {
GLint internal_format; GLint internal_format;
GLenum format, type; GLenum format, type;
int bytes;
} }
const gl_formats[] = const gl_formats[] =
{ {
/* Unknown */
{ 0, 0, 0 },

/* R8G8B8 */
{ GL_RGB, GL_RGB, GL_UNSIGNED_BYTE },

/* A8R8G8B8 */
#if __CELLOS_LV2__
{ GL_ARGB_SCE, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV },
#elif defined __native_client__ || defined HAVE_GLES_2X
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE },
#else
/* Seems efficient for little endian textures */
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV },
#endif
{ 0, 0, 0, 0 }, /* Unknown */
{ GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, 3 }, /* RGB_8 */


/* A8B8G8R8 */
#if __CELLOS_LV2__ #if __CELLOS_LV2__
{ GL_ARGB_SCE, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV },
{ GL_ARGB_SCE, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 4 },
{ GL_ARGB_SCE, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, 4 },
{ GL_LUMINANCE8, GL_LUMINANCE, GL_UNSIGNED_BYTE, 1 },
#elif defined __native_client__ || defined HAVE_GLES_2X #elif defined __native_client__ || defined HAVE_GLES_2X
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, 4 },
/* FIXME: if GL_RGBA is not available, we should advertise /* FIXME: if GL_RGBA is not available, we should advertise
* this format as "not available" on this platform. */ * this format as "not available" on this platform. */
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE },
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, 4 },
{ GL_R8, GL_R8, GL_UNSIGNED_BYTE, 1 },
#else #else
/* Seems efficient for little endian textures */ /* Seems efficient for little endian textures */
{ GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV },
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 4 }, /* ARGB_8 */
{ GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4 }, /* ABGR_8 */
{ GL_R8, GL_RED, GL_UNSIGNED_BYTE, 1 }, /* A8 */
#endif #endif
}; };


m_data->m_internal_format = GET_CLAMPED(gl_formats, format).internal_format; m_data->m_internal_format = GET_CLAMPED(gl_formats, format).internal_format;
m_data->m_gl_format = GET_CLAMPED(gl_formats, format).format; m_data->m_gl_format = GET_CLAMPED(gl_formats, format).format;
m_data->m_gl_type = GET_CLAMPED(gl_formats, format).type; m_data->m_gl_type = GET_CLAMPED(gl_formats, format).type;
m_data->m_bytes_per_elem = GET_CLAMPED(gl_formats, format).bytes;


glGenTextures(1, &m_data->m_texture); glGenTextures(1, &m_data->m_texture);
glBindTexture(GL_TEXTURE_2D, m_data->m_texture); glBindTexture(GL_TEXTURE_2D, m_data->m_texture);
@@ -207,12 +216,12 @@ void Texture::SetSubData(ivec2 origin, ivec2 size, void *data)
D3DLOCKED_RECT rect; D3DLOCKED_RECT rect;
m_data->m_texture->LockRect(0, &rect, NULL, 0); m_data->m_texture->LockRect(0, &rect, NULL, 0);


int stride = size.x * m_data->m_bytes_per_elem;
for (int j = 0; j < size.y; j++) for (int j = 0; j < size.y; j++)
{ {
uint8_t *dst = (uint8_t *)rect.pBits + (origin.y + j) * rect.Pitch; 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.x * 4;
memcpy(dst, src, size.x * 4);
uint8_t *src = (uint8_t *)data + j * stride;
memcpy(dst, src, stride);
} }


m_data->m_texture->UnlockRect(0); m_data->m_texture->UnlockRect(0);


+ 4
- 3
src/gpu/texture.h View File

@@ -25,9 +25,10 @@ struct PixelFormat
enum Value enum Value
{ {
Unknown = 0, Unknown = 0,
R8G8B8,
A8R8G8B8,
A8B8G8R8,
RGB_8,
ARGB_8,
ABGR_8,
Y_8,
} }
m_value; m_value;




+ 2
- 2
src/tileset.cpp View File

@@ -123,12 +123,12 @@ void TileSet::TickDraw(float seconds)
switch (data->img->GetFormat()) switch (data->img->GetFormat())
{ {
case Image::FORMAT_RGB: case Image::FORMAT_RGB:
format = PixelFormat::R8G8B8;
format = PixelFormat::RGB_8;
planes = 3; planes = 3;
break; break;
case Image::FORMAT_RGBA: case Image::FORMAT_RGBA:
default: default:
format = PixelFormat::A8R8G8B8;
format = PixelFormat::ARGB_8;
planes = 4; planes = 4;
break; break;
} }


+ 7
- 7
tutorial/04_texture.cpp View File

@@ -36,7 +36,7 @@ public:
m_vertices << vec2( 1.0, -1.0); m_vertices << vec2( 1.0, -1.0);
m_vertices << vec2( 1.0, 1.0); m_vertices << vec2( 1.0, 1.0);


m_heightmap = new uint8_t[4 * TEXTURE_WIDTH * 1];
m_heightmap = new uint8_t[TEXTURE_WIDTH * 1];
} }


virtual ~TextureDemo() virtual ~TextureDemo()
@@ -50,16 +50,16 @@ public:


/* Generate a new heightmap at the beginning */ /* Generate a new heightmap at the beginning */
if (m_frames == 0) if (m_frames == 0)
memset(m_heightmap, 255, 4 * TEXTURE_WIDTH);
memset(m_heightmap, 255, TEXTURE_WIDTH);


/* Scroll left */ /* Scroll left */
for (int i = 0; i < TEXTURE_WIDTH - 1; i++) for (int i = 0; i < TEXTURE_WIDTH - 1; i++)
m_heightmap[4 * i] = m_heightmap[4 * i + 4];
m_heightmap[i] = m_heightmap[i + 1];


int height = m_heightmap[4 * (TEXTURE_WIDTH - 1)];
int height = m_heightmap[TEXTURE_WIDTH - 1];
height = (height + 127 + 40 * lol::sin(m_frames * 0.03) + rand() % 97 - 38) / 2; height = (height + 127 + 40 * lol::sin(m_frames * 0.03) + rand() % 97 - 38) / 2;
height = std::max(15, std::min(height, 240)); height = std::max(15, std::min(height, 240));
m_heightmap[4 * (TEXTURE_WIDTH - 1)] = height;
m_heightmap[TEXTURE_WIDTH - 1] = height;


/* Update frame counter */ /* Update frame counter */
++m_frames; ++m_frames;
@@ -72,7 +72,7 @@ public:
/* Initialise GPU data */ /* Initialise GPU data */
if (!m_ready) if (!m_ready)
{ {
m_texture = new Texture(ivec2(TEXTURE_WIDTH, 1), PixelFormat::A8R8G8B8);
m_texture = new Texture(ivec2(TEXTURE_WIDTH, 1), PixelFormat::Y_8);


m_shader = Shader::Create(LOLFX_RESOURCE_NAME(04_texture)); m_shader = Shader::Create(LOLFX_RESOURCE_NAME(04_texture));
m_coord = m_shader->GetAttribLocation("in_Position", VertexUsage::Position, 0); m_coord = m_shader->GetAttribLocation("in_Position", VertexUsage::Position, 0);
@@ -117,7 +117,7 @@ int main(int argc, char **argv)
{ {
System::Init(argc, argv); System::Init(argc, argv);


Application app("Tutorial 4: Texture", ivec2(640, 480), 60.0f);
Application app("Tutorial 4: Texture", ivec2(1280, 720), 60.0f);


new TextureDemo(); new TextureDemo();




+ 1
- 1
tutorial/11_fractal.cpp View File

@@ -442,7 +442,7 @@ public:
/* 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. */
m_texture = new Texture(ivec2(m_size.x / 2, m_size.y * 2), m_texture = new Texture(ivec2(m_size.x / 2, m_size.y * 2),
PixelFormat::A8B8G8R8);
PixelFormat::ABGR_8);


/* Ensure the texture data is complete at least once, otherwise /* Ensure the texture data is complete at least once, otherwise
* uploading subimages will not work. */ * uploading subimages will not work. */


Loading…
Cancel
Save