Sign in to follow this  
Oogst

glTexSubImage2D fails on some computers

Recommended Posts

I use glTexSubImage2D to render characters of a font to a texture when needed. This works almost everywhere, but on some computers, the font just disappears after a while. This is what seems to happen on those computers:

-initial characters are rendered to font using glTexSubImage2D
-font looks good in the game during gameplay and such
-game requests additional characters and these are rendered to the texture
-font entirely disappears in the game

This suggests that the problem may have something to do with the previously rendered frame. Or it may be accidental and may in fact be caused by the phase of the moon.

I am kind of stuck with this, especially since it only fails on some rare computers, so I am hoping somewhere here can help me find the problem.

I'll post the related code below.

Thanks in advance! :)

Share this post


Link to post
Share on other sites
This is the code I use to create the font texture:


glGenBuffers(1, &pixelBufferObjectID);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pixelBufferObjectID);
glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, maximumGlyphDataSize, 0, GL_STREAM_DRAW);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);

const GLuint bytesPerPixel = 2;
const GLuint bufferSize = textureSize * textureSize * bytesPerPixel;

// create a zero filled buffer
GLubyte* imageData = new GLubyte[bufferSize];
memset(imageData, 0, bufferSize);

// generate and bind texture
unsigned int textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

// write the image data to the texture to create an empty texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, textureSize, textureSize,
0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, imageData);

// clean up after usage
delete[] imageData;


This is the code that renders to the font texture:


glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pixelBufferObjectID);
glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, maximumGlyphDataSize, 0, GL_STREAM_DRAW);
void* buffer = glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY);

if (buffer)
{
// copy pixels from glyph to the pixel buffer
writeGlyphToPixelBuffer(glyph, buffer);

// we are done with copying, unmap the buffer so glTexSubImage2D can use it
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);

// write to this texture, use linear filtering, 0 = from the pixel buffer
glBindTexture(GL_TEXTURE_2D, texture.getTextureId());
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexSubImage2D(GL_TEXTURE_2D, 0,
slot->pixelPositionLeft,
texture.height - slot->pixelPositionTop,
maxGlyphSizeInPixels, maxGlyphSizeInPixels,
GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 0);

// bind pixel buffer object to update pixel values
glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pixelBufferObjectID);
}

glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);


And this is the information on drivers and extensions from one failing computer:


OpenGL GL_VENDOR ATI Technologies Inc.
OpenGL GL_RENDERER ATI Mobility Radeon HD 4650
OpenGL GL_VERSION 2.1.8306 Release
OpenGL GL_EXTENSIONS
GL_AMDX_vertex_shader_tessellator
GL_AMD_performance_monitor
GL_AMD_texture_texture4
GL_ARB_color_buffer_float
GL_ARB_depth_buffer_float
GL_ARB_depth_texture
GL_ARB_draw_buffers
GL_ARB_draw_instanced
GL_ARB_fragment_program
GL_ARB_fragment_program_shadow
GL_ARB_fragment_shader
GL_ARB_half_float_pixel
GL_ARB_half_float_vertex
GL_ARB_instanced_arrays
GL_ARB_multisample
GL_ARB_multitexture
GL_ARB_occlusion_query
GL_ARB_pixel_buffer_object
GL_ARB_point_parameters
GL_ARB_point_sprite
GL_ARB_shader_objects
GL_ARB_shader_texture_lod
GL_ARB_shading_language_100
GL_ARB_shadow
GL_ARB_shadow_ambient
GL_ARB_texture_border_clamp
GL_ARB_texture_compression
GL_ARB_texture_cube_map
GL_ARB_texture_env_add
GL_ARB_texture_env_combine
GL_ARB_texture_env_crossbar
GL_ARB_texture_env_dot3
GL_ARB_texture_float
GL_ARB_texture_mirrored_repeat
GL_ARB_texture_non_power_of_two
GL_ARB_texture_rectangle
GL_ARB_transpose_matrix
GL_ARB_vertex_buffer_object
GL_ARB_vertex_program
GL_ARB_vertex_shader
GL_ARB_window_pos
GL_ATI_draw_buffers
GL_ATI_envmap_bumpmap
GL_ATI_fragment_shader
GL_ATI_meminfo
GL_ATI_separate_stencil
GL_ATI_texture_compression_3dc
GL_ATI_texture_env_combine3
GL_ATI_texture_float
GL_EXT_abgr
GL_EXT_bgra
GL_EXT_blend_color
GL_EXT_blend_equation_separate
GL_EXT_blend_func_separate
GL_EXT_blend_minmax
GL_EXT_blend_subtract
GL_EXT_compiled_vertex_array
GL_EXT_copy_texture
GL_EXT_draw_buffers2
GL_EXT_draw_range_elements
GL_EXT_fog_coord
GL_EXT_framebuffer_blit
GL_EXT_framebuffer_multisample
GL_EXT_framebuffer_object
GL_EXT_framebuffer_sRGB
GL_EXT_gpu_program_parameters
GL_EXT_gpu_shader4
GL_EXT_multi_draw_arrays
GL_EXT_packed_depth_stencil
GL_EXT_packed_float
GL_EXT_packed_pixels
GL_EXT_point_parameters
GL_EXT_rescale_normal
GL_EXT_secondary_color
GL_EXT_separate_specular_color
GL_EXT_shadow_funcs
GL_EXT_stencil_wrap
GL_EXT_subtexture
GL_EXT_texgen_reflection
GL_EXT_texture3D
GL_EXT_texture_compression_latc
GL_EXT_texture_compression_rgtc
GL_EXT_texture_compression_s3tc
GL_EXT_texture_cube_map
GL_EXT_texture_edge_clamp
GL_EXT_texture_env_add
GL_EXT_texture_env_combine
GL_EXT_texture_env_dot3
GL_EXT_texture_filter_anisotropic
GL_EXT_texture_lod_bias
GL_EXT_texture_mirror_clamp
GL_EXT_texture_object
GL_EXT_texture_rectangle
GL_EXT_texture_sRGB
GL_EXT_texture_shared_exponent
GL_EXT_transform_feedback
GL_EXT_vertex_array
GL_KTX_buffer_region
GL_NV_blend_square
GL_NV_texgen_reflection
GL_SGIS_generate_mipmap
GL_SGIS_texture_edge_clamp
GL_SGIS_texture_lod
GL_WIN_swap_hint
WGL_EXT_swap_control

Share this post


Link to post
Share on other sites
I'm still wondering what went wrong here, but I fixed this by working around it: instead of updating part of the texture, I now keep the entire texture in normal memory and whenever I change something in it, I delete the texture from video memory and reload it from memory. Not very good for performance, but since this is not done a lot, it isn't noticeable in practice.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this