OpenGL的。无法绘制多个形状。新的init清除以前绘制的形状

时间:2016-01-22 10:07:54

标签: opengl graphics colors shapes

我正试图在正方形内绘制一些正方形。我有两个功能,initRedSquare()initBlueSquare()。他们有不同的缓冲区和单独的vao,我刚刚在这里发布问题之前添加了它。

单独地画出来。但是我希望蓝色能够出现在红色之上。制作蓝色方块时,它会完全移除红色方块。

在这两者之后我还要画出更多的形状。

代码:

void initRedSquare( GLfloat val )
{
    GLfloat vertices[] =
    {
        +0.0f, +0.0f,
        +1.0f, +0.0f, +0.0f,

        (+0.8f - val), (+0.8f - val),
        +1.0f, +0.0f, +0.0f,

        (-0.8f + val), (+0.8f - val),
        +1.0f, +0.0f, +0.0f,

        (-0.8f + val), (-0.8f + val),
        +1.0f, +0.0f, +0.0f,

        (+0.8f - val), (-0.8f + val),
        +1.0f, +0.0f, +0.0f,
    };

    // // Specifiy the vertices for a triangle
    // vec2 vertices[3] = {
    //     vec2( -1, 0 ), vec2( -0.8, 1 ), vec2( -0.6, 0 )
    // };

    // Create a vertex array object
    GLuint vao[1];
    glGenVertexArrays( 1, vao );
    glBindVertexArray( vao[0] );


    // Create and initialize a buffer object
    GLuint vertexbuffer;
    glGenBuffers( 1, &vertexbuffer );
    glBindBuffer( GL_ARRAY_BUFFER, vertexbuffer );
    glBufferData( GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW );

    // Load shaders and use the resulting shader program
    GLuint program = InitShader( "vshader21.glsl", "fshader21.glsl" );
    glUseProgram( program );

    // Initialize the vertex position attribute from the vertex shader
    GLuint vPosition_location = glGetAttribLocation( program, "vPosition" );
    glEnableVertexAttribArray( vPosition_location );
    glVertexAttribPointer( vPosition_location, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5,
                           BUFFER_OFFSET(0) );

    GLuint vColor_location = glGetAttribLocation( program, "vColor" );
    glEnableVertexAttribArray( vColor_location );
    glVertexAttribPointer( vColor_location, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5,
                           BUFFER_OFFSET(sizeof(float) * 2) );

    GLushort indices[] =
    {
        0, 1, 2,
        0, 3, 4,
        0, 2, 3,
        0, 4, 1
    };
    GLuint indexBuffer;
    glGenBuffers( 1, &indexBuffer );
    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, indexBuffer );
    glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW );



    //glClearColor( 1.0, 1.0, 1.0, 1.0 ); // white background
}


void initBlueSquare( GLfloat val )
{
    GLfloat vertices[] =
    {
        +0.0f, +0.0f,
        +0.0f, +0.0f, +1.0f,

        (+0.8f - val), (+0.8f - val),
        +0.0f, +0.0f, +1.0f,

        (-0.8f + val), (+0.8f - val),
        +0.0f, +0.0f, +1.0f,

        (-0.8f + val), (-0.8f + val),
        +0.0f, +0.0f, +1.0f,

        (+0.8f - val), (-0.8f + val),
        +0.0f, +0.0f, +1.0f,
    };

    // // Specifiy the vertices for a triangle
    // vec2 vertices[3] = {
    //     vec2( -1, 0 ), vec2( -0.8, 1 ), vec2( -0.6, 0 )
    // };

    // Create a vertex array object
    GLuint vao[2];
    glGenVertexArrays( 1, vao );
    glBindVertexArray( vao[1] );


    // Create and initialize a buffer object
    GLuint vertexbuffer2;
    glGenBuffers( 1, &vertexbuffer2 );
    glBindBuffer( GL_ARRAY_BUFFER, vertexbuffer2 );
    glBufferData( GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW );

    // Load shaders and use the resulting shader program
    GLuint program = InitShader( "vshader21.glsl", "fshader21.glsl" );
    glUseProgram( program );

    // Initialize the vertex position attribute from the vertex shader
    GLuint vPosition_location = glGetAttribLocation( program, "vPosition" );
    glEnableVertexAttribArray( vPosition_location );
    glVertexAttribPointer( vPosition_location, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5,
                           BUFFER_OFFSET(0) );

    GLuint vColor_location = glGetAttribLocation( program, "vColor" );
    glEnableVertexAttribArray( vColor_location );
    glVertexAttribPointer( vColor_location, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5,
                           BUFFER_OFFSET(sizeof(float) * 2) );

    GLushort indices[] =
    {
        0, 1, 2,
        0, 3, 4,
        0, 2, 3,
        0, 4, 1
    };
    GLuint indexBuffer2;
    glGenBuffers( 1, &indexBuffer2 );
    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, indexBuffer2 );
    glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW );



    //glClearColor( 1.0, 1.0, 1.0, 1.0 ); // white background
}

void
display( void )
{
    //glClear( GL_COLOR_BUFFER_BIT );     // clear the window
    //glDrawArrays( GL_TRIANGLES, 0, 6 );    // draw the points
    glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_SHORT, 0);
    glFlush();
}



void
keyboard( unsigned char key, int x, int y )
{
    switch ( key ) {
    case 033:
        exit( EXIT_SUCCESS );
        break;
    }
}



int
main( int argc, char **argv )
{
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGBA );
    glutInitWindowSize( 500, 500 );

    glutCreateWindow( "Assignment 2" );
    glewExperimental=GL_TRUE;

    glewInit();
    initRedSquare(0.2f);
    glutDisplayFunc( display );
    glutKeyboardFunc( keyboard );

    initBlueSquare(0.3f);
    glutDisplayFunc( display );
    glutKeyboardFunc( keyboard );

    glutMainLoop();
    return 0;
}

顶点着色器:

attribute vec4 vPosition;
attribute vec3 vColor;

varying vec3 finalColor;

void
main()
{
    gl_Position = vPosition;
    finalColor = vColor;
}

Fragment Shader:

varying vec3 finalColor;

void
main()
{
    gl_FragColor = vec4( finalColor, 1.0 );
}

1 个答案:

答案 0 :(得分:3)

你编程的方式是不合理的。

首先,最重要的是,glutDisplayFunc( display );不直接调用draw函数,它只是告诉过应该绘制什么东西时应该调用哪个函数。因此,此函数必须能够一次绘制所有内容,在您的情况下,它将需要两个具有正确状态集的绘制调用。

要做到这一点,你必须将init函数中生成的缓冲区/ vaos存储在这些函数之外的某个位置并绘制两个对象:

void display( void )
{
    glClear( GL_COLOR_BUFFER_BIT );

    glBindVertexArray(red_vao);
    glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_SHORT, 0);

    glBindVertexArray(blue_vao);
    glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_SHORT, 0);

    glFlush();
}

,其中red_vaoblue_vao是相应init函数中生成的vao句柄。

相关问题