具有纹理的扩展旋转立方体示例

时间:2014-06-05 20:28:07

标签: c opengl

我目前正在研究一个有效的旋转立方体示例的扩展。 但是因为有很多变化,因为index_buffers不是纹理的好主意,我 现在有一个bug。我无法弄清楚为什么我的立方体现在只包含一些三角形。 所以我希望其他人能找到问题。

为了更好地理解,我将整个代码放在此页面上。

https://www.dropbox.com/s/0mj5wb56rfzvpsx/Rotating_Cube.zip

 GLfloat vertex_buffer_data[] = { /* 8 cube vertices */
    -1.0, -1.0,  1.0,
     1.0, -1.0,  1.0,
     1.0,  1.0,  1.0,
    -1.0,  1.0,  1.0,
    -1.0, -1.0, -1.0,
     1.0, -1.0, -1.0,
     1.0,  1.0, -1.0,
    -1.0,  1.0, -1.0,
};

GLushort index_buffer_data[] = { // Indices of 6*2 triangles
    0, 1, 2,
    2, 3, 0,
    1, 5, 6,
    6, 2, 1,
    7, 6, 5,
    5, 4, 7,
    4, 0, 3,
    3, 7, 4,
    4, 5, 1,
    1, 0, 4,
    3, 2, 6,
    6, 7, 3,
};

GLfloat UV[] = {
    0.0, 0.0,
    1.0, 1.0,
    0.0, 1.0,

    0.0, 0.0,
    1.0, 0.0,
    1.0, 1.0,

    0.0, 0.0,
    1.0, 1.0,
    0.0, 1.0,

    0.0, 0.0,
    1.0, 0.0,
    1.0, 1.0,

    0.0, 0.0,
    1.0, 1.0,
    0.0, 1.0,

    0.0, 0.0,
    1.0, 0.0,
    1.0, 1.0,

    0.0, 0.0,
    1.0, 1.0,
    0.0, 1.0,

    0.0, 0.0,
    1.0, 0.0,
    1.0, 1.0,

    0.0, 0.0,
    1.0, 1.0,
    0.0, 1.0,

    0.0, 0.0,
    1.0, 0.0,
    1.0, 1.0,

    0.0, 0.0,
    1.0, 1.0,
    0.0, 1.0,

    0.0, 0.0,
    1.0, 0.0,
    1.0, 1.0
};

typedef struct {
    GLfloat Position[3];
    GLfloat UV[2];
} VertexData;

VertexData Vertices[index_size];



/*----------------------------------------------------------------*/


/******************************************************************
*
* Display
*
* This function is called when the content of the window needs to be
* drawn/redrawn. It has been specified through 'glutDisplayFunc()';
* Enable vertex attributes, create binding between C program and 
* attribute name in shader
*
*******************************************************************/

void Display()
{
    /* Clear window; color specified in 'Initialize()' */
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glEnableVertexAttribArray(vPosition);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glVertexAttribPointer(vPosition, 3, GL_FLOAT, GL_FALSE, 0, 0);

    glEnableVertexAttribArray(vUV);
    glBindBuffer(GL_ARRAY_BUFFER, TextureID);
    glVertexAttribPointer(vUV, 2, GL_FLOAT, GL_FALSE, 0, 0);

    /*glEnableVertexAttribArray(vColor);
    glBindBuffer(GL_ARRAY_BUFFER, CBO);
    glVertexAttribPointer(vColor, 3, GL_FLOAT,GL_FALSE, 0, 0);   
    */

    //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
    //GLint size;
    //glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);


    /* Activate first (and only) texture unit */
    glActiveTexture(GL_TEXTURE0);

    /* Bind current texture  */
    glBindTexture(GL_TEXTURE_2D, TextureID);

    /* Get texture uniform handle from fragment shader */ 
    TextureUniform  = glGetUniformLocation(ShaderProgram, "myTextureSampler");

    /* Set location of uniform sampler variable */ 
    glUniform1i(TextureUniform, 0);

    /* Enable position and UV attribute */
    glEnableVertexAttribArray(vPosition);
    glEnableVertexAttribArray(vUV);


    glVertexAttribPointer(vPosition, 3, GL_FLOAT, GL_FALSE, sizeof(vertex_buffer_data), 0);
    glVertexAttribPointer(vUV, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (const GLvoid*) sizeof(Vertices[0].Position));

    /* Associate program with shader matrices */
    GLint projectionUniform = glGetUniformLocation(ShaderProgram, "ProjectionMatrix");
    if (projectionUniform == -1) 
    {
        fprintf(stderr, "Could not bind uniform ProjectionMatrix\n");
    exit(-1);
    }
    glUniformMatrix4fv(projectionUniform, 1, GL_TRUE, ProjectionMatrix);

    GLint ViewUniform = glGetUniformLocation(ShaderProgram, "ViewMatrix");
    if (ViewUniform == -1) 
    {
        fprintf(stderr, "Could not bind uniform ViewMatrix\n");
        exit(-1);
    }
    glUniformMatrix4fv(ViewUniform, 1, GL_TRUE, ViewMatrix);

    GLint RotationUniform = glGetUniformLocation(ShaderProgram, "ModelMatrix");
    if (RotationUniform == -1) 
    {
        fprintf(stderr, "Could not bind uniform ModelMatrix\n");
        exit(-1);
    }
    glUniformMatrix4fv(RotationUniform, 1, GL_TRUE, ModelMatrix);  

    glDrawArrays(GL_TRIANGLES, 0, numVertices);

    /* Disable attributes */
    glDisableVertexAttribArray(vPosition);
    glDisableVertexAttribArray(vUV);   

    /* Swap between front and back buffer */ 
    glutSwapBuffers();
}

void SetupDataBuffers()
{
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
}

void getNewVertices() {
    int i;
    for(i=0; i < index_size; i++){
        Vertices[i].Position[0] = vertex_buffer_data[3*index_buffer_data[i]+0];
        Vertices[i].Position[1] = vertex_buffer_data[3*index_buffer_data[i]+1];
        Vertices[i].Position[2] = vertex_buffer_data[3*index_buffer_data[i]+2];
        Vertices[i].UV[0] = UV[2*i];
        Vertices[i].UV[1] = UV[2*i+1];
    }
}

1 个答案:

答案 0 :(得分:2)

首先,你的顶点指针是错误的。

您没有在任何地方使用(名为VBO) TextureID,因此请删除所有此代码:

glEnableVertexAttribArray(vPosition);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(vPosition, 3, GL_FLOAT, GL_FALSE, 0, 0);

glEnableVertexAttribArray(vUV);
glBindBuffer(GL_ARRAY_BUFFER, TextureID);
glVertexAttribPointer(vUV, 2, GL_FLOAT, GL_FALSE, 0, 0);

将其替换为:

glBindBuffer (GL_ARRAY_BUFFER, VBO);
glEnableVertexAttribArray (vPosition);
glEnableVertexAttribArray (vUV);

最后,由于您将positionuv打包到一个结构数组中,这就是您想要的:

glVertexAttribPointer (vPosition, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), 0);
glVertexAttribPointer (vUV,       2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (const GLubyte*)0 + offsetof(struct VertexData,UV));

这将解决我立即看到您的代码出错的所有问题,可能还有其他问题我错过了。