2301_82107800 2024-06-08 23:39 采纳率: 0%
浏览 2

用OPENGL建立一个小车,没添加光照前可以渲染出来,添加光照和材质后,轮子可以渲染出来,但是车身不见了为什么

用OPENGL建立一个小车,没添加光照前可以渲染出来,添加光照和材质后,轮子可以渲染出来,但是车身不见了为什么?

  • 写回答

2条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-06-08 23:39
    关注

    引自免费微信小程序:皆我百晓生

    在OpenGL中,当添加光照和材质之后,物体可能因为光照计算、材质设置或者其他图形管线参数的原因而无法正确显示。为了找出问题所在,我们可以从以下几个方面进行排查:

    1. 检查光源位置和方向:确保光源的位置和方向是正确的,并且对模型有影响。
    2. 检查光照模式:确认使用的光照模式(如 ambient, diffuse, specular, 或者是它们的组合)是否正确。
    3. 检查材质属性:确保你为车身和轮子设置了不同的材质属性,比如颜色、反射率、透明度等。
    4. 检查深度缓冲:有时由于深度缓冲的问题,可能会导致一些部分被遮挡。确保深度测试是开启的,并且正确地配置了深度函数。
    5. 检查着色器:如果你使用的是着色器,确保顶点着色器和片段着色器中的光照计算逻辑没有错误。

    下面是一个基本的示例代码,展示了如何在OpenGL中创建一个简单的场景,包含一个带光照的小车。这个例子使用了现代OpenGL(也称为OpenGL Core Profile),并且假设你已经设置了窗口和上下文。我们将使用GLSL着色器处理光照。

    首先,我们需要创建一个简单的立方体作为车身,和两个圆柱体作为轮子。然后我们定义一个光源和材质属性。接着,我们将实现一个简单的Phong光照模型。

    #include <GL/glew.h>
    #include <GLFW/glfw3.h>
    #include <glm/glm.hpp>
    
    // ... (其他必要的头文件)
    
    const char* vertexShaderSource = R"(
    #version 330 core
    layout (location = 0) in vec3 aPos;
    uniform mat4 model;
    uniform mat4 view;
    uniform mat4 projection;
    
    out vec3 ourColor;
    
    void main()
    {
        gl_Position = projection * view * model * vec4(aPos, 1.0f);
        ourColor = vec3(1.0f, 0.5f, 0.2f); // 车身颜色
    }
    )";
    
    const char* fragmentShaderSource = R"(
    #version 330 core
    in vec3 ourColor;
    uniform vec3 lightPos;
    uniform vec3 objectColor;
    uniform vec3 ambientLight;
    uniform vec3 diffuseLight;
    uniform vec3 specularLight;
    uniform float shininess;
    uniform float constantAttenuation;
    uniform float linearAttenuation;
    uniform float quadraticAttenuation;
    
    out vec4 FragColor;
    
    void main()
    {
        vec3 norm = normalize(normalize(gl_NormalMatrix * gl_Normal));
        vec3 lightDir = normalize(lightPos - gl_ModelViewPosition);
        float diff = max(dot(norm, lightDir), 0.0);
        vec3 ambient = ambientLight * objectColor;
        vec3 diffuse = diff * diffuseLight * objectColor;
        vec3 spec = normalize(-lightDir);
        vec3 viewDir = normalize(-gl_ViewDirection);
        float specAngle = max(dot(norm, spec), 0.0);
        vec3 specular = pow(specAngle, shininess) * specularLight;
        
        vec3 result = (ambient + diffuse + specular) * constantAttenuation
                     + (diffuse + specular) * linearAttenuation * length(lightPos - gl_ModelViewPosition)
                     + specular * quadraticAttenuation * pow(length(lightPos - gl_ModelViewPosition), 2);
    
        FragColor = vec4(result, 1.0f);
    }
    )";
    
    int main()
    {
        // 初始化glfw并创建窗口
        // ...
    
        // 初始化GLEW
        glewInit();
    
        // 创建顶点数据
        // ...
        // 车身顶点数据
        GLfloat carVertices[] = {
            // ... (车身顶点坐标)
        };
        // 轮子顶点数据
        GLfloat wheelVertices[] = {
            // ... (轮子顶点坐标)
        };
    
        // ... (创建VAOs, VBOs, EBOs)
    
        // 编译并链接着色器
        // ...
    
        // 设置视口和投影矩阵
        // ...
    
        while (!glfwWindowShouldClose(window))
        {
            // 清除屏幕
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
            // 绘制车身
            glUseProgram(shaderProgram);
            glUniformMatrix4fv(modelLocation, 1, GL_FALSE, glm::value_ptr(glm::mat4(1.0)));
            glUniformMatrix4fv(viewLocation, 1, GL_FALSE, glm::value_ptr(camera.GetView()));
            glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, glm::value_ptr(projection));
    
            glBindVertexArray(carVAO);
            glDrawElements(GL_TRIANGLES, carIndices.size(), GL_UNSIGNED_INT, 0);
            glBindVertexArray(0);
    
            // 绘制轮子
            glUseProgram(shaderProgram);
            glUniformMatrix4fv(modelLocation, 1, GL_FALSE, glm::value_ptr(glm::translate(glm::vec3(1.0f, 0.5f, 0.0f))));
            glUniformMatrix4fv(viewLocation, 1, GL_FALSE, glm::value_ptr(camera.GetView()));
            glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, glm::value_ptr(projection));
    
            glBindVertexArray(wheelVAO);
            glDrawArrays(GL_TRIANGLES, 0, 36);
            glBindVertexArray(0);
    
            // 更新窗口
            glfwSwapBuffers(window);
            glfwPollEvents();
        }
    
        // 清理资源
        // ...
    
        return 0;
    }
    

    在这个示例中,我们使用了一个简单的Phong光照模型,它包括环境光、漫反射光和镜面高光。确保你已经在fragmentShaderSource中设置了正确的光源位置和材料属性。如果车身仍然不可见,请检查你的顶点数据和索引数组是否正确。同时,确保你在初始化时开启了深度测试。

    如果你还有问题,或者需要进一步的帮助,请提供更多的信息,例如你的具体代码段、错误消息以及你尝试过哪些调试步骤。这样我可以更准确地帮助你定位问题。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 6月8日

悬赏问题

  • ¥15 lvgl v8.2定时器提前到来
  • ¥15 qtcp 发送数据时偶尔会遇到发送数据失败?用的MSVC编译器(标签-qt|关键词-tcp)
  • ¥15 cam_lidar_calibration报错
  • ¥15 拓扑学,凸集,紧集。。
  • ¥15 如何扩大AIS数据容量
  • ¥15 单纯型python实现编译报错
  • ¥15 c++2013读写oracle
  • ¥15 c++ gmssl sm2验签demo
  • ¥15 关于模的完全剩余系(关键词-数学方法)
  • ¥15 有没有人懂这个博图程序怎么写,还要跟SFB连接,真的不会,求帮助