Ich habe mich bemüht, die Ausgabe von glReadPixels zu verstehen, die in der Theorie offensichtlich einfach zu sein scheint, aber tatsächlich verwirrende (zumindest für mich) Ergebnisse hervorbringt.glReadPixels gibt immer den gleichen Wert in glClearColor zurück
Angenommen, ich habe einen einfachen Fragment-Shader, der ein einzelnes Dreieck mit einem Farbwert von vec4 (0,2, 0, 0, 0) zeichnet, während die Hintergrundfarbe auf (0,3, 1,0, 1,0, 0,0) eingestellt ist. etwa so:
Unten ist der vollständige Code (mit Ausnahme von Shader-Konstruktion), die ich oben das Bild erzeugen verwenden:
#include "shader.h" // shader compile/link/use
#include <GLFW\glfw3.h>
#include <iostream>
const int DISPLAY_WIDTH = 16;
const int DISPLAY_HEIGHT = 16;
//============= shader code ==========================
const GLchar *vertexShaderSource = R"glsl(#version 440
in vec2 position;
void main()
{
gl_Position = vec4(position, 0.0, 1.0);
})glsl";
const GLchar *fragmentShaderSource = R"glsl(#version 440
out vec4 outColor;
void main()
{
outColor = vec4(0.2,0.,0.,0.);
})glsl";
//============= c++ entry point ==========================
int main(int argc, char** argv) {
glfwInit();
GLFWwindow* window = glfwCreateWindow(DISPLAY_WIDTH, DISPLAY_HEIGHT, "test", NULL, NULL);
glfwMakeContextCurrent(window);
GLenum res = glewInit();
// triangle data (xy-position)
float vertices[] = {
0.0f, 0.5f,
0.5f, -0.5f,
-0.5f, -0.5f
};
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// enable vertex xy-position attribute
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
// compile, link and use shader program
Shader shader(vertexShaderSource, fragmentShaderSource);
shader.Use();
// rendering loop
while (!glfwWindowShouldClose(window)) {
glClearColor(0.3f, 1.0f, 1.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
glFlush();
// read pixels from backbuffer
GLubyte data[DISPLAY_WIDTH * DISPLAY_HEIGHT];
glReadPixels(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, GL_RED, GL_UNSIGNED_BYTE, data);
for (int i = 0; i < DISPLAY_WIDTH * DISPLAY_HEIGHT; i++) {
int a = data[i]; // implicit conversion of unsigned char to int
std::cout << a << std::endl;
}
std::getchar(); // wait for user input
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
Beachten Sie, dass ich einen Standard-Framebuffer bin mit , die meine Farbwerte als normalisierte s behandelt Ganzzahlige Ganzzahlen und konvertiert sie in den Bereich zwischen [0-255], dh meine Hintergrundfarbe wird (76, 255, 255, 0) sein, während meine Geometriefarbe (51, 0, 0, 0 sein wird).
Und so, nachdem ich meine Geometrie zeichnen und die Puffer tauschen, bekomme ich mein Bild. Jetzt möchte ich die Farbwerte auslesen. Um es zu tun, füge ich die notwendige glReadPixels bezogenen Code, kurz bevor ich Puffer tauschen:
GLubyte* data = new GLubyte[DISPLAY_WIDTH * DISPLAY_HEIGHT];
glReadPixels(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, GL_RED, GL_UNSIGNED_BYTE, data);
Um den Prozess der Prüfung der Pixelwerte zu erleichtern, die ich aus dem Framebuffer ausgelesen, ich Rotkanals nur extrahieren, daher ist die Größe der Daten, die erforderlich sind, um Pixeldaten aufzunehmen, DISPLAY_WIDTH * DISPLAY_HEIGHT
. Außerdem bedeutet dies, dass die Werte, die ich ausdrucke, für die Hintergrundfarbe '76' und für die Geometrie '51' sein sollten.
Überraschenderweise ist jeder einzelne Rotkanal-Pixeldaten (alle DISPLAY_WIDTH * DISPLAY_HEIGHT Pixel gedruckt), die ich ausdruck, zufällig '76', als ob die Geometrie ignoriert würde. Beachten Sie, dass ich Pixel nach dem Zeichenaufruf lese und bevor ich Puffer austausche.
Ich würde mich sehr freuen, wenn Sie mich wissen lassen könnten, was ich hier vermisse.
Wenn Sie Farbe für den Hintergrund, aber nicht für das Objekt erhalten, scheint 'glReadPixels' zwischen den Aufrufen" Clear Color "und" Swap Buffer "zu lesen. Oder es liest aus dem 'Front Buffer' statt dem Standard' Back Buffer' nach einem ersten Tausch, den Sie irgendwie vermissen. – Ripi2
Was Sie tun, sieht richtig aus. Sind Sie _sure_ Sie sehen nur Hintergrundpixel? Von Ihrem Bild wird es eine Menge Hintergrundpixel vor der ersten Geometrie geben ... – Bahbar
Bearbeiten in [mcve]. Fühlen Sie sich frei, [this] (https://stackoverflow.com/a/8841923/44729) als Basis zu verwenden. – genpfault