Frage

Ich versuche, ein paar Maschen mit einer frustumischen Projektion auf einem Hintergrundbild (orthografische Projektion) zu rendern. Egal was ich tue, das Hintergrundbild steht immer wieder auf der Szene (versteckt die Maschen).

Ich habe einen kleinen Test ausprobiert - als ich sie beide mit derselben Projektionsmatrix gemacht habe, die in der richtigen Reihenfolge waren - war das Hintergrundbild hinter den Maschen.

Dies sind die Projektionsmatrizen und die Tiefenpuffer init:

glEnable(GL_DEPTH_TEST);
glClearDepthf( 1.0f );
glDepthFunc( GL_LEQUAL );
glDepthMask (GL_TRUE);

EGLConfig eglconfig;
EGLint const attrib_list[] = {
    EGL_DEPTH_SIZE, 16,
    EGL_NONE
};
EGLint numreturned;
CHECK(eglChooseConfig(esContext.eglDisplay, attrib_list, &eglconfig, 1, &numreturned) != EGL_FALSE);

float fieldOfView = 60.0;
float znear = 0.1f;
float zfar = 100000;
float size = (float)(znear * tanf((fieldOfView * M_PI /180.0f) / 2.0f)); 

m_orthoProjMatrix.loadOrtho(0, 
                            screenWidth, 
                            0, 
                            screenHeight, 
                            znear, 
                            zfar);

m_frustProjMatrix.loadFrustum(-size, 
                               size, 
                              -size / (screenWidth / screenHeight), 
                               size / (screenWidth / screenHeight), 
                               znear, 
                               zfar);

Ich reinige die Puffer mit: glclear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

Eine letzte Sache. Wenn ich GL_Depth_test deaktiviere, werden die Maschen vor dem Hintergrundbild gezeichnet, weil der Hintergrund zuerst aufgerufen wird.

Ich kann nicht sagen, welches, der Tiefenpuffer oder die Projektionsmatrizen, die dieses Problem verursachen. Die Werte der Matrizen mit Screenwidth = 960 und ScreenHeight = 640:

Orthographic Proj Matrix:
0.00208 0.00000 0.00000 -1.00000
0.00000 0.00313 0.00000 -1.00000
0.00000 0.00000 0.00000 -1.00000
0.00000 0.00000 0.00000  1.00000

Frustum Proj Matrix:
1.73205 0.00000  0.00000  0.00000
0.00000 2.59808  0.00000  0.00000
0.00000 0.00000 -1.00000 -0.20000
0.00000 0.00000 -1.00000  0.00000

Camera Settings:
Vector3 pos(0,10,50);
Vector3 at(0,0,0);
Vector3 up(0,1,0);
LookAt(pos,at,up);

Scene Settings:
Vector3 BackgroundImagePosition (0,0, -430);
Vector3 SomeMesh(0,0,0);

Was mache ich falsch? Amir.

Bearbeiten: So zeichne ich die Bilder mit der orthografischen Projektion:

GLfloat verts[] = { 
image->x + image->width  , image->y                , image->z,
image->x + image->width  , image->y + image->height, image->z,
image->x                 , image->y + image->height, image->z,
image->x                 , image->y                , image->z};
Matrix4s mv(m_camera->getCameraViewMatrix());
Matrix4f proj(ResManPtr->getOrthoProjMatrix() * mv);
glUniformMatrix4fv(prog->getUniformLocation("u_projMatrix"), 1, GL_FALSE, &(*proj));
glActiveTexture(GL_TEXTURE0);
image->tex->bind();
glUniform1i(prog->getUniformLocation("s_texture"), 0);
glEnableVertexAttribArray(prog->getAttribLocation("a_position")); 
glVertexAttribPointer(prog->getAttribLocation("a_position"), 3, GL_FLOAT, GL_FALSE, 0, verts); 
glEnableVertexAttribArray(prog->getAttribLocation("a_texCoord"));
glVertexAttribPointer(prog->getAttribLocation("a_texCoord"), 2, GL_FLOAT, GL_FALSE, 0, m_texcoord);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

Und so zeichne ich die Netze mit der frustumischen Projektion:

Matrix4f mv(world->getCamera()->getCameraViewMatrix());
const btVector3& dir = getDirection();
Scalar xzAngle = atan2s(dir.x(), dir.z()) - (Scalar)M_PI_2;
btVector3 origin = getGhostObject()->getWorldTransform().getOrigin();
mv.applyTranslate(origin.x(), origin.y() - m_width/2, origin.z());
mv.applyRotateY(xzAngle);    
GLProgramPtr prog = ResManPtr->getProgramMap()[Consts::DEFAULT_PROGRAM_KEY];
Matrix4f proj(ResManPtr->getFrustProjMatrix() * mv);
glUniformMatrix4fv(prog->getUniformLocation("u_projMatrix"), 1, GL_FALSE, &(*proj));
glActiveTexture(GL_TEXTURE0);
m_texture->bind();  
glUniform1i(prog->getUniformLocation("s_texture") , 0);
m_model->render(frame_number);
War es hilfreich?

Lösung

Wenn ich richtig verstehe, möchten Sie die folgenden separaten Dinge tun:

  • Zeichnen Sie ein Vollbildquad mit einer Textur darauf
  • Tun Sie etwas, damit dieses Quad im Z-Puffer nicht berücksichtigt wird
  • Zeichnen Sie danach ein Netz (mit der gewünschten Projektion, Ansicht und Modellmatrizen).

"Wenn ich GL_Depth_test deaktiviere, werden die Netze vor dem Hintergrundbild gezeichnet, weil der Hintergrund zuerst aufgerufen wird." -> Ich nehme an, dass Sie sowohl Ihr Vollbild -Quad als auch unser Netz getrennt zeichnen können. So sind VBO -Setup, Matrizen, Texturen und Dinge gut. Es ist nur Punkt Nr. 2, der vermisst.

  • Lösung 1:

Löschen Sie alles für einen neuen Rahmen, genau wie immer. Z-Puffer wird überall 1,0 sein

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

Zeichnen Sie den Hintergrund. Ihr Farbpuffer ist in Ordnung, aber es saugt, weil der Z-Puffer die Tiefe Ihres Quad enthält, sagen wir 0,5. Wenn Sie Ihr Netz rendern, müssen Sie das Glück haben, dass die neuen Tiefenwerte kleiner als 0,5 sind oder der Tiefentest fehlschlägt. Aber wir können etwas dagegen tun: Löschen Sie einfach den Z-Puffer auf 1,0 wieder:

glClear(GL_DEPTH_BUFFER_BIT);

Zeichnen Sie jetzt das andere Netz wie gewohnt. Die ModelViewProjection -Matrix hat sich geändert, aber OpenGL weiß nicht das: Es weiß nur, dass die Tiefe überall 1,0 ist. Der Tiefentest ist also immer erfolgreich für Ihr Netz. Sie werden also Ihr Netz sehen, wo es sein sollte, mit korrekten Z-Werten und dem Hintergrundquad überall sonst.

  • Lösung 2

Hier verhindern Sie, dass die Tiefenwerte aktualisiert werden, wenn das Full -Screen -Quad gezogen wird.

Deaktivieren Sie Schreibvorgänge über den Tiefenpuffer:

glDepthMask(GL_FALSE);

Zeichnen Sie den Hintergrund. Farbpuffer ist in Ordnung, und Z-Buffer enthält immer noch überall 1.0, wie von glclear () einige Zeilen oben festgelegt.

Jetzt schreibt wiederum über den Tiefenpuffer:

glDepthMask(GL_TRUE);

Zeichne das andere Netz. Z-Puffer wird nach wie vor überall 1,0 sein, als hätten Sie gerade Glclear () angerufen. gemalt werden.

  • Lösung 3

Zeichnen Sie einfach Ihren Hintergrund weit weg von der Kamera in der Nähe des fernen Clipping -Flugzeugs. (dh mit einer großen Z -Komponente). Die Z-Komponente wird 0,9999 oder so ähnlich sein, und wie zuvor wird Mesh in Ordnung rendern.

Ich kann wirklich nicht in Details erklären. Tut mir leid, wenn es immer noch nicht klar ist, ich habe versucht, jede Idee auf verschiedene Weise neu zu formulieren, kann nichts mehr tun.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top