Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Problem with shadows OpenGL



  • Hi, I am trying to add shadow to my scene and I am having problems when I have more than 1 light with shadows.
    What happen is that sometimes it paint only 1 shadow and sometimes it paints the saame shadow twice and a bit moved.
    Now I am using 2 lights.
    This is my code for generating shadow maps:

    for( auto l : luces)
                    { // - Para cada fuente luminosa
                        if (l->getCastShadow() && l->getNeedRecalcShadow())
                        {
                            if(l->getTipo() == PUNTUAL)
                            {
                               l->setLookAtSombra(QVector3D(camaras[camaraActiva].getLookAt()));
                            }
                            // - Calcular la matriz de visión y proyección para la luz lightVPMat
                            l->calcularVPMatrix();
                            QMatrix4x4 vpMatrixLuz = l->getVPMatrix();
    
                            glwindow::getInstance()->makeCurrent();
                            glBindFramebuffer(GL_FRAMEBUFFER, l->getShadowFBO2());
                            glActiveTexture(GL_TEXTURE2);
                            glBindTexture(GL_TEXTURE_2D, l->getDepthText());
                            glClear(GL_DEPTH_BUFFER_BIT);
                            glViewport(0, 0, l->getShadowMapWidth(), l->getShadowMapHeight());
                            glEnable(GL_DEPTH_TEST);
                            glDepthFunc(GL_LESS);
                            glEnable(GL_PRIMITIVE_RESTART);
                            glPrimitiveRestartIndex(FINAL);
                            glEnable(GL_CULL_FACE);
                            glCullFace(GL_FRONT);
    
                            for( auto o : objetosEscena)
                            {
                                if (modoTextura)
                                {
    
                                    QMatrix4x4 lightMVP = vpMatrixLuz * o.second->getModelMatrix();
                                    shaderGenerarSombras->use();
                                    shaderGenerarSombras->setUniform("mvpMatrixLuz", lightMVP);
                                    o.second->drawAsTriangles(shaderGenerarSombras,modelMatrix,l->getVisionMatrixLuz(),l->getProyectionMatrixLuz());
    
                                 }
    
                            }
                            GLubyte *pixels;
                            pixels = (GLubyte *)malloc(512*512*4);
                            glReadPixels(0, 0, 512, 512, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, pixels);
                            QImage image = QImage(pixels, 512, 512, QImage::Format_Grayscale8);
                            image = image.mirrored();
                            QString str = "Mapa"+QString::number(cont)+".png";
                            cont++;
                            bool resul = image.save(str, "PNG");
                            l->setNeedRecalcShadow(false);
    
                        }
                    }
    

    and this is the code to paint shadows:

    glBindFramebuffer(GL_FRAMEBUFFER, glwindow::getInstance()->defaultFramebufferObject());
                glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
                glEnable(GL_MULTISAMPLE);
                glEnable(GL_DEPTH_TEST);
                glPrimitiveRestartIndex(FINAL);
                glEnable(GL_PRIMITIVE_RESTART);
                glEnable(GL_BLEND);
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                glEnable(GL_CULL_FACE);
                glCullFace(GL_BACK);
                glViewport(0, 0, width, height);
                glDepthFunc(GL_LEQUAL);
    for( auto l : luces)
                    { // - Para cada fuente luminosa
                        if (l->getCastShadow())
                        {
    
                            LightTypes tipo = l->getTipo();
                            if (tipo != AMBIENTAL)
                            {
                                if (primero)
                                {
                                    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                                    primero = false;
                                }
                                else
                                {
                                    glBlendFunc(GL_SRC_ALPHA, GL_ONE);
                                }
    
                                shaderProgram* shader = shadersLuzSombras.find(tipo)->second;
                                l->setVisionMatrix(visionMatrix);
                                l->aplicar(shader);
                                shader->use();
                                if(atenuacionEnabled)
                                {
                                    shader->setUniform("atenuacionEnabled",1);
                                    shader->setUniform("c1",c1);
                                    shader->setUniform("c2",c2);
                                    shader->setUniform("c3",c3);
                                }else
                                {
                                    shader->setUniform("atenuacionEnabled",0);
                                }
                                if(fogEnabled && l->getKeyLight())
                                {
                                    shader->setUniform("fogEnabled",1);
                                    shader->setUniform("zMin",this->zMin);
                                    shader->setUniform("zMax", this->zMax);
    
                                }else
                                {
                                    shader->setUniform("fogEnabled",0);
                                }
                                luzAmbiental->aplicar(shader);
                                glActiveTexture(2);
                                glBindTexture(GL_TEXTURE_2D, l->getDepthText());
                                QMatrix4x4 vpMatrixLuz = l->getVPMatrix();
                                QMatrix4x4 lightViewProjMatrix = shadowBias * vpMatrixLuz;
                                for( auto o : objetosEscena)
                                {
                                    QMatrix4x4 lightMVP = lightViewProjMatrix * o.second->getModelMatrix();
                                    shader->use();
                                    shader->setUniform("shadowMap", 2);
                                    shader->setUniform("mShadowMatrix",lightMVP);
                                    shader->setUniform("shadowMin",0.1f);
                                    o.second->drawAsTriangles(shader,modelMatrix,visionMatrix,proyectionMatrix);
    
                                }
    
                            }
    
                        }
    
    
                    }
    

    I was debbuging and the texture id are different and it coincides with the id where the shadow map are saved.
    I leave you here the shadow maps:
    1_1563810110579_Mapa1.png 0_1563810110579_Mapa0.png

    and this is the result:
    0_1563810124544_Captura.PNG

    Thanks.



  • I found the solution, I don't know why but I had to create a QOpenGLTexture with my texture and then bind that QOpenGLTexture. I don't know why it doesn't work with glActiveTexture() and glBindTexture().


Log in to reply