【问题标题】:wxWidgets OpenGL textureswxWidgets OpenGL 纹理
【发布时间】:2012-12-17 11:13:40
【问题描述】:

我最近一直在学习 wxWidgets(2.9.4 版),但在让纹理在 OpenGL 窗口中正常工作时遇到了问题(但 glColor4f 工作正常)。

我尝试按照 wxWidget 的教程进行操作,包括从 wxImage 加载纹理。我还尝试使用 stbi_image 加载纹理,但无论我做什么,纹理始终保持白色。这是我正在使用的代码:

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;

这是我在画布类中使用的参数:

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

我用谷歌搜索了这个问题并注意到其他人也有这个问题,但除了切换到 wxWidgets 2.8 之外,我似乎找不到任何真正的解决方案,它在 VS2010 中无法正确构建(什么我用)。

如果需要,我可以提供其他代码,我不确定这个问题的根源是什么。

【问题讨论】:

  • 运行纹理加载代码时是否有当前的 GL 上下文?
  • 是的,我调用 context = new wxGLContext(this);在构造函数中,我有 wxGLCanvas::SetCurrent(*context);在我的渲染循环中。但是我尝试将其直接移动到 context = new wxGLContext(this);线。我从中得到了一个纹理,但调试器抛出了错误断言“IsShownOnScreen()”失败
  • 到底是什么问题? “无法正常工作”确实不够准确。
  • 纹理都是白色的,抱歉不够清楚。
  • glEnable(GL_TEXTURE_2D);?

标签: opengl wxwidgets textures


【解决方案1】:

我通常会这样做:

// 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();

【讨论】:

  • 这仍然给我一个“IsShownOnScreen()”断言失败。除非在创建框架后调用 SetCurrent,否则我似乎无法摆脱它。
  • 创建,你的意思是构造,还是展示?我期待显示。所以你首先要显示框架。我会将其添加到答案中的代码中。
  • 我的意思是构造,但这适用于 Show();包括的方法。感谢您的帮助:)
【解决方案2】:

好吧,我设法找到了问题的根源,但是我真的找不到一个干净的解决方案。原来我不得不调用 wxGLCanvas::SetCurrent(*context);在尝试加载任何纹理之前,但 wxGLCanvas::SetCurrent(*context);只能在显示窗口时调用(即不在我正在加载纹理的构造函数中)。所以到目前为止我的解决方案是这样的:

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

在我的渲染循环中调用,initGL() 完成所有 GL 设置并加载我需要的纹理。这可以正常工作,但似乎是一个可怕的解决方案。

【讨论】:

    猜你喜欢
    • 2011-05-19
    • 1970-01-01
    • 2023-04-01
    • 2010-09-17
    • 2018-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多