Browse Source

gpu: support 1-component (luminance) textures.

legacy
Sam Hocevar sam 12 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;
GLenum m_gl_format, m_gl_type;
#endif
int m_bytes_per_elem;
};

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

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

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

/* A8R8G8B8 */
# if defined USE_D3D9
D3DFMT_A8R8G8B8,
{ D3DFMT_A8R8G8B8, 4 },
# else
/* 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
};

D3DFORMAT d3d_format = GET_CLAMPED(d3d_formats, format);
D3DFORMAT d3d_format = GET_CLAMPED(d3d_formats, format).format;
# if defined USE_D3D9
int d3d_usage = D3DUSAGE_DYNAMIC;
# 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,
d3d_usage, d3d_format,
D3DPOOL_DEFAULT, &m_data->m_texture, NULL);
m_data->m_bytes_per_elem = GET_CLAMPED(d3d_formats, format).bytes;
#else
static struct
{
GLint internal_format;
GLenum format, type;
int bytes;
}
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__
{ 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
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, 4 },
/* FIXME: if GL_RGBA is not available, we should advertise
* 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
/* 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
};

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_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);
glBindTexture(GL_TEXTURE_2D, m_data->m_texture);
@@ -207,12 +216,12 @@ void Texture::SetSubData(ivec2 origin, ivec2 size, void *data)
D3DLOCKED_RECT rect;
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++)
{
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);


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

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



+ 2
- 2
src/tileset.cpp View File

@@ -123,12 +123,12 @@ void TileSet::TickDraw(float seconds)
switch (data->img->GetFormat())
{
case Image::FORMAT_RGB:
format = PixelFormat::R8G8B8;
format = PixelFormat::RGB_8;
planes = 3;
break;
case Image::FORMAT_RGBA:
default:
format = PixelFormat::A8R8G8B8;
format = PixelFormat::ARGB_8;
planes = 4;
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_heightmap = new uint8_t[4 * TEXTURE_WIDTH * 1];
m_heightmap = new uint8_t[TEXTURE_WIDTH * 1];
}

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

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

/* Scroll left */
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 = std::max(15, std::min(height, 240));
m_heightmap[4 * (TEXTURE_WIDTH - 1)] = height;
m_heightmap[TEXTURE_WIDTH - 1] = height;

/* Update frame counter */
++m_frames;
@@ -72,7 +72,7 @@ public:
/* Initialise GPU data */
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_coord = m_shader->GetAttribLocation("in_Position", VertexUsage::Position, 0);
@@ -117,7 +117,7 @@ int main(int argc, char **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();



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

@@ -442,7 +442,7 @@ public:
/* Create a texture of half the width and twice the height
* so that we can upload four different subimages each frame. */
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
* uploading subimages will not work. */


Loading…
Cancel
Save