Hi, I’m using PBO texture uploads for a couple of years now - code is working fine. Now I wanted to change my multi PBO, multi Texture approach to using a singular texture as a 2D Atlas.
When I copy one tile into the texture though, I get the result that the copied tile has reduced in height and is copied multiple times in width instead.
This is my scenario:
atlas texture: 5760x1080
tile: 1920x1080
result: attached
original: attached
It looks like the texture is filling a row of a 3x3 array instead of just one tile of a 1x3 array… the issues scales with the atlas size:
1920x1080 atlas -> no error (tile size = atlas size)
3840x1080 atlas -> expected: 1x2, but actually: 2x2
5760x1080 atlas -> expected: 1x3, but actually: 3x3
and so on…
Any clues?
Code:
int m_textureWidth = 5760;
int m_textureHeight = 1080;
int m_atlasSize = m_textureWidth*m_textureHeight*3;
int m_tileSize = 1920*1080*3;
GLuint* m_textureIds;
GLuint* m_pboIds;
unsigned char* m_pBuf = .. contains the image bytes ..
void InitAtlasTexture()
{
m_textureIds = new GLuint[1];
glGenTextures(1, m_textureIds);
glBindTexture(GL_TEXTURE_2D, m_textureIds[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_BGR, m_textureWidth, m_textureHeight, 0, GL_BGR, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
}
void InitPBO()
{
m_pboIds = new GLuint[1];
glGenBuffers(1, m_pboIds);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pboIds[0]);
glBufferStorage(GL_PIXEL_UNPACK_BUFFER, m_atlasSize, 0, GL_MAP_WRITE_BIT);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
}
bool CopyTexture()
{
GLubyte* ptr = NULL;
ptr = (GLubyte*)glMapNamedBufferRange(m_pboIds[0], 0, m_atlasSize, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_INVALIDATE_RANGE_BIT);
if (ptr)
{
memcpy(ptr, m_pBuf, m_tileSize);
glUnmapNamedBuffer(m_pboIds[0]);
}
else
{
return false;
}
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, m_pboIds[0]);
glTextureSubImage2D(m_textureIds[0], 0, 0, 0, m_textureWidth, m_textureHeight, GL_BGR, GL_UNSIGNED_BYTE, 0);
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
return true;
}
void Render()
{
//..just the snipet thats important here:
float left = 0.0;
float right = 1.0;
float top = 1.0;
float bottom = 0.0;
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, m_textureIds[0]);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(left, bottom);
glVertex3f(-width/2.0, -height/2.0, 0.0f);
glTexCoord2f(right, bottom);
glVertex3f(width/2.0, -height/2.0, 0.0f);
glTexCoord2f(left, top);
glVertex3f(-width/2.0, height/2.0, 0.0f);
glTexCoord2f(right, top);
glVertex3f(width/2.0, height/2.0, 0.0f);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
}