【问题标题】:OpenGL. Cannot draw multiple shapes. New init clears previously drawn shapeOpenGL。无法绘制多个形状。新的初始化清除以前绘制的形状
【发布时间】:2016-01-22 10:07:54
【问题描述】:

我正在尝试在正方形内绘制一些正方形。我有两个函数,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;
}

片段着色器:

varying vec3 finalColor;

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

【问题讨论】:

    标签: opengl graphics colors shapes


    【解决方案1】:

    你的程序结构是行不通的。

    首先,也是最重要的,glutDisplayFunc( display ); 不直接调用 draw 函数,它只是告诉 glut 每当需要绘制某些东西时应该调用哪个函数。所以这个函数必须能够一次绘制所有内容,在你的情况下,它需要两个具有正确状态集的绘制调用。

    为此,您必须将在 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句柄。

    【讨论】:

    • 你能建议我如何在函数之外存储缓冲区/vaos。我是一个初学者,在这一点上我对如何去做这件事有点困惑。
    • 最简单的就是使用全局变量。
    • 这对 GLUT 来说有点不幸,因为它根本没有 void* 令牌。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-19
    • 2012-04-15
    相关资源
    最近更新 更多