Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 球体图像纹理被阴影贴图扭曲-OpenGL_C++_Opengl_3d_Geometry_Shadow - Fatal编程技术网

C++ 球体图像纹理被阴影贴图扭曲-OpenGL

C++ 球体图像纹理被阴影贴图扭曲-OpenGL,c++,opengl,3d,geometry,shadow,C++,Opengl,3d,Geometry,Shadow,我在OpenGL中使用固定函数管道(而不是着色器)进行阴影映射。我已经很好地实现了阴影贴图,但是在阴影投射的对象上没有纹理 当我在球体渲染之前将纹理添加到球体时,它会出现扭曲。我可以在光源周围移动,它会根据光源的位置或多或少地扭曲光源 可能的原因是什么 这是我的glLightfv(GL_LIGHT1,GL_漫反射,白色); glLightfv(GL_LIGHT1,GL_镜面反射,白色) 至于踢腿,这也是我的第一次和第二次传球 glClear(GL_COLOR_BUFFER_BIT | GL_DE

我在OpenGL中使用固定函数管道(而不是着色器)进行阴影映射。我已经很好地实现了阴影贴图,但是在阴影投射的对象上没有纹理

当我在球体渲染之前将纹理添加到球体时,它会出现扭曲。我可以在光源周围移动,它会根据光源的位置或多或少地扭曲光源

可能的原因是什么

这是我的glLightfv(GL_LIGHT1,GL_漫反射,白色); glLightfv(GL_LIGHT1,GL_镜面反射,白色)

至于踢腿,这也是我的第一次和第二次传球

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);
lightPosition = VECTOR3D(lightX, lightY, lightZ);
glLoadIdentity();
gluLookAt(  lightPosition.x, lightPosition.y, lightPosition.z,
            0.0f, 0.0f, 0.0f,
            0.0f, 1.0f, 0.0f);
glGetFloatv(GL_MODELVIEW_MATRIX, lightViewMatrix);




glMatrixMode(GL_PROJECTION);
glLoadMatrixf(lightProjectionMatrix);

glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(lightViewMatrix);

//Use viewport the same size as the shadow map
glViewport(0, 0, shadowMapSize, shadowMapSize);

//Draw back faces into the shadow map
glCullFace(GL_FRONT);

//Disable color writes, and use flat shading for speed
glShadeModel(GL_FLAT);
glColorMask(0, 0, 0, 0);
//Draw the scene
renderObjects();

//Read the depth buffer into the shadow map texture
glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, shadowMapSize, shadowMapSize);

//restore states
glCullFace(GL_BACK);
glShadeModel(GL_SMOOTH);
glColorMask(1, 1, 1, 1);


//2nd pass - Draw from camera's point of view
glClear(GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadMatrixf(cameraProjectionMatrix);

glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(cameraViewMatrix);

glViewport(0, 0, windowWidth, windowHeight);

//Use dim light to represent shadowed areas
glLightfv(GL_LIGHT1, GL_POSITION, VECTOR4D(lightPosition));
glLightfv(GL_LIGHT1, GL_AMBIENT, white*0.2f);
glLightfv(GL_LIGHT1, GL_DIFFUSE, white*0.2f);
glLightfv(GL_LIGHT1, GL_SPECULAR, black);
glEnable(GL_LIGHT1);
glEnable(GL_LIGHTING);

renderObjects();

由于您使用的是固定函数管道,因此我假设您使用的是纹理矩阵(每个纹理图像单元状态)

当您尝试从常规纹理采样时,是否确定纹理矩阵设置正确?在我看来,您使用的漫反射纹理矩阵与阴影贴图使用的矩阵相同。通常,在对除阴影贴图之外的所有对象进行采样时,都需要标识矩阵

考虑下面的例子: 在本例中,第二次绘制仍然受到必须为阴影贴图加载的矩阵的影响。您可以通过两种方式解决此问题:

  • 使用纹理图像单元对阴影贴图进行采样
  • 应用阴影贴图后,推/弹出或加载标识纹理矩阵

  • 什么是漫反射纹理?在进行第一次/第二次渲染时,我不会渲染纹理。只有第三步是加载它们,然后在对象上绑定和渲染它们。在注释中解释太多的工作,所以我用一些伪代码编写了一个答案。我添加了一些代码来向您展示我当前在最后渲染过程中所做的操作。当我加载标识矩阵时,我的照明会消失,尽管如此。@Gentatsu:我最初的假设是错误的。。。您正在使用基于纹理矩阵的
    glTexGen(…)
    。这是一个非常相似的概念,不过要解决这个问题,你需要在你的阴影通过后调用
    glDisable(GL\u TEXTURE\u GEN\u S)
    glDisable(GL\u TEXTURE\u GEN\u T)
    glDisable(GL\u TEXTURE\u GEN\u Q)
    。我只是注意到了一些事情。我的纹理一次只显示一部分纹理。嗯,这给了我回光,但现在我的阴影不显示了。在我现在渲染对象之前,我正在调用disable。@Gentatsu:实际上,这需要在
    renderObjects()
    中完成。我假设您刚才讨论的三个过程都是在该函数中完成的。第一遍需要启用纹理坐标生成,但第三遍(可能是第二遍)没有启用。如果您能展示
    renderObjects(…)
    的实现,那会有所帮助。
    void Widget::renderObjects()
    {
      glPushMatrix();
        glColor4f(1.0, 1.0, 1.0, 1.0);
        glPushMatrix();
          //glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emission); 
          //glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular); 
          arcBall->q.rotate();
          world->render();
          glPushMatrix();
            torso->frame = frame;
            torso->draw();
            glPushMatrix();
              renderParticles();
            glPopMatrix();
          glPopMatrix();
        glPopMatrix();
      glPopMatrix();
    }
    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    glMatrixMode(GL_MODELVIEW);
    lightPosition = VECTOR3D(lightX, lightY, lightZ);
    glLoadIdentity();
    gluLookAt(  lightPosition.x, lightPosition.y, lightPosition.z,
                0.0f, 0.0f, 0.0f,
                0.0f, 1.0f, 0.0f);
    glGetFloatv(GL_MODELVIEW_MATRIX, lightViewMatrix);
    
    
    
    
    glMatrixMode(GL_PROJECTION);
    glLoadMatrixf(lightProjectionMatrix);
    
    glMatrixMode(GL_MODELVIEW);
    glLoadMatrixf(lightViewMatrix);
    
    //Use viewport the same size as the shadow map
    glViewport(0, 0, shadowMapSize, shadowMapSize);
    
    //Draw back faces into the shadow map
    glCullFace(GL_FRONT);
    
    //Disable color writes, and use flat shading for speed
    glShadeModel(GL_FLAT);
    glColorMask(0, 0, 0, 0);
    //Draw the scene
    renderObjects();
    
    //Read the depth buffer into the shadow map texture
    glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, shadowMapSize, shadowMapSize);
    
    //restore states
    glCullFace(GL_BACK);
    glShadeModel(GL_SMOOTH);
    glColorMask(1, 1, 1, 1);
    
    
    //2nd pass - Draw from camera's point of view
    glClear(GL_DEPTH_BUFFER_BIT);
    
    glMatrixMode(GL_PROJECTION);
    glLoadMatrixf(cameraProjectionMatrix);
    
    glMatrixMode(GL_MODELVIEW);
    glLoadMatrixf(cameraViewMatrix);
    
    glViewport(0, 0, windowWidth, windowHeight);
    
    //Use dim light to represent shadowed areas
    glLightfv(GL_LIGHT1, GL_POSITION, VECTOR4D(lightPosition));
    glLightfv(GL_LIGHT1, GL_AMBIENT, white*0.2f);
    glLightfv(GL_LIGHT1, GL_DIFFUSE, white*0.2f);
    glLightfv(GL_LIGHT1, GL_SPECULAR, black);
    glEnable(GL_LIGHT1);
    glEnable(GL_LIGHTING);
    
    renderObjects();
    
    glActiveTexture (GL_TEXTURE0);
    glMatrixMode    (GL_TEXTURE);
    glLoadMatrixf   (shadow_matrix);
    
    glBindTexture   (shadow_map);
    
    // Draw shadow pass
    
    glBindTexture   (diffuse_map);
    
    // Draw the base diffuse pass