• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
zaneski13

glTexSubImage2D not working with GL_RGB or GL_LUMINANCE textures [SOLVED]

7 posts in this topic

Ok, so I'm having a problem with the glTexSubImage2D function. The function only works with GL_RGBA textures, but when I use GL_RGB or GL_LUMINANCE textures, glTexSubImage2D acts funny.

I've created a class called TextureEditable
Bellow are the 2 functions I made. SetData, and SetSubData(). formatType can be TEX_RGB, TEX_RGBA, or TEX_ALPHA

[CODE]
bool TextureEditable::SetData(int width_, int height_, unsigned char *pixels, int formatType)
{
if ( !math::IsPower2(width_) || !math::IsPower2(height_) )
return false;
if ( !pixels )
return false;
if ( formatType != TEX_RGB && formatType != TEX_RGBA && formatType != TEX_ALPHA )
return false;
//ok, so the data that was passed in is good, only error that can possibly happen is if the data has less elements that width*height*bpp
format = formatType;
width = width_;
height = height_;
if ( data )
delete [] data;
int bpp = 1;
if ( format == TEX_RGB )
bpp = 3;
else if ( format == TEX_RGBA )
bpp = 4;
cout << "bpp = " << bpp << endl;
data = new unsigned char[width*height*bpp];

for ( int i=0; i < width*height*bpp; i++ )
data[i] = pixels[i];
//now we have the data
if ( texID == 0 ) //then we haven't generated a gl texture yet, so generate one
{
Texture::EnableGLTextures();
glGenTextures(1, &texID);
glBindTexture(GL_TEXTURE_2D, texID);
Texture::lastBoundTexture = texID;
cout << "creating tex " << texID << endl;
}
Texture::EnableGLTextures();
glBindTexture(GL_TEXTURE_2D, texID);
Texture::lastBoundTexture = texID;
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
if ( format == TEX_RGB )
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
}
else if ( format == TEX_RGBA )
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
}
else if ( format == TEX_ALPHA )
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE , GL_UNSIGNED_BYTE, data);
}



return true;
}
bool TextureEditable::SetSubData(int x, int y, int w, int h, unsigned char *pixels)
{
if ( !pixels )
return false;
if ( x < 0 || x >= width || y < 0 || y >= height )
return false;

Texture::EnableGLTextures();
glBindTexture(GL_TEXTURE_2D, texID);
Texture::lastBoundTexture = texID;
if (format == TEX_RGBA )
{
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
}
else if ( format == TEX_RGB )
{
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGB, GL_UNSIGNED_BYTE, pixels);
}
else if ( format == TEX_ALPHA )
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels);

}
[/CODE]



OK, so those are the main functions I'm working with in that class.

in my main program I do this...

[CODE]
tex2 = new TextureEditable("");

unsigned char pixels[4*4] = {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100};
tex2->SetData(4,4,pixels,TEX_ALPHA);

unsigned char sub[2*2] = {255,255,255,255};
tex2->SetSubData(1,1,2,2,sub);
[/CODE]


I render a quad with the texture mapped on it. What I should see is a grey square with a white square in the middle
Instead I see a grey square with a square in the middle that is shaded white in the first 2 texels and shaded different shades of grey for the other 2 texels

Note, the desired effect works when I use a texture that has GL_RGBA data. I think whats happening is when I call glTexSubImage2D its taking the pixel data i send it assumes its a RGBA texture when its a greyscale texture. But I'm not sure. Any help would be greatly appreciated.
0

Share this post


Link to post
Share on other sites
Your code looks correct on the first view, your problem might be somewhere else.
You could try this code: [url="http://nehe.gamedev.net/tutorial/texture_mapping/12038/"]http://nehe.gamedev...._mapping/12038/[/url] and compare it step by step to yours to see where the problem is.

the_visualist
0

Share this post


Link to post
Share on other sites
Look up glPixelStore and GL_UNPACK_ALIGNMENT. The parameter determines the byte alignment of each row of image data, and thus how much passing is present in the source data. The default value if 4, which means that each row of the image must start on a byte-offset that is a multiple of 4. Your luminance sub-image does not obey that alignment, since the second row is only two bytes away from the start address, so OpenGL skips two bytes before starting to read the second row, and at that time you are outside the sub-image data. Either pad the image data to meed the alignment requirement, or set the alignment to 1 byte to imply no padding.
1

Share this post


Link to post
Share on other sites
Thanks, that sounds like the function I should be using. Just a question. I checked the reference guide for glPixelStore and the parameter [b]GL_UNPACK_ALIGNMENT, and appariently the only valid values you can pass to the function is 1,2,4, or 8. According to [/b][url="http://www.talisman.org/opengl-1.1/Reference/glPixelStore.html"]http://www.talisman.org/opengl-1.1/Reference/glPixelStore.html[/url]

So when the pixel data I'm passing to the texture is GL_LUMIANCE I'd call glPixelStore([b]GL_UNPACK_ALIGNMENT, 1); before calling glTexSubImage2D()[/b]
[b]But, when the pixel data I'm passing to the texture is GL_RGB I'd call glPixelStore([/b][b]GL_UNPACK_ALIGNMENT, 3) before calling glTexSubImage2D() but '3' isn't a valid value to pass to [/b]glPixelStore([b]GL_UNPACK_ALIGNMENT, n); According to the link above, only 1,2,4, and 8 are valid values. 1 being (L,L,L,1) 2 being (L,L,L,A) ??? 4 being (R,G,B,A) 8 being (R,G,B,A,ummmmmmmmmm idk)[/b]
0

Share this post


Link to post
Share on other sites
Heres what I have for code at the moment

[CODE]
bool TextureEditable::SetSubData(int x, int y, int w, int h, unsigned char *pixels)
{
if ( !pixels )
return false;
if ( x < 0 || x >= width || y < 0 || y >= height )
return false;


Texture::EnableGLTextures();
glBindTexture(GL_TEXTURE_2D, texID);
Texture::lastBoundTexture = texID;
if (format == TEX_RGBA )
{
glPixelStorei( GL_UNPACK_ALIGNMENT, 4);
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
}
else if ( format == TEX_RGB )
{
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGB, GL_UNSIGNED_BYTE, pixels);
}
else if ( format == TEX_ALPHA )
{
glPixelStorei( GL_UNPACK_ALIGNMENT, 1);
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_LUMINANCE, GL_UNSIGNED_BYTE, &pixels[0]);
}

}
[/CODE]

Right now TEX_RGBA and TEX_ALPHA formats are working. idk what to do about TEX_RGB since '3' isnt a valid value to pass to glPixelStore
0

Share this post


Link to post
Share on other sites
The byte alignment has nothing to do with how many color components you have. All it means is that each row of the image must start on an address that is a multiple of the alignment.

Consider a 5 pixel wide RGB image with one byte per channel; each row of the image is then 15 bytes. So where does the second row of pixels start? Is it 15 bytes from the start of the first row? The default alignment is 4, which means that OpenGL assumes that each row starts on an offset that that is a multiple of 4 bytes from the previous row. Thus, in the example, the 15-byte row has to be padded with an empty byte before the next one starts. If there is no padding, OpenGL won't read the image correctly, since the image doesn't contain any padding but OpenGL assumes it does. That is, rows are not necessarily stored tightly packed in memory.

Consider instead that you have a 5 pixel wide luminance image. Each row is now 5 bytes, which still isn't a multiple of 4. The next multiple of 4 is 8, so there must be 3 bytes of padding at the end of each row before the next row starts.

Consider an RGBA image this time; each row is now 20 bytes, which [i]is[/i] a multiple of 4. No padding is necessary for this image, since each row is already a multiple of 4 bytes long.

It has nothing to do with what format you use, but how long each row is in bytes. The byte-length of each row must be a multiple of the alignment, or you have to insert padding after each row to ensure that the alignment is fulfilled.
1

Share this post


Link to post
Share on other sites
If you have strict non-padded data, then just set the alignment to 1 and don't bother with it anymore. Every image is on a 1-byte alignment, so there won't be any problems, at least no read to the image properly.
1

Share this post


Link to post
Share on other sites
Thanks for clarifying! [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]
I can move onto my editor now
0

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  
Followers 0