After playing around with OpenGL in Qt and reading through the code. I found two things that could be cause of your texture issues. I'm assuming you have put the content folder in the working directory of the program (You do say it definitely exists; if you're unsure you can just call QDir::currentPath() and print it out somewhere) and that you know the image has loaded correctly ( simple check with QImage::isNull() ).
1. Loading the texture when the context hasn't been set will cause the texture loading to fail. The context is automatically set when the functions paintGL(), resizeGL(), or initializeGL() are called. But if you try to load the texture else where (for example, the constructor) the gl functions calls fail. To fix the problem simply call makeCurrent() inside the relevant function body. For all I know you've already known about and rectified this issue.
Qt Doc wrote:
Your widget's OpenGL rendering context is made current when paintGL(), resizeGL(), or initializeGL() is called. If you need to call the standard OpenGL API functions from other places (e.g. in your widget's constructor or in your own paint functions), you must call makeCurrent() first.
2. Using 1 for the level parameter (2nd param) in the glTexImage2D call. I'm no openGL (or Qt) expert so I don't know if you're performing arcane trickery I don't understand. But to use the base texture you pass 0 to the level parameter. A quick read around shows you only should specify a level when you provide the mip-mapped images yourself (I have no idea how you go about this). When I used 1 for the level parameter; all I got was the glorious white quad you described. Using 0 gave a textured quad.
Here's the class I quickly wrote out to test OpenGL in Qt. I left out the main.cpp (just the standard main.cpp file for Qt projects).
Header
Code: Select all
#ifndef OPENGL_TEST_H
#define OPENGL_TEST_H
#include <QGLWidget>
#include <QImage>
class MyOpenGL : public QGLWidget {
Q_OBJECT
private:
GLuint m_textureid;
void loadTexture();
public:
MyOpenGL();
~MyOpenGL();
void initializeGL();
void resizeGL(int w, int h);
void paintGL();
};
#endif // OPENGL_TEST_H
CPP
Code: Select all
#include "opengl_test.h"
#include <QMessageBox>
#include <QDir>
MyOpenGL::MyOpenGL() {
makeCurrent(); //Set openGL context. Required for loading the texture.
loadTexture();
}
MyOpenGL::~MyOpenGL() {
}
void MyOpenGL::initializeGL() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); //Black background.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 1.0, 0.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//loadTexture(); --You can also load the texture here. No need to set the context as its automatically set.
}
void MyOpenGL::loadTexture() {
QImage img, texture;
//Load the texture
img.load("res/texture_test.png");
if(img.isNull()) {
QMessageBox::information(this,
"OpenGL Test - Failed to load image",
"Failed to load texture_test.png\nWorking Dir: " + QDir::currentPath(),
QMessageBox::Ok
);
} else {
texture = QGLWidget::convertToGLFormat(img);
//Send the texture data to openGL
glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT);
glGenTextures(1, &m_textureid);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, m_textureid);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture.width(), texture.height(), 0,
GL_RGBA, GL_UNSIGNED_BYTE, texture.bits());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glPopAttrib();
}
}
void MyOpenGL::resizeGL(int w, int h) {
glViewport(0, 0, w, h); //Set the viewport
glPushAttrib(GL_TRANSFORM_BIT); //Store current matrix mode
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 1.0, 0.0, -1.0, 1.0);
glPopAttrib(); //Restore matrix mode
}
void MyOpenGL::paintGL() {
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, m_textureid); //Bind the converted texture.
//Draw the textured quad.
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(0.1f, 0.1f, 0.0f); //Top Left
glTexCoord2f(0.0f, 0.0f); glVertex3f(0.1f, 0.9f, 0.0f); //Bottom Left
glTexCoord2f(1.0f, 0.0f); glVertex3f(0.9f, 0.9f, 0.0f); //Bottom Right
glTexCoord2f(1.0f, 1.0f); glVertex3f(0.9f, 0.1f, 0.0f); //Top Right
glEnd();
glPopAttrib(); //Restore previously bound texture and state.
}
I hope this post provides some help. If it doesn't I'm sure someone with more Qt/OpenGL experience than myself can shine some light on the issue.