OpenGL: Texture Mapping

Started by
3 comments, last by Brother Bob 19 years, 3 months ago
im new to opengl so please bare with me... i cant seem to get texture mapping to work... i have an image->water128x128.bmp 256 colours i get pixel data like this... void* GetImageData(HINSTANCE hInst) { HBITMAP hbmp; BITMAP bmp; // gets handle to bitmap... hbmp = LoadBitmap(hInst,MAKEINTRESOURCE(water)); // gets bitmap info... GetObject(hbmp,sizeof(BITMAP),&bmp); return bmp.bmBits; } then i render a basic quad like so... void Render() { unsigned int TexObj; void *pImageData; // enables 2d texture mapping... glEnable(GL_TEXTURE_2D); // call the above function... pImageData =GetImageData((HINSTANCE)GetWindowLong(WindowFromDC(hdc),GWL_HINSTANCE)); // generates and binds ("unused") texture object... glGenTextures(1,&TexObj); glBindTexture(1,TexObj); // sets texture params... glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_NEAREST); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); glTexImage2D(GL_TEXTURE_2D,1,GL_RGB8,128,128,1,GL_RGB,GL_BYTE,pImageData); // render quad and sets coords... glBegin(GL_QUADS); glTexCoord2f(0,1); glVertex3f(-0.5,0.5f,0); glTexCoord2f(0,0); glVertex3f(-0.5f,-0.5f,0); glTexCoord2f(1,0); glVertex3f(0.5f,-0.5f,0); glTexCoord2f(1,1); glVertex3f(0.5f,0.5f,0); glEnd(); // displays image... SwapBuffers(hdc); // release texobj glDeleteTextures(1,&TexObj); // disable state... glDisable(GL_TEXTURE_2D); return; } i call render before the win32 message loop(nothing fancy->GetMessage() stylee)... all i get is a white rectangle... p.s. is it better to enable a state,do something and disable state when the function has finished or would it be better to enable,do something,disable when the application is closing down..? thank you for your time... happy coding...;)
Advertisement
My only real input here (i dont know the whole hbmp thing) is too check that your textures are multiples of 2 (i think). Best have a texture of 128x128.

As for the PS, its up too you. Personally i set commonly used states such as GL_TEXTURE_2D to active at the start of pogram, and disable them when i need to. But states like GL_BLEND, GL_FOG, etc, i activate only when i need them.

I dont think this is the best method, im only a hobby programmer.
------------ "Here lies a toppled God,His fall was not a small one,We but built his pedastle,A narrow, and a tall one" Frank Herbert (Dune:Messiah)
It's been a while since I touched any OGL :o) I don't know that it's the only problem, but I'm pretty sure this:

glBindTexture(1,TexObj);


should be this:

glBindTexture(GL_TEXTURE_2D,TexObj);


and you'd get a GL_INVALID_ENUM error code from that.


On the subject of setting render states:

It's something of a tradeoff between performance, maintenance cost and development time. Setting states can take quite a while (relatively speaking), so performance-wise it's best to put render calls for different things together in batches to minimise the need to change render states. That requires some development time to design and implement, though, and it can be harder to debug as you're no longer rendering things in submission order: rendering is deferred. Alternatively, resetting state to how it was when you entered a function when you exit that function is more predictable and allows submission-ordered rendering more simply (if that's what you want), but it's a bit less efficient and requires that you write the code to do it whenever you render something. You can design your code to make that easy, though.
Harry.
I just re-read your states question and I think it's probably not quite the question I was answering :o) By all means set the states you're interested in to your own default values on startup. If you're going to depend on that default value in some systems, then when you want to change the state for some purpose you'll have to remember to change it back afterwards. In general I would favour setting states (particularly those that aren't changing much) at as broad a scope as possible.
Harry.
You should never load the texture data in the render function like that. Load the texture once on startup, and bind the texture each time you want to use is. Although technically it will work, you shouldn't do it.

The problem with texturing you're having (apart from what HarryW said) is that your texture object is incomplete. You tell OpenGL you want a mipmap minification filter, which require a complete mipmap set. You're only uploading a single mipmap level, but all mipmap level down to 1x1 must be supplied or the texture object is invalid. Also, you're uploading the second mipmap level with your call to glTexImage2D (second parameter, 0 is the base mipmap level), so your texture is missing the base level aswell, not only the lower mipmap levels.

First of all you must at least supply the base level, and if you want mipmapping, you should supply a complete mipmap set. Do this by either using gluBuild2DMipmaps instead of glTexImage2D, or enable automatic mipmap generation (check out this). If you don't need mipmapping, just supply the base level and set minification filter to GL_LINEAR or GL_NEAREST.

I strongly suggest you read up a bit on texturing. Try here.

This topic is closed to new replies.

Advertisement