我首先要为问题的长度道歉。我相信我犯了一些小的,愚蠢的错误,但由于我完全找不到它,我决定发布所有相关代码以防万一。
我终于使用QImage进行纹理加载,并且能够立即渲染纹理。 但是,顶点数组不起作用,我不知道为什么。 最明显的事情,比如“你启用了顶点数组和纹理坐标数组吗?”可能不是答案。我将发布初始化代码。
这是init函数:
/* general OpenGL initialization function */
int initGL()
{
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0, 0, 0, 1); // Black Background
glEnable ( GL_COLOR_MATERIAL );
glColorMaterial ( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
glDisable(GL_DEPTH_TEST);
//ENABLED VERTEX ARRAYS AND TEXTURE COORDINATE ARRAYS
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
//ENABLED 2D TEXTURING
glEnable ( GL_TEXTURE_2D );
glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 );
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
//seed random
srand(time(NULL));
return( TRUE );
}
我有初始化,调整大小和绘制由QGLWidget调用的函数(它本身只是一个调用实际工作函数的骨架)
纹理加载功能:
GLuint LoadGLTextures( const char * name )
{
//unformatted QImage
QImage img;
//load the image from a .qrc resource
if(!img.load(":/star.bmp"))
{
qWarning("ERROR LOADING IMAGE");
}
//an OpenGL formatted QImage
QImage GL_formatted_image;
GL_formatted_image = QGLWidget::convertToGLFormat(img);
//error check
if(GL_formatted_image.isNull())
qWarning("IMAGE IS NULL");
else
qWarning("IMAGE NOT NULL");
//texture ID
GLuint _textures[1];
//enable texturing
glEnable(GL_TEXTURE_2D);
//generate textures
glGenTextures(1,&_textures[0]);
//bind the texture
glBindTexture(GL_TEXTURE_2D,_textures[0]);
//texture parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D,_textures[0]);
//generate 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());
glBindTexture(GL_TEXTURE_2D,_textures[0]);
//return the texture ID
return _textures[0];
}
这是绘图代码:
//this does draw
//get the texture ID
GLuint tex_id = LoadGLTextures(":/star.png");
glBindTexture(GL_TEXTURE_2D, tex_id); // Actually have an array of images
glColor3f(1.0f, 0.0f, 0.5f);
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 0.0f);glVertex2f(1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);glVertex2f(1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);glVertex2f(0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);glVertex2f(0.0f, 0.0f);
glEnd();
//this does not draw
//translations code
glLoadIdentity();
glTranslatef(-1.0f, 0.0f, 0.0f);
//bind the texture
glBindTexture(GL_TEXTURE_2D, tex_id);
//set color state
glColor4f(0.0f, 1.0f, 0.0f, 0.5);
//vertices to be rendered
static GLfloat vertices[] =
{
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f
};
static GLshort coord_Data[] =
{
1, 0,
1, 1,
0, 1,
0, 0
};
//bind the texture
glBindTexture(GL_TEXTURE_2D, tex_id);
//pointer to the vertex array
glVertexPointer(2, GL_FLOAT, 0, vertices);
//texture coordinate pointer
glTexCoordPointer(2, GL_SHORT, 0, coord_Data);
//draw the arrays
glDrawArrays(GL_QUADS, 0, 4);
感谢您的帮助, Dragonwrenn
答案 0 :(得分:2)
一种可能性是问题源于在调用glTexCoordPointer之前调用glVertexCoordPointer。在顶点坐标后指定纹理坐标时会发生奇怪的事情。我知道这对于使用纹理坐标绘制单个顶点是正确的。我不确定数组是否属实。
其他一些事情......
您是否尝试过使用QPixMap而不是QImage?我怀疑这是你的问题的答案,因为它听起来像纹理适当地应用于第一个四边形。
有两次调用bindTexture。
您是否尝试过在代码的第二部分绘制顶点(没有纹理)?
最后,你得到任何编译器警告吗?
答案 1 :(得分:0)
您放置OpenGL状态操作的方式很难跟踪事物。按需设置OpenGL状态是个好主意。所以
移动此
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_CORRD_ARRAY);
之前
//bind the texture
glBindTexture(GL_TEXTURE_2D, tex_id);
glVertexPointer(2, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_SHORT, 0, coord_Data);
//draw the arrays
glDrawArrays(GL_QUADS, 0, 4);
您也应该从initGL
移动其他代码。
在向glTexImage提供数据之前属于纹理加载器:
glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 );
属于绘图功能的开头:
glShadeModel(GL_SMOOTH);
glClearColor(0, 0, 0, 1);
glEnable( GL_COLOR_MATERIAL );
glColorMaterial ( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
glDisable(GL_DEPTH_TEST);
遵循该方案,您还应在绘图功能中设置视口和投影矩阵。我只是在说这个,因为大多数教程都采用不同的方式,这使得人们认为这是正确的方法。技术上也是投影和视口以及按需状态。
每次绘制调用都不应重新加载纹理。请注意,通过绘图处理程序按需初始化纹理是一个好主意,您应该在纹理封装类中添加一些标志,告诉我,如果引用的纹理已经可用于OpenGL。
仅出于调试目的,请尝试将纹理坐标的类型更改为浮动。