我在Windows上使用Qt 4.7.1库为假定的目标平台制作了基本的OpenGL 2.1 \ ES示例。 Target是某种Linux,Qt 4.8最大可用,没有glm或类似的库。嵌入式GPU仅支持ES 1.0或OpenGL 2.1。例子是"经典"纹理多维数据集,你可能会在各种OpenGL示例中遇到..但是这些示例使用对OpenGL函数的直接调用,因为缺乏正确的标题和glew而无法在开发和目标平台上使用。开发平台是Windows 7。
几何
static const int vertexDataCount = 6 * 4 * 4;
static const float vertexData[vertexDataCount] = {
// Left face
-0.5f, -0.5f, -0.5f, 1.0f,//0
-0.5f, -0.5f, 0.5f, 1.0f,//1
-0.5f, 0.5f, 0.5f, 1.0f,//2
-0.5f, 0.5f, -0.5f, 1.0f,//3
// Top face
-0.5f, 0.5f, -0.5f, 1.0f, //4
-0.5f, 0.5f, 0.5f, 1.0f, //5
0.5f, 0.5f, 0.5f, 1.0f, //6
0.5f, 0.5f, -0.5f, 1.0f, //7
// Right face
0.5f, 0.5f, -0.5f, 1.0f,//8
0.5f, 0.5f, 0.5f, 1.0f,//9
0.5f, -0.5f, 0.5f, 1.0f,//10
0.5f, -0.5f, -0.5f, 1.0f,//11
// Bottom face
0.5f, -0.5f, -0.5f, 1.0f,//12
0.5f, -0.5f, 0.5f, 1.0f,//13
-0.5f, -0.5f, 0.5f, 1.0f,//14
-0.5f, -0.5f, -0.5f, 1.0f,//15
// Front face
0.5f, -0.5f, 0.5f, 1.0f,//16/
0.5f, 0.5f, 0.5f, 1.0f,//17
-0.5f, 0.5f, 0.5f, 1.0f,//18
-0.5f, -0.5f, 0.5f, 1.0f,//19
// Back face
0.5f, 0.5f, -0.5f, 1.0f,//20
0.5f, -0.5f, -0.5f, 1.0f,//21
-0.5f, -0.5f, -0.5f, 1.0f,//22
-0.5f, 0.5f, -0.5f, 1.0f //23
};
// Normal vectors
static const int normalDataCount = 6 * 4 * 3;
static const float normalData[normalDataCount] = {
// Left face
-1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
// Top face
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
// Right face
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
// Bottom face
0.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
// Front face
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
// Back face
0.0f, 0.0f, -1.0f,
0.0f, 0.0f, -1.0f,
0.0f, 0.0f, -1.0f,
0.0f, 0.0f, -1.0f
};
// Texure coords
static const int textureCoordDataCount = 6 * 4 * 2;
static const float textureCoordData[textureCoordDataCount] = {
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f
};
// Indices
//
// 3 indices per triangle
// 2 triangles per face
// 6 faces
static const int indexDataCount = 6 * 3 * 2;
static const unsigned int indexData[indexDataCount] = {
0, 1, 2, 0, 2, 3, // Left face
4, 5, 6, 4, 6, 7, // Top face
8, 9, 10, 8, 10, 11, // Right face
12, 14, 15, 12, 13, 14, // Bottom face
16, 17, 18, 16, 18, 19, // Front face
20, 22, 23, 20, 21, 22 // Back face
};
这就是我加载纹理的方法
glEnable(GL_TEXTURE_2D);
m_texture = bindTexture(QImage("cube.png"));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
if(m_shaderProgram)
m_shaderProgram->setUniformValue("texture", 0); // texture unit 0, assuming that we used
顶点着色器
#version 120
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
attribute vec4 vertex;
attribute vec3 normal;
attribute vec2 texturecoord;
varying vec3 fragmentNormal;
varying vec2 outtexture;
void main( void )
{
// Transform the normal vector
fragmentNormal = ( modelViewMatrix * vec4( normal, 0.0 ) ).xyz;
// Calculate the clip-space coordinates
gl_Position = projectionMatrix * modelViewMatrix * vertex;
outtexture = texturecoord;
}
片段着色器
#version 120
// in
uniform sampler2D texture;
varying vec2 outtexture;
varying vec3 fragmentNormal;
// out
// gl_FragColor
void main( void )
{
// Calculate intensity as max of 0 and dot product of the
// fragmentNormal and the eye position (0,0,1).
float intensity;
intensity = max( dot( fragmentNormal, vec3( 0.0, 0.0, 1.0 ) ), 0.15 );
gl_FragColor = intensity * texture2D(texture,outtexture); // vec4( 1.0, 0.0, 0.0, 1.0 );
}
我以这种方式绑定缓冲区(prepareBufferObject是我从Qt示例中获取的小片段函数):
// Prepare the vertex, normal and index buffers
m_vertexBuffer = new QGLBuffer(QGLBuffer::VertexBuffer );
if ( !prepareBufferObject( m_vertexBuffer, QGLBuffer::StaticDraw, vertexData, sizeof(vertexData) ) )
return;
m_normalBuffer = new QGLBuffer(QGLBuffer::VertexBuffer );
if ( !prepareBufferObject( m_normalBuffer, QGLBuffer::StaticDraw, normalData, sizeof(normalData) ) )
return;
m_texBuffer = new QGLBuffer(QGLBuffer::IndexBuffer );
if ( !prepareBufferObject( m_texBuffer, QGLBuffer::StaticDraw, textureCoordData, sizeof(textureCoordData) ) )
return;
m_indexBuffer = new QGLBuffer(QGLBuffer::IndexBuffer );
if ( !prepareBufferObject( m_indexBuffer, QGLBuffer::StaticDraw, indexData, sizeof(indexData) ) )
return;
loadShaders("vertexshader120.glsl", "fragshader120.glsl");
// Enable the "vertex" attribute to bind it to our vertex buffer
m_vertexBuffer->bind();
m_shaderProgram->setAttributeBuffer( "vertex", GL_FLOAT, 0, 4 ); //xyzw
m_shaderProgram->enableAttributeArray( "vertex" );
// Enable the "normal" attribute to bind it to our texture coords buffer
m_normalBuffer->bind();
m_shaderProgram->setAttributeBuffer( "normal", GL_FLOAT, 0, 3 ); //xyz
m_shaderProgram->enableAttributeArray( "normal" );
m_texBuffer->bind();
m_shaderProgram->setAttributeBuffer( "texturecoord", GL_FLOAT, 0, 2 ); //uv
m_shaderProgram->enableAttributeArray( "texturecoord" );
// Bind the index buffer ready for drawing
m_indexBuffer->bind();
最后,paintGL方法
void GWidget::paintGL()
{
QMatrix4x4 model;
model.setToIdentity();
model.rotate(m_rotation);
QMatrix4x4 mv = m_view * model;
// MVP = projection * view * model
// uploading MVP into shader (may add code to check if MVP was update since last redraw)
m_shaderProgram->setUniformValue("modelViewMatrix",mv);
m_shaderProgram->setUniformValue("projectionMatrix",m_projection);
// set up to render the scene
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw stuff
glDrawElements( GL_TRIANGLES, // Type of primitive to draw
indexDataCount, // The number of indices in our index buffer we wish to draw
GL_UNSIGNED_INT, // The element type of the index buffer
0 ); // Offset from the start of our index buffer of where to begin
}
除了纹理在开发和目标平台上看起来未对齐和倾斜之外,一切都有效。我检查了UV并且它们对应于正确的顶点 - 但它看起来像纹理坐标的顺序是错误的。这里的错误在哪里?
供参考:source code
这是我第一次尝试使用灵活的管道,所以我可以做一些愚蠢的事情。
答案 0 :(得分:1)
您正在将纹理坐标缓冲区设置为索引缓冲区:
m_texBuffer = new QGLBuffer(QGLBuffer::IndexBuffer );
由于它包含顶点属性数据,因此应将其创建为:
m_texBuffer = new QGLBuffer(QGLBuffer::VertexBuffer);