不正确的纹理映射,而使用QGLBuffer



我为假定的目标平台编写了基本的OpenGL 2.1ES示例,在Windows上使用Qt 4.7.1库。目标是某种Linux, Qt 4.8 max可用,没有glm或类似的库。嵌入式GPU仅支持es1.0或opengl2.1。例如"经典"纹理立方体,你可能会在各种OpenGL示例中遇到它。但这些例子使用直接调用OpenGL函数,这对我来说是不可用的,因为缺乏适当的头和发光-无论是在开发和目标平台上。开发平台为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,它们对应于适当的顶点-但看起来纹理坐标的顺序是错误的。错误在哪里?

参考:源代码

这是我第一次尝试使用柔性管道,所以我可以在这里做一些蠢事。

你正在设置纹理坐标缓冲区作为索引缓冲区:

m_texBuffer = new QGLBuffer(QGLBuffer::IndexBuffer );

因为它包含顶点属性数据,它应该被创建为:

m_texBuffer = new QGLBuffer(QGLBuffer::VertexBuffer);

最新更新