我有一个纹理问题——它正确地加载了图像,但将垃圾渲染到几何体上。几何体本身画得很好(一个简单的三角形),但无论我加载哪种纹理,它都会将随机图案喷到三角形上。
我在带有 Qt 4.7 和 OpenGL 的 Mac OS X 上使用 g++ 4.2.1
首先,这是控制台输出:
BallGLWidget::initializeGL called
Image format is GL_RGB
Checking textures...
glGetError enum value: GL_NO_ERROR
此外,我用于着色器初始化的日志记录代码没有记录任何错误。
OpenGL初始化函数:
void BallGLWidget::initializeGL()
{
cout << "BallGLWidget::initializeGL called" << endl;
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
initializeShaders();
checkOpenGLError();
glEnableVertexAttribArray(VERTEX_POS_NUM);
glEnableVertexAttribArray(TEX_POS_NUM);
glBindAttribLocation(programHandle, VERTEX_POS_NUM, VERTEX_POS_ATTRIB_NAME);
glBindAttribLocation(programHandle, TEX_POS_NUM, TEX_COORD_ATTRIB_NAME);
//this MUST be called AFTER glBindAttribLocation
glLinkProgram(programHandle);
//FIXME:-----------DEBUG-----------
printProgramInfoLog(programHandle);
//-----------END-DEBUG-----------
glUseProgram(programHandle);
//FIXME:-----------DEBUG-----------
printProgramInfoLog(programHandle);
//-----------END-DEBUG-----------
checkOpenGLError();
samplerUniformLocation =
glGetUniformLocation(programHandle, BALL_SAMPLER_NAME);
glUniform1f(samplerUniformLocation, 0);
glActiveTexture(GL_TEXTURE0);
ball_texture_handle = loadTexture(BALL_IMAGE_PATH);
//bind it in initialization because we're only using
//1 texture in the program
glBindTexture(GL_TEXTURE_2D, ball_texture_handle);
}
这是 loadTexture 函数:
GLuint BallGLWidget::loadTexture(const char* filenamePtr)
{
//create & prepare a temporary texture handle that will be copied to
//DesktopMain::ball_texture_handle after this function returns
GLuint texHandle;
glGenTextures(1, &texHandle);
glBindTexture(GL_TEXTURE_2D, texHandle);
QImage* img = new QImage();
if(!img->load(filenamePtr))
{
//error loading image, handle error
cerr << "ERROR LOADING TEXTURE" << endl;
}
//This is the Qt way- its commented out for conventional OpenGL code
//bind the texture to the current context
//GLuint texHandle = bindTexture(*img);
GLenum openglImageFormat;
QImage::Format imgFormat = img->format();
switch(imgFormat)
{
case QImage::Format_RGB32:
openglImageFormat = GL_RGB;
cout << "Image format is GL_RGB" << endl;
break;
case QImage::Format_ARGB32:
openglImageFormat = GL_RGBA;
cout << "Image format is GL_RGBA" << endl;
break;
//handle this case the same as ARGB32
case QImage::Format_ARGB32_Premultiplied:
openglImageFormat = GL_RGBA;
cout << "Image format is GL_RGBA (premultiplied)" << endl;
break;
case QImage::Format_Invalid:
cerr << "ERROR: INVALID IMAGE FORMAT" << endl;
return -1;
break;
default:
cerr << "ERROR: UNRECOGNIZED IMAGE FORMT" << endl;
return -1;
break;
}
//use tightly packed pixel values
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
//use linear filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
img->width(), img->height(), 0, openglImageFormat,
GL_UNSIGNED_BYTE, img->bits());
cerr << "Checking textures..." << endl;
checkOpenGLError();
delete img;
return texHandle;
}
顶点着色器:
attribute vec2 a_v_position;
attribute vec2 a_tex_position;
varying vec2 tex_coord_output;
void main()
{
//copy attributes to varyings for use in the frag shader
tex_coord_output = a_tex_position;
gl_Position = vec4(a_v_position, 0.0, 1.0);
}
片段着色器:
varying vec2 tex_coord_output;
uniform sampler2D ballsampler;
void main()
{
gl_FragColor = texture2D(ballsampler, tex_coord_output);
}
编辑:
根据要求,该程序的屏幕截图。
https://docs.google.com/open?id=0B8xCefwW3X4TY2Y3N2M0MGYtMDQ0NS00MDk4LWEzODgtNDc3OWFkODI3ZWE3
编辑:
属性位置已关闭,因为显然 glBindAttribLocation 仅在链接程序对象之前调用才有效(http://www.opengl.org/sdk/docs/man/xhtml/glBindAttribLocation.xml)。我相应地更改了上面的代码,但程序仍然如下所示(纹理仍然存在问题......):
我得到以下结果: https://docs.google.com/open?id=0B8xCefwW3X4TNWE0YTQ5MTktZTA2Yy00YmI4LWJmMjMtYTlhOTYxMGNkMTk0