🔒 Locked
multiple textures = one texture
Advertisement
Original Post
I've tried glTexSubImage2D() several times and I cannot get it to do what I want. I've been told before that glTexSubImage2D() actually does not do this, but from the documentation it would appear as though it does. Maybe I was just using the function wrong. I googled texture atlas and found out what it is, but I didn't see anything on how to implement one.
Let me make sure that I'm using glTexSubImage2D() correctly before I rule it out.
I'd create the textures that I want to put into one texture, create a texture big enough to fit all of those textures, bind the big texture, then call glTexSubImage2D(GL_TEXTURE_2D, ___texture_I_want_to_put_into_big_texture____, xOffset, yOffset, width, height , GL_RGBA, GL_UNSIGNED_BYTE, ___pixels_of_texture_I_want_to_put_into_big_texture____);, right?
Let me make sure that I'm using glTexSubImage2D() correctly before I rule it out.
I'd create the textures that I want to put into one texture, create a texture big enough to fit all of those textures, bind the big texture, then call glTexSubImage2D(GL_TEXTURE_2D, ___texture_I_want_to_put_into_big_texture____, xOffset, yOffset, width, height , GL_RGBA, GL_UNSIGNED_BYTE, ___pixels_of_texture_I_want_to_put_into_big_texture____);, right?
Quote:
Original post by yahn
Let me make sure that I'm using glTexSubImage2D() correctly before I rule it out.
I'd create the textures that I want to put into one texture, create a texture big enough to fit all of those textures, bind the big texture, then call glTexSubImage2D(GL_TEXTURE_2D, ___texture_I_want_to_put_into_big_texture____, xOffset, yOffset, width, height , GL_RGBA, GL_UNSIGNED_BYTE, ___pixels_of_texture_I_want_to_put_into_big_texture____);, right?
Second parameter is which mipmap level of the big texture you want to update. If your texture doesn't have mipmaps, this parameter must be zero (the base level texture, which is the only one present if you're not using mipmaps). I'm not sure what you mean you pass into it, but it does look suspicious.
I don't see what I am doing. I can render it fine when I render each glyph individually, but when I try:
on each glyph it doesn't work. ox and oy are the x and y offsets. f->glyph->bitmap.width is the width, f->gly->bitmap.rows is the height, and f->glyph->bitmap.buffer is the pixel data. When I render the texture that is bound, nothing happens.
[Edited by - yahn on February 27, 2008 2:32:34 PM]
glTexSubImage2D(GL_TEXTURE_2D, 0, ox, oy, f->glyph->bitmap.width, f->glyph->bitmap.rows, GL_RGBA, GL_UNSIGNED_BYTE, f->glyph->bitmap.buffer);on each glyph it doesn't work. ox and oy are the x and y offsets. f->glyph->bitmap.width is the width, f->gly->bitmap.rows is the height, and f->glyph->bitmap.buffer is the pixel data. When I render the texture that is bound, nothing happens.
[Edited by - yahn on February 27, 2008 2:32:34 PM]
What do you mean by "nothing happens"? Does the textured primitive appear without texture, or does it not appear at all? If it doesn't appear at all, then there are other things that just the texturing that is wrong. Post some relevant code.
Unless your many small textures are generated programmatically, I'd recommend that you use an offline tool to put the many small textures into one, rather than copying them together by hand using glTexSubImage2D.
Not only does this save you an awful lot of startup time (and coding work), but it also allows you to properly generate mip levels (this is *not* as simple as scaling everything down).
nVidia offers a commandline tool for texture atlasses. If you mostly want to pack characters for displaying text, BMFont (from the Angelcode site) is quite nice.
Not only does this save you an awful lot of startup time (and coding work), but it also allows you to properly generate mip levels (this is *not* as simple as scaling everything down).
nVidia offers a commandline tool for texture atlasses. If you mostly want to pack characters for displaying text, BMFont (from the Angelcode site) is quite nice.
By nothing happens, I mean when I render the texture nothing is showing up. I figure I probably have something wrong in there, but shouldn't SOMETHING show up?
Basically I set the string member of the String class equal to the static string I want to render. I go through the loop to create a glyph for each character, which works, because when I uncomment the tex->render() at the end, everything works fine. I just don't want to build the glyphs constantly when I don't need to. If anything else needs clarified, I will, but there isn't much code to clarify.
Can anyone help me? I've been stuck on this for a while. Thank you.
[Edited by - yahn on February 27, 2008 2:54:30 PM]
int String::render_glyph(char c, Texture *tex, int ox, int oy){ if (face == NULL) { return -1; } FT_Face f = *face; FT_UInt glyph_index = FT_Get_Char_Index(f, c); FT_UInt error = FT_Load_Glyph(f, glyph_index, FT_LOAD_DEFAULT); if (error) { return -1; } error = FT_Render_Glyph(f->glyph, FT_RENDER_MODE_NORMAL); if (error) { return -1; } int width = power2(f->glyph->bitmap.width); int height = power2(f->glyph->bitmap.rows); GLubyte *pad = new GLubyte[2*width*height]; int h = 0, w = 0; while (h < height) { while (w < width) { pad[2*(w + h*width)] = pad[2*(w + h*width) + 1] = (w >= f->glyph->bitmap.width || h >= f->glyph->bitmap.rows) ? 0 : f->glyph->bitmap.buffer[w + f->glyph->bitmap.width*h]; w++; } w = 0; h++; } tex->width = width; tex->height = height; tex->load(pad, GL_RGBA, GL_LUMINANCE_ALPHA); delete [] pad; glTranslatef(f->glyph->bitmap_left, 0, 0); glTranslatef(0, -f->glyph->bitmap_top, 0); float x = (float)f->glyph->bitmap.width/(float)width; float y = (float)f->glyph->bitmap.rows/(float)height; //tex->render(ox + x + f->glyph->bitmap_left, oy + y + 16); glTexSubImage2D(GL_TEXTURE_2D, 0, ox, oy, f->glyph->bitmap.width, f->glyph->bitmap.rows, GL_RGBA, GL_UNSIGNED_BYTE, f->glyph->bitmap.buffer); return f->glyph->advance.x >> 6;}bool String::build(){ int i = 0; int l = string.length(); int o = 0; std::vector<Texture *> textures; glBindTexture(GL_TEXTURE_2D, texture->texture); for (i < 0; i < l; i++) { Texture *tex = new Texture; textures.push_back(tex); o += render_glyph(string, tex, o, 0); if (o == -1) { int s = textures.size(); int j = 0; while (j < s) { delete textures[j]; j++; } return false; } } l = textures.size(); for (i < 0; i < l; i++) { delete textures; i++; } built = true; return true;}Basically I set the string member of the String class equal to the static string I want to render. I go through the loop to create a glyph for each character, which works, because when I uncomment the tex->render() at the end, everything works fine. I just don't want to build the glyphs constantly when I don't need to. If anything else needs clarified, I will, but there isn't much code to clarify.
Can anyone help me? I've been stuck on this for a while. Thank you.
[Edited by - yahn on February 27, 2008 2:54:30 PM]
I'll simplify that code a lot in hopes that someone can tell me what I'm doing wrong. I know that the problem is with how I'm using glTexSubImage2D(), but I just cannot get it right.
I want to use freetype to render glyphs and then put them inside one texture to make a string. The pixel data from each of those images is stored in a variable called pad. So, in a pseudo code can someone tell me what I want to do?
I think it is:
I know that has a memory leak, but I'm trying to keep it as simple as possible.
That seems like it should be right, but it's just rendering a white rectangle as if nothing is in pad, but there is because when I render pad with glTexImage2D() it works.
I want to use freetype to render glyphs and then put them inside one texture to make a string. The pixel data from each of those images is stored in a variable called pad. So, in a pseudo code can someone tell me what I want to do?
I think it is:
String string = "Hello, World!";glBindTexture(GL_TEXTURE_2D, texture); // texture being the texture for the stringfor (i = 0; i < string.length(); i++){ char *pad = render_glyph(string); glTexSubImage2D(GL_TEXTURE_2D, 0, xOffSet, yOffSet, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pad);}I know that has a memory leak, but I'm trying to keep it as simple as possible.
That seems like it should be right, but it's just rendering a white rectangle as if nothing is in pad, but there is because when I render pad with glTexImage2D() it works.
The initial call to glTexImage() is similar to calling malloc in C or new in C++. It performs allocation of the memory for the texture, that was bound previously by calling glBindTexture().
Later on you can call glTexSubImage() to modify part or all of that texture. The size of the texture will not change by doing this, only its contents.
Consider for instance the case where your glyphs are of size 32x32 pixels each. If you allocated a texture with a size of 256x256 pixels by calling glTexImage(), then you can store 8x8=64 of those glyphs in that texture later on by calling glTexSubImage() for each glyph.
Later on you can call glTexSubImage() to modify part or all of that texture. The size of the texture will not change by doing this, only its contents.
Consider for instance the case where your glyphs are of size 32x32 pixels each. If you allocated a texture with a size of 256x256 pixels by calling glTexImage(), then you can store 8x8=64 of those glyphs in that texture later on by calling glTexSubImage() for each glyph.
You mean glTexImage2D(), right? I don't see a function called glTexImage(). I changed the process to this:
It is still drawing a white rectangle to the screen.
String string = "Hello, World!";glBindTexture(GL_TEXTURE_2D, texture); // texture being the texture for the stringglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL);for (i = 0; i < string.length(); i++){ char *pad = render_glyph(string); glTexSubImage2D(GL_TEXTURE_2D, 0, xOffSet, yOffSet, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pad);}It is still drawing a white rectangle to the screen.
When allocating textures never forget to call glTexParameter(), for instance like this:
Also look into this tutorial:
http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=06
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);Also look into this tutorial:
http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=06
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement