Open shadd3 opened 8 years ago
@shadd3 For displaying code, you can use triple quote (I took the freedom to edit your comment)
The texture_atlas_upload
should do nothing if there is not something new to upload. Isn't it the case ?
right, but from my understanding, it is not the case see my comments in your code + my proposal best regards - shadd
void
texture_atlas_upload( texture_atlas_t * self )
{
assert( self );
assert( self->data );
// shadd : the id texture is created once
if( !self->id )
{
glGenTextures( 1, &self->id );
}
glBindTexture( GL_TEXTURE_2D, self->id );
// shadd : the tex parameters are bound to texture object id; so it is not necessary to apply at each time (see immutable vs mutable texture Gl khronos spec)
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
if( self->depth == 4 )
{
.....
}
else if( self->depth == 3 )
{
// shadd: the texture is allocated and uploaded at each time; use glTexSubImage2D for updating
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, self->width, self->height,
0, GL_RGB, GL_UNSIGNED_BYTE, self->data );
}
else
{
.....
}
}
from https://www.opengl.org/wiki/Common_Mistakes
Updating a texture To change texels in an already existing 2d texture, use glTexSubImage2D:
glBindTexture(GL_TEXTURE_2D, textureID); //A texture you have already created storage for glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, pixels); glTexImage2D creates the storage for the texture, defining the size/format and removing all previous pixel data. glTexSubImage2D only modifies pixel data within the texture. It can be used to update all the texels, or simply a portion of them.
To copy texels from the framebuffer, use glCopyTexSubImage2D.
glBindTexture(GL_TEXTURE_2D, textureID); //A texture you have already created storage for glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, width, height); //Copy current read buffer to texture
Note that there is a glCopyTexImage2D function, which does the copy to fill the image, but also defines the image size, format and so forth, just like glTexImage2D.
- in openGlES3.0 and openGL desktop it is better to use glTexStorage2D => Immutable vs mutable texture object https://www.khronos.org/opengles/sdk/docs/man3/html/glTexStorage2D.xhtml
- my proposal I tested on my client code; it seems ok ...
void
texture_atlas_upload( texture_atlas_t * self )
{
assert( self );
assert( self->data );
size_t const s = vector_size(self->nodes);
if (!self->id)
{
glGenTextures(1, &self->id);
glBindTexture(GL_TEXTURE_2D, self->id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
if (self->depth == 4)
{
#ifdef GL_UNSIGNED_INT_8_8_8_8_REV
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self->width, self->height,
0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, self->data);
#else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self->width, self->height,
0, GL_RGBA, GL_UNSIGNED_BYTE, self->data);
#endif
}
else if (self->depth == 3)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, self->width, self->height,
0, GL_RGB, GL_UNSIGNED_BYTE, self->data);
}
else
{
#if defined(GL_ES_VERSION_2_0) || defined(GL_ES_VERSION_3_0)
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, self->width, self->height,
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, self->data);
#else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, self->width, self->height,
0, GL_RED, GL_UNSIGNED_BYTE, self->data);
#endif
}
}
else
{
if (s != self->nodesCurSize)
{
glBindTexture(GL_TEXTURE_2D, self->id);
if (self->depth == 4)
{
// TODO: glTexSubImage2D
}
else if (self->depth == 3)
{
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, self->width, self->height, GL_RGB, GL_UNSIGNED_BYTE, self->data);
}
else
{
// TODO: glTexSubImage2D
}
}
}
self->nodesCurSize = s;
}
The texture_atlas_upload
API call was dropped just recently. Library clients should handle the texture generation, uploading and cleaning up by themselves.
Hello,
I am building the font on the fly. During the drawing, I call ftgl::texture_atlas_upload(m_text_buffer->manager->atlas); This call is necessary when some new glyph have been added. otherwise this call causes useless GPU upload transferts. Currently, I am using this hack to avoid some useless transferts
we could not have an "official AP"I that would be responsible for transferring or not the texture ? Best regards