0
votes

I've recently been learning wxWidgets (version 2.9.4) and have been having trouble getting textures to work correctly in an OpenGL window (glColor4f works fine however).

I've tried following the tutorials from wxWidget including loading textures from a wxImage. I also tried using stbi_image to load in the texture but no matter what I do the textures always remain white. Here's the code I'm using:

wxImage* img = new wxImage(wxT("grass.png"));

GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

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

GLubyte *bitmapData=img->GetData();
GLubyte *alphaData=img->GetAlpha();

int bytesPerPixel = img->HasAlpha() ?  4 : 3;
int imageWidth = img->GetWidth();
int imageHeight = img->GetHeight();

int imageSize = imageWidth * imageHeight * bytesPerPixel;
GLubyte *imageData=new GLubyte[imageSize];

int rev_val=imageHeight-1;

for(int y=0; y<imageHeight; y++)
{
    for(int x=0; x<imageWidth; x++)
    {
        imageData[(x+y*imageWidth)*bytesPerPixel+0]=
                bitmapData[( x+(rev_val-y)*imageWidth)*3];

        imageData[(x+y*imageWidth)*bytesPerPixel+1]=
                bitmapData[( x+(rev_val-y)*imageWidth)*3 + 1];

        imageData[(x+y*imageWidth)*bytesPerPixel+2]=
                bitmapData[( x+(rev_val-y)*imageWidth)*3 + 2];

        if(bytesPerPixel==4) imageData[(x+y*imageWidth)*bytesPerPixel+3]=
                alphaData[ x+(rev_val-y)*imageWidth ];
    }
}

glTexImage2D(GL_TEXTURE_2D,
                0,
                bytesPerPixel,
                imageWidth,
                imageHeight,
                0,
                img->HasAlpha() ?  GL_RGBA : GL_RGB,
                GL_UNSIGNED_BYTE,
                imageData);

delete[] imageData;
wxDELETE(img);

return texture;

Here's the arguments I use in my canvas class:

int args[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_DEPTH_SIZE, 16, 0 };

I've googled the problem and noticed other people are having it too, but there doesn't seem to be any real solution that I can find other than switching to wxWidgets 2.8, which doesn't build properly in VS2010 (what I use).

I can provide other code if needed, I'm not really sure what the root of this problem is.

2
Do you have a current GL context when you run the texture loading code?genpfault
Yes, I call context = new wxGLContext(this); in the constructor and I have wxGLCanvas::SetCurrent(*context); in my render loop. However I tried moving that to straight under the context = new wxGLContext(this); line. I got a texture from this but the debugger threw the error assert "IsShownOnScreen()" failedsler
What is the problem exactly? "Having trouble getting it to work" is really not precise enough.VZ.
Textures are all white, sorry for not making it clear enough.sler
glEnable(GL_TEXTURE_2D);?Bartek Banachewicz

2 Answers

1
votes

I usually do something along these lines:

// define a specialisation of wxGLCanvas

class cMyCanvas: public wxGLCanvas
{
 ...

// in frame constructor, call canvas constructor

cMyCanvas * myCanvas = new cMyCanvas( this );

// show the frame

Show();

// set context current

myCanvas->SetCurrent( context );

// initialize canvas

myCanvas-> initGL();
0
votes

Well I managed to find the source of the problem, however I can't really find a clean solution to it. Turns out I had to call wxGLCanvas::SetCurrent(*context); before attempting to load any textures, but wxGLCanvas::SetCurrent(*context); can only be called when the window is shown (i.e. not in the constructor, where I was loading my textures). So my solution so far is this:

static bool initialInit = false;
if(!initialInit) {
    wxGLCanvas::SetCurrent(*context);
    initGL();
    initialInit = true;
}

which is called in my render loop, initGL() does all the GL setup and loads the textures I need. This works correctly but seems like a horrible solution.