C++ Qt顶点数组不使用QImage
首先,我要为问题的长度道歉。我相信我犯了一些小而愚蠢的错误,但由于我完全找不到它,我决定发布所有相关代码以防万一 我最终使用QImage实现了纹理加载,并且能够以即时模式渲染纹理。 然而,顶点数组不工作,我不知道为什么。 最明显的问题,如“是否启用了顶点阵列和纹理坐标阵列?”可能不是答案。我将发布初始化代码 以下是init函数:C++ Qt顶点数组不使用QImage,c++,qt,opengl,vertex-array,C++,Qt,Opengl,Vertex Array,首先,我要为问题的长度道歉。我相信我犯了一些小而愚蠢的错误,但由于我完全找不到它,我决定发布所有相关代码以防万一 我最终使用QImage实现了纹理加载,并且能够以即时模式渲染纹理。 然而,顶点数组不工作,我不知道为什么。 最明显的问题,如“是否启用了顶点阵列和纹理坐标阵列?”可能不是答案。我将发布初始化代码 以下是init函数: /* general OpenGL initialization function */ int initGL() { glS
/* 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 );
}
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];
}
我有QGLWidget调用的初始化、调整大小和绘制函数(它本身只是一个调用实际工作函数的框架)
纹理加载功能:
/* 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 );
}
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按照您放置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,则应向纹理封装类添加一些标志
仅出于调试目的,尝试将纹理坐标的类型更改为浮动。一种可能性是,问题源于在调用glTexCoordPointer之前调用glVertexCoordPointer。在顶点坐标之后指定纹理坐标时,会发生奇怪的事情。我知道这对于使用纹理坐标绘制单个顶点是正确的。我不确定数组是否正确 其他一些事情 您是否尝试过使用QPixMap而不是QImage?我怀疑这是你问题的答案,因为它听起来像纹理正确地应用于第一个四边形 有两个对bindTexture的调用 在代码的第二部分中,您是否尝试过只绘制顶点(没有纹理)
最后,您是否收到任何编译器警告?另请参见1。尝试将其更改为QPixmap。行为没有变化(立即模式四边形显示良好,顶点阵列不显示)2+1用于在顶点坐标之前提醒我纹理坐标(尽管问题仍未解决)3。立即模式绘图将正确继续,顶点阵列不会4。5没有编译器警告。感谢提醒您使用纹理绑定,您可以在某些调用之后,特别是在gldrawArray之后,尝试调用glGetError。也许这会对你的问题有所帮助。