为什么glreadpixels仅在某些情况下有效?

时间:2018-12-03 03:13:18

标签: c++ opengl graphics

如果我尝试使用glreadpixels来阅读屏幕,然后使用gldrawpixels再次绘制相同的内容,则必须,但仅当我使用除gldrawarrays以外的其他图形来绘制时, gldrawelementsgluSphere/gluCylinder工作正常)。我正在尝试在屏幕上绘制对象并将像素保存在数组中。

我尝试读取/写入前/后缓冲区,在交换缓冲区后读取,但无济于事。

这是我用来绘制对象的代码:(请注意,在此范围之外,我不使用任何类型的缓冲区)。

 void CCssample5View::DrawCylinder(Model obj)
    {
    GLuint VertexArrayID;
    glGenVertexArrays(1, &VertexArrayID);
    glBindVertexArray(VertexArrayID);

    Shader castingShader("casting.vs", "casting.fs");
    Shader lightShader("light.vs", "light.fs");

    GLuint MatrixID = glGetUniformLocation(castingShader.ID, "MVP");
    GLuint ViewMatrixID = glGetUniformLocation(castingShader.ID, "V");
    GLuint ModelMatrixID = glGetUniformLocation(castingShader.ID, "M");

    GLuint textur = loadBMP_custom("flower.bmp");
    GLuint TextureID = glGetUniformLocation(castingShader.ID , "myTextureSampler");


    indexVBO(obj.vertices, obj.uvs, obj.normals, obj.indices, obj.indexed_vertices, obj.indexed_uvs, obj.indexed_normals);

    GLuint vertexbuffer;
    glGenBuffers(1, &vertexbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glBufferData(GL_ARRAY_BUFFER, obj.indexed_vertices.size() * sizeof(glm::vec3), &obj.indexed_vertices[0], GL_STATIC_DRAW);

    GLuint uvbuffer;
    glGenBuffers(1, &uvbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
    glBufferData(GL_ARRAY_BUFFER, obj.indexed_uvs.size() * sizeof(glm::vec2), &obj.indexed_uvs[0], GL_STATIC_DRAW);

    GLuint normalbuffer;
    glGenBuffers(1, &normalbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
    glBufferData(GL_ARRAY_BUFFER, obj.indexed_normals.size() * sizeof(glm::vec3), &obj.indexed_normals[0], GL_STATIC_DRAW);

    GLuint elementbuffer;
    glGenBuffers(1, &elementbuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, obj.indices.size() * sizeof(unsigned short), &obj.indices[0], GL_STATIC_DRAW);



    castingShader.use();

    GLuint LightID = glGetUniformLocation(castingShader.ID, "LightPosition_worldspace");
    computeMatricesFromInputs();
    GLfloat gProjectionMatrix[16];
    glGetFloatv(GL_PROJECTION_MATRIX, gProjectionMatrix);
    glm::mat4 ProjectionMatrix = glm::make_mat4(gProjectionMatrix);// = glm::mat4(gProjectionMatrix);   

    GLfloat gViewMatrix[16];
    glGetFloatv(GL_MODELVIEW_MATRIX, gViewMatrix);
    glm::mat4 ViewMatrix = glm::make_mat4(gViewMatrix);// = glm::mat4(gProjectionMatrix);

    glm::vec3 lightPos = glm::vec3(4, 4, 4);
    glUniform3f(LightID, lightPos.x, lightPos.y, lightPos.z);
    glUniformMatrix4fv(ViewMatrixID, 1, GL_FALSE, &ViewMatrix[0][0]);

    glm::mat4 ModelMatrix1 = glm::mat4(1.0);
    glm::mat4 MVP1 = ProjectionMatrix * ViewMatrix * ModelMatrix1;


    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, textur);

    glUniform1i(TextureID, 0);
    // Send our transformation to the currently bound shader, 
    // in the "MVP" uniform
    glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP1[0][0]);
    glUniformMatrix4fv(ModelMatrixID, 1, GL_FALSE, &ModelMatrix1[0][0]);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glVertexAttribPointer(
        0,                  // attribute
        3,                  // size
        GL_FLOAT,           // type
        GL_FALSE,           // normalized?
        0,                  // stride
        (void*)0            // array buffer offset
    );

    // 2nd attribute buffer : UVs
    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
    glVertexAttribPointer(
        1,                                // attribute
        2,                                // size
        GL_FLOAT,                         // type
        GL_FALSE,                         // normalized?
        0,                                // stride
        (void*)0                          // array buffer offset
    );

    // 3rd attribute buffer : normals
    glEnableVertexAttribArray(2);
    glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
    glVertexAttribPointer(
        2,                                // attribute
        3,                                // size
        GL_FLOAT,                         // type
        GL_FALSE,                         // normalized?
        0,                                // stride
        (void*)0                          // array buffer offset
    );

    // Index buffer
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);

    // Draw the triangles !
    glDrawElements(
        GL_TRIANGLES,      // mode
        obj.indices.size(),    // count
        GL_UNSIGNED_SHORT,   // type
        (void*)0           // element array buffer offset
    );

    //glFlush(); glFinish(); readScreen(screen, GL_RGB, true);

    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(2);

    glDeleteBuffers(1, &vertexbuffer);
    glDeleteBuffers(1, &uvbuffer);
    glDeleteBuffers(1, &normalbuffer);
    glDeleteBuffers(1, &elementbuffer);
    glDeleteProgram(castingShader.ID);
    glDeleteTextures(1, &textur);
    glDeleteVertexArrays(1, &VertexArrayID);
}

这些是我的读取和绘制屏幕功能:

void CCssample5View::readScreen(GLubyte* screen, GLenum format, bool back)
{
    check();


    if (format == GL_RGB) {


        check();
        if (back) {
            glReadBuffer(GL_BACK);
            check();
        }
        else {
            glReadBuffer(GL_FRONT);
            check();
        }

    }
    //glRasterPos2i(00, 00);
    //glDisable(GL_DEPTH_TEST);
    glPixelStorei(GL_PACK_ALIGNMENT, 1);
    glReadPixels(0, 0, w, h, format, GL_UNSIGNED_BYTE, screen);


    glFlush();
    glFinish();
    bool found = false;
    for (size_t u = 0; u <= w * h * 4; u++) {
        if (screen[u] != 0) {
            found = true;
            break;
        }
    }
    assert(found);
    check();


}
void CCssample5View::drawScreen(GLubyte *screen, GLenum format, bool back)
{


    glClear(GL_COLOR_BUFFER_BIT);
    //glGetIntegerv(GL_CURRENT_RASTER_POSITION, rasterpos);
    if (back) {
        glDrawBuffer(GL_BACK);
    }
    else {
        glDrawBuffer(GL_FRONT);
    }    

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glDrawPixels(w, h, format, GL_UNSIGNED_BYTE, screen);
    check();

    glFlush();
    glFinish();
}

除了阅读屏幕部分之外,当绘图完美时似乎无法找出问题所在。

1 个答案:

答案 0 :(得分:0)

我知道了。我所要做的就是在绘图滚筒功能的最后添加glUseProgram(0)。经过3个多星期的调查。