我最近刚拿起Qt并将其与OpenGL一起使用
但是,问题是,将我的SDL代码移至Qt并更改纹理代码以使用QImage时,它将停止工作。
该图像确实正确加载,如通过错误检查代码所示。
谢谢!
附注:请不要建议我使用glDrawPixels,我需要解决当前的问题。原因之一是1.速度慢2. android(此代码最终可能会在其上运行)是OpenGL ES,不支持glDrawPixels
这是代码:
//original image
QImage img;
if(!img.load(":/star.png"))
{
//loads correctly
qWarning("ERROR LOADING IMAGE");
}
//array for holding texture ID
GLuint texture[1];
//get the OpenGL-friendly image
QImage GL_formatted_image;
GL_formatted_image = QGLWidget::convertToGLFormat(img);
//make sure its not null
if(GL_formatted_image.isNull())
qWarning("IMAGE IS NULL");
else
qWarning("IMAGE NOT NULL");
//generate the texture name
glGenTextures(1, texture);
//bind the texture ID
glBindTexture(GL_TEXTURE_2D, texture[0]);
//generate the texture
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, GL_formatted_image.width(),
GL_formatted_image.height(),
0, GL_RGBA, GL_UNSIGNED_BYTE, GL_formatted_image.bits() );
//texture parameters
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//draw the texture
glPushMatrix();
glTranslatef(-2.0f, 0.0f, 0.0f);
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_TRIANGLES);
glVertex2f(1.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(0.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex2f(0.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glEnd();
glPopMatrix();
这是SDL的原始纹理加载功能:
GLuint loadTexturewithSDL(const char* FILE, GLenum texture_format)
{
GLuint texture; // This is a handle to our texture object
SDL_Surface *surface; // This surface will tell us the details of the image
GLint nOfColors;
if ( (surface = SDL_LoadBMP(FILE)) ) {
// Check that the image's width is a power of 2
if ( (surface->w & (surface->w - 1)) != 0 ) {
printf("warning: image's width is not a power of 2\n");
}
// Also check if the height is a power of 2
if ( (surface->h & (surface->h - 1)) != 0 ) {
printf("warning: image's height is not a power of 2\n");
}
// get the number of channels in the SDL surface
nOfColors = surface->format->BytesPerPixel;
if (nOfColors == 4) // contains an alpha channel
{
if (surface->format->Rmask == 0x000000ff)
texture_format = GL_RGBA;
else
texture_format = GL_BGRA;
} else if (nOfColors == 3) // no alpha channel
{
if (surface->format->Rmask == 0x000000ff)
texture_format = GL_RGB;
else
texture_format = GL_BGR;
} else {
printf("warning: the image is not truecolor.. this will probably break\n");
// this error should not go unhandled
}
// Have OpenGL generate a texture object handle for us
glGenTextures( 1, &texture );
// Bind the texture object
glBindTexture( GL_TEXTURE_2D, texture );
// Set the texture's stretching properties
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
// Edit the texture object's image data using the information SDL_Surface gives us
glTexImage2D( GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0,
texture_format, GL_UNSIGNED_BYTE, surface->pixels );
}
else {
printf("SDL could not load image %s\n", SDL_GetError());
SDL_Quit();
return 1;
}
// Free the SDL_Surface only if it was successfully created
if ( surface ) {
SDL_FreeSurface( surface );
}
return texture;
}
最佳答案
我有类似的代码可以工作,但使用glTexSubImage2D:
void Widget::paintGL()
{
glClear (GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,win.width(),0,win.height());
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,texture);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0,0 , image.width(), image.height(), glFormat, glType, image.bits() );
glBegin(GL_QUADS); // in theory triangles are better
glTexCoord2i(0,0); glVertex2i(0,win.height());
glTexCoord2i(0,1); glVertex2i(0,0);
glTexCoord2i(1,1); glVertex2i(win.width(),0);
glTexCoord2i(1,0); glVertex2i(win.width(),win.height());
glEnd();
glFlush();
}
void Widget::initializeGL()
{
glClearColor (0.0,0.0,0.0,1.0);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,win.width(),0,win.height());
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glGenTextures(3,&texture);
glBindTexture(GL_TEXTURE_2D,texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D,texture);
glTexImage2D(GL_TEXTURE_2D, 0, glFormat, image.width(), image.height(), 0, glFormat, glType, NULL );
glDisable(GL_TEXTURE_2D);
}
还有ctor void Widget::setDisplayOptions()
{
glFormat = GL_RGB; // QImage RGBA is BGRA
glType = GL_UNSIGNED_BYTE;
QGL::setPreferredPaintEngine(QPaintEngine::OpenGL2);
QGLFormat glFmt;
glFmt.setSwapInterval(1); // 1= vsync on
glFmt.setAlpha(GL_RGBA==glFormat);
glFmt.setRgba(GL_RGBA==glFormat);
glFmt.setDoubleBuffer(true); // default
glFmt.setOverlay(false);
glFmt.setSampleBuffers(false);
QGLFormat::setDefaultFormat(glFmt);
setAttribute(Qt::WA_OpaquePaintEvent,true);
setAttribute(Qt::WA_PaintOnScreen,true);
}
中的一些性能调整
关于qt - 在OpenGL中使用QImage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5335218/