OpenGL场景渲染失败?

问题描述 投票:0回答:1

我需要在 OpenGL 中创建一盏带有杆子和支架的灯。我需要对对象的每个顶点使用至少 2 个原始形状和不同的颜色。

由于某种原因,没有任何渲染。有什么问题吗?

这是我的源代码:

#include <iostream>
#include <vector>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

const char* vertexShaderSource = R"(
    #version 330 core
    layout (location = 0) in vec3 aPos;
    uniform mat4 model;
    out vec4 vertexColor;
    void main()
    {
        gl_Position = model * vec4(aPos, 1.0);
        vertexColor = vec4(1.0, 1.0, 0.0, 1.0); // Yellow color for the lamp
    }
)";

const char* fragmentShaderSource = R"(
    #version 330 core
    in vec4 vertexColor;
    out vec4 FragColor;
    void main()
    {
        FragColor = vertexColor;
    }
)";

const int sphereSegments = 32; // Number of horizontal segments
const int sphereRings = 16;    // Number of vertical rings
const float sphereRadius = 0.2f;
const float poleHeight = 1.5f;
const float poleRadius = 0.025f;
const int poleSegments = 20;
const float baseHeight = 0.1f;
const float baseRadius = 0.3f;
const int baseSegments = 30;
const float shadeRadius = 0.4f;
const float shadeHeight = 0.2f;

const float pi = glm::pi<float>();

void createSphere(std::vector<float>& vertices, std::vector<unsigned int>& indices, float radius, glm::vec4 color) {
    const float pi = glm::pi<float>();
    const float twoPi = 2.0f * pi;
    const float phiStep = pi / static_cast<float>(sphereRings);
    const float thetaStep = twoPi / static_cast<float>(sphereSegments);

    for (int ring = 0; ring <= sphereRings; ++ring) {
        const float phi = ring * phiStep;
        for (int segment = 0; segment <= sphereSegments; ++segment) {
            const float theta = segment * thetaStep;
            const float x = radius * sin(phi) * cos(theta);
            const float y = radius * cos(phi);
            const float z = radius * sin(phi) * sin(theta);
            vertices.push_back(x);
            vertices.push_back(y);
            vertices.push_back(z);
            // Color
            vertices.push_back(color.r);
            vertices.push_back(color.g);
            vertices.push_back(color.b);
            vertices.push_back(color.a);
        }
    }

    for (int ring = 0; ring < sphereRings; ++ring) {
        for (int segment = 0; segment < sphereSegments; ++segment) {
            const int currentRow = ring * (sphereSegments + 1);
            const int nextRow = (ring + 1) * (sphereSegments + 1);
            indices.push_back(currentRow + segment);
            indices.push_back(nextRow + segment);
            indices.push_back(nextRow + (segment + 1));
            indices.push_back(currentRow + segment);
            indices.push_back(nextRow + (segment + 1));
            indices.push_back(currentRow + (segment + 1));
        }
    }
}

void createCylinder(std::vector<float>& vertices, std::vector<unsigned int>& indices, float radius, float height, glm::vec4 color) {
    const float pi = glm::pi<float>();
    const float twoPi = 2.0f * pi;
    const float thetaStep = twoPi / static_cast<float>(sphereSegments);

    for (int segment = 0; segment <= sphereSegments; ++segment) {
        const float theta = segment * thetaStep;
        const float x = radius * cos(theta);
        const float z = radius * sin(theta);
        const float yTop = height / 2.0f;
        const float yBottom = -height / 2.0f;

        // Top vertex
        vertices.push_back(x);
        vertices.push_back(yTop);
        vertices.push_back(z);
        vertices.push_back(color.r);
        vertices.push_back(color.g);
        vertices.push_back(color.b);
        vertices.push_back(color.a);

        // Bottom vertex
        vertices.push_back(x);
        vertices.push_back(yBottom);
        vertices.push_back(z);
        vertices.push_back(color.r);
        vertices.push_back(color.g);
        vertices.push_back(color.b);
        vertices.push_back(color.a);

        if (segment > 0) {
            // Triangle 1 indices
            indices.push_back((segment - 1) * 2);
            indices.push_back(segment * 2);
            indices.push_back((segment - 1) * 2 + 1);

            // Triangle 2 indices
            indices.push_back((segment - 1) * 2 + 1);
            indices.push_back(segment * 2);
            indices.push_back(segment * 2 + 1);
        }
    }
}

int main() {
    if (!glfwInit()) {
        std::cerr << "Failed to initialize GLFW" << std::endl;
        return -1;
    }

    // GLFW window and GLEW initialization
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    GLFWwindow* window = glfwCreateWindow(800, 600, "Lamp 3D Model", nullptr, nullptr);
    if (!window) {
        std::cerr << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);

    if (glewInit() != GLEW_OK) {
        std::cerr << "Failed to initialize GLEW" << std::endl;
        return -1;
    }

    glEnable(GL_DEPTH_TEST);

    GLuint vertexShader, fragmentShader, shaderProgram;

    // Create and compile the vertex shader
    vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
    glCompileShader(vertexShader);

    // Check for vertex shader compilation errors
    int success;
    char infoLog[512];
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    if (!success) {
        glGetShaderInfoLog(vertexShader, 512, nullptr, infoLog);
        std::cerr << "Vertex shader compilation failed:\n" << infoLog << std::endl;
        return -1;
    }

    // Create and compile the fragment shader
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
    glCompileShader(fragmentShader);

    // Check for fragment shader compilation errors
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
    if (!success) {
        glGetShaderInfoLog(fragmentShader, 512, nullptr, infoLog);
        std::cerr << "Fragment shader compilation failed:\n" << infoLog << std::endl;
        return -1;
    }

    // Create a shader program and link the shaders
    shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);

    // Check for shader program linking errors
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    if (!success) {
        glGetProgramInfoLog(shaderProgram, 512, nullptr, infoLog);
        std::cerr << "Shader program linking failed:\n" << infoLog << std::endl;
        return -1;
    }

    glUseProgram(shaderProgram);

    // Define colors for lamp components
    glm::vec4 baseColor = glm::vec4(0.2f, 0.2f, 0.2f, 1.0f); // Gray
    glm::vec4 poleColor = glm::vec4(0.5f, 0.5f, 0.5f, 1.0f); // Gray
    glm::vec4 shadeColor = glm::vec4(1.0f, 1.0f, 0.0f, 1.0f); // Yellow

    // Create lamp components
    std::vector<float> baseVertices;
    std::vector<unsigned int> baseIndices;
    createSphere(baseVertices, baseIndices, baseRadius, baseColor);

    std::vector<float> poleVertices;
    std::vector<unsigned int> poleIndices;
    createCylinder(poleVertices, poleIndices, poleRadius, poleHeight, poleColor);

    std::vector<float> shadeVertices;
    std::vector<unsigned int> shadeIndices;
    createSphere(shadeVertices, shadeIndices, shadeRadius, shadeColor);

    GLuint baseVAO, baseVBO, baseEBO;
    GLuint poleVAO, poleVBO, poleEBO;
    GLuint shadeVAO, shadeVBO, shadeEBO;

    // Initialize base VAO, VBO, and EBO
    glGenVertexArrays(1, &baseVAO);
    glBindVertexArray(baseVAO);

    glGenBuffers(1, &baseVBO);
    glBindBuffer(GL_ARRAY_BUFFER, baseVBO);
    glBufferData(GL_ARRAY_BUFFER, baseVertices.size() * sizeof(float), &baseVertices[0], GL_STATIC_DRAW);

    glGenBuffers(1, &baseEBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, baseEBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, baseIndices.size() * sizeof(unsigned int), &baseIndices[0], GL_STATIC_DRAW);

    // Set vertex attribute pointers for base
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    // Initialize pole VAO, VBO, and EBO
    glGenVertexArrays(1, &poleVAO);
    glBindVertexArray(poleVAO);

    glGenBuffers(1, &poleVBO);
    glBindBuffer(GL_ARRAY_BUFFER, poleVBO);
    glBufferData(GL_ARRAY_BUFFER, poleVertices.size() * sizeof(float), &poleVertices[0], GL_STATIC_DRAW);

    glGenBuffers(1, &poleEBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, poleEBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, poleIndices.size() * sizeof(unsigned int), &poleIndices[0], GL_STATIC_DRAW);

    // Set vertex attribute pointers for pole
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    // Initialize shade VAO, VBO, and EBO
    glGenVertexArrays(1, &shadeVAO);
    glBindVertexArray(shadeVAO);

    glGenBuffers(1, &shadeVBO);
    glBindBuffer(GL_ARRAY_BUFFER, shadeVBO);
    glBufferData(GL_ARRAY_BUFFER, shadeVertices.size() * sizeof(float), &shadeVertices[0], GL_STATIC_DRAW);

    glGenBuffers(1, &shadeEBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, shadeEBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, shadeIndices.size() * sizeof(unsigned int), &shadeIndices[0], GL_STATIC_DRAW);

    // Set vertex attribute pointers for shade
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    // Rendering loop
    while (!glfwWindowShouldClose(window)) {
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glUseProgram(shaderProgram);

        // Set transformation matrices for the lamp components
        glm::mat4 model;

        // Base transformation
        model = glm::translate(model, glm::vec3(0.0f, -1.0f, 0.0f));
        glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, glm::value_ptr(model));
        glBindVertexArray(baseVAO);
        glDrawElements(GL_TRIANGLES, baseIndices.size(), GL_UNSIGNED_INT, 0);

        // Pole transformation
        model = glm::mat4(); // Reset model matrix
        model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f)); // Adjust position
        glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, glm::value_ptr(model));
        glBindVertexArray(poleVAO);
        glDrawElements(GL_TRIANGLES, poleIndices.size(), GL_UNSIGNED_INT, 0);

        // Shade transformation
        model = glm::mat4(); // Reset model matrix
        model = glm::translate(model, glm::vec3(0.0f, 1.0f, 0.0f)); // Adjust position
        glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, glm::value_ptr(model));
        glBindVertexArray(shadeVAO);
        glDrawElements(GL_TRIANGLES, shadeIndices.size(), GL_UNSIGNED_INT, 0);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    // Clean up and terminate GLFW
    glDeleteVertexArrays(1, &baseVAO);
    glDeleteBuffers(1, &baseVBO);
    glDeleteBuffers(1, &baseEBO);

    glDeleteVertexArrays(1, &poleVAO);
    glDeleteBuffers(1, &poleVBO);
    glDeleteBuffers(1, &poleEBO);

    glDeleteVertexArrays(1, &shadeVAO);
    glDeleteBuffers(1, &shadeVBO);
    glDeleteBuffers(1, &shadeEBO);

    glDeleteProgram(shaderProgram);

    glfwTerminate();

    return 0;
}
c++ opengl glsl glfw glm-math
1个回答
0
投票

几个问题:

  1. GLM 自 2018 年以来就没有默认初始化的东西,所以像

    glm::mat4 model;
    这样的东西会给你一个未初始化的,可能是垃圾矩阵。另外,像
    model = glm::mat4();
    这样的东西会给你一个 zero 矩阵,这也不是你想要启动转换管道的东西。

    使用

    glm::mat4 model = glm::mat4(1);
    获得单位矩阵

  2. createSphere()
    createCylinder()
    都为每个顶点发出 4 个浮点颜色,每个顶点总共 7 个浮点颜色。然而,所有
    glVertexAttribPointer()
    调用都要求 3 * sizeof(float)
    stride

    删除颜色数据或将stride切换为

    7 * sizeof(float)

一起(切换到GLAD,因为这就是我在我的系统上所做的事情):

#include <iostream>
#include <vector>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

const char* vertexShaderSource = R"(
    #version 330 core
    layout (location = 0) in vec3 aPos;
    uniform mat4 model;
    out vec4 vertexColor;
    void main()
    {
        gl_Position = model * vec4(aPos, 1.0);
        vertexColor = vec4(1.0, 1.0, 0.0, 1.0); // Yellow color for the lamp
    }
)";

const char* fragmentShaderSource = R"(
    #version 330 core
    in vec4 vertexColor;
    out vec4 FragColor;
    void main()
    {
        FragColor = vertexColor;
    }
)";

const int sphereSegments = 32; // Number of horizontal segments
const int sphereRings = 16;    // Number of vertical rings
const float sphereRadius = 0.2f;
const float poleHeight = 1.5f;
const float poleRadius = 0.025f;
const int poleSegments = 20;
const float baseHeight = 0.1f;
const float baseRadius = 0.3f;
const int baseSegments = 30;
const float shadeRadius = 0.4f;
const float shadeHeight = 0.2f;

const float pi = glm::pi<float>();

void createSphere(std::vector<float>& vertices, std::vector<unsigned int>& indices, float radius, glm::vec4 color) {
    const float pi = glm::pi<float>();
    const float twoPi = 2.0f * pi;
    const float phiStep = pi / static_cast<float>(sphereRings);
    const float thetaStep = twoPi / static_cast<float>(sphereSegments);

    for (int ring = 0; ring <= sphereRings; ++ring) {
        const float phi = ring * phiStep;
        for (int segment = 0; segment <= sphereSegments; ++segment) {
            const float theta = segment * thetaStep;
            const float x = radius * sin(phi) * cos(theta);
            const float y = radius * cos(phi);
            const float z = radius * sin(phi) * sin(theta);
            vertices.push_back(x);
            vertices.push_back(y);
            vertices.push_back(z);
            // Color
            vertices.push_back(color.r);
            vertices.push_back(color.g);
            vertices.push_back(color.b);
            vertices.push_back(color.a);
        }
    }

    for (int ring = 0; ring < sphereRings; ++ring) {
        for (int segment = 0; segment < sphereSegments; ++segment) {
            const int currentRow = ring * (sphereSegments + 1);
            const int nextRow = (ring + 1) * (sphereSegments + 1);
            indices.push_back(currentRow + segment);
            indices.push_back(nextRow + segment);
            indices.push_back(nextRow + (segment + 1));
            indices.push_back(currentRow + segment);
            indices.push_back(nextRow + (segment + 1));
            indices.push_back(currentRow + (segment + 1));
        }
    }
}

void createCylinder(std::vector<float>& vertices, std::vector<unsigned int>& indices, float radius, float height, glm::vec4 color) {
    const float pi = glm::pi<float>();
    const float twoPi = 2.0f * pi;
    const float thetaStep = twoPi / static_cast<float>(sphereSegments);

    for (int segment = 0; segment <= sphereSegments; ++segment) {
        const float theta = segment * thetaStep;
        const float x = radius * cos(theta);
        const float z = radius * sin(theta);
        const float yTop = height / 2.0f;
        const float yBottom = -height / 2.0f;

        // Top vertex
        vertices.push_back(x);
        vertices.push_back(yTop);
        vertices.push_back(z);
        vertices.push_back(color.r);
        vertices.push_back(color.g);
        vertices.push_back(color.b);
        vertices.push_back(color.a);

        // Bottom vertex
        vertices.push_back(x);
        vertices.push_back(yBottom);
        vertices.push_back(z);
        vertices.push_back(color.r);
        vertices.push_back(color.g);
        vertices.push_back(color.b);
        vertices.push_back(color.a);

        if (segment > 0) {
            // Triangle 1 indices
            indices.push_back((segment - 1) * 2);
            indices.push_back(segment * 2);
            indices.push_back((segment - 1) * 2 + 1);

            // Triangle 2 indices
            indices.push_back((segment - 1) * 2 + 1);
            indices.push_back(segment * 2);
            indices.push_back(segment * 2 + 1);
        }
    }
}

int main() {
    if (!glfwInit()) {
        std::cerr << "Failed to initialize GLFW" << std::endl;
        return -1;
    }

    // GLFW window and GLEW initialization
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    GLFWwindow* window = glfwCreateWindow(800, 600, "Lamp 3D Model", nullptr, nullptr);
    if (!window) {
        std::cerr << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);

    gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);

    glEnable(GL_DEPTH_TEST);

    GLuint vertexShader, fragmentShader, shaderProgram;

    // Create and compile the vertex shader
    vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
    glCompileShader(vertexShader);

    // Check for vertex shader compilation errors
    int success;
    char infoLog[512];
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    if (!success) {
        glGetShaderInfoLog(vertexShader, 512, nullptr, infoLog);
        std::cerr << "Vertex shader compilation failed:\n" << infoLog << std::endl;
        return -1;
    }

    // Create and compile the fragment shader
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
    glCompileShader(fragmentShader);

    // Check for fragment shader compilation errors
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
    if (!success) {
        glGetShaderInfoLog(fragmentShader, 512, nullptr, infoLog);
        std::cerr << "Fragment shader compilation failed:\n" << infoLog << std::endl;
        return -1;
    }

    // Create a shader program and link the shaders
    shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);

    // Check for shader program linking errors
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    if (!success) {
        glGetProgramInfoLog(shaderProgram, 512, nullptr, infoLog);
        std::cerr << "Shader program linking failed:\n" << infoLog << std::endl;
        return -1;
    }

    glUseProgram(shaderProgram);

    // Define colors for lamp components
    glm::vec4 baseColor = glm::vec4(0.2f, 0.2f, 0.2f, 1.0f); // Gray
    glm::vec4 poleColor = glm::vec4(0.5f, 0.5f, 0.5f, 1.0f); // Gray
    glm::vec4 shadeColor = glm::vec4(1.0f, 1.0f, 0.0f, 1.0f); // Yellow

    // Create lamp components
    std::vector<float> baseVertices;
    std::vector<unsigned int> baseIndices;
    createSphere(baseVertices, baseIndices, baseRadius, baseColor);

    std::vector<float> poleVertices;
    std::vector<unsigned int> poleIndices;
    createCylinder(poleVertices, poleIndices, poleRadius, poleHeight, poleColor);

    std::vector<float> shadeVertices;
    std::vector<unsigned int> shadeIndices;
    createSphere(shadeVertices, shadeIndices, shadeRadius, shadeColor);

    GLuint baseVAO, baseVBO, baseEBO;
    GLuint poleVAO, poleVBO, poleEBO;
    GLuint shadeVAO, shadeVBO, shadeEBO;

    // Initialize base VAO, VBO, and EBO
    glGenVertexArrays(1, &baseVAO);
    glBindVertexArray(baseVAO);

    glGenBuffers(1, &baseVBO);
    glBindBuffer(GL_ARRAY_BUFFER, baseVBO);
    glBufferData(GL_ARRAY_BUFFER, baseVertices.size() * sizeof(float), &baseVertices[0], GL_STATIC_DRAW);

    glGenBuffers(1, &baseEBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, baseEBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, baseIndices.size() * sizeof(unsigned int), &baseIndices[0], GL_STATIC_DRAW);

    // Set vertex attribute pointers for base
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    // Initialize pole VAO, VBO, and EBO
    glGenVertexArrays(1, &poleVAO);
    glBindVertexArray(poleVAO);

    glGenBuffers(1, &poleVBO);
    glBindBuffer(GL_ARRAY_BUFFER, poleVBO);
    glBufferData(GL_ARRAY_BUFFER, poleVertices.size() * sizeof(float), &poleVertices[0], GL_STATIC_DRAW);

    glGenBuffers(1, &poleEBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, poleEBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, poleIndices.size() * sizeof(unsigned int), &poleIndices[0], GL_STATIC_DRAW);

    // Set vertex attribute pointers for pole
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    // Initialize shade VAO, VBO, and EBO
    glGenVertexArrays(1, &shadeVAO);
    glBindVertexArray(shadeVAO);

    glGenBuffers(1, &shadeVBO);
    glBindBuffer(GL_ARRAY_BUFFER, shadeVBO);
    glBufferData(GL_ARRAY_BUFFER, shadeVertices.size() * sizeof(float), &shadeVertices[0], GL_STATIC_DRAW);

    glGenBuffers(1, &shadeEBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, shadeEBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, shadeIndices.size() * sizeof(unsigned int), &shadeIndices[0], GL_STATIC_DRAW);

    // Set vertex attribute pointers for shade
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    // Rendering loop
    while (!glfwWindowShouldClose(window)) {
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glUseProgram(shaderProgram);

        // Set transformation matrices for the lamp components
        glm::mat4 model = glm::mat4(1);

        // Base transformation
        model = glm::translate(model, glm::vec3(0.0f, -1.0f, 0.0f));
        glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, glm::value_ptr(model));
        glBindVertexArray(baseVAO);
        glDrawElements(GL_TRIANGLES, baseIndices.size(), GL_UNSIGNED_INT, 0);

        // Pole transformation
        model = glm::mat4(1); // Reset model matrix
        model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f)); // Adjust position
        glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, glm::value_ptr(model));
        glBindVertexArray(poleVAO);
        glDrawElements(GL_TRIANGLES, poleIndices.size(), GL_UNSIGNED_INT, 0);

        // Shade transformation
        model = glm::mat4(1); // Reset model matrix
        model = glm::translate(model, glm::vec3(0.0f, 1.0f, 0.0f)); // Adjust position
        glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, glm::value_ptr(model));
        glBindVertexArray(shadeVAO);
        glDrawElements(GL_TRIANGLES, shadeIndices.size(), GL_UNSIGNED_INT, 0);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    // Clean up and terminate GLFW
    glDeleteVertexArrays(1, &baseVAO);
    glDeleteBuffers(1, &baseVBO);
    glDeleteBuffers(1, &baseEBO);

    glDeleteVertexArrays(1, &poleVAO);
    glDeleteBuffers(1, &poleVBO);
    glDeleteBuffers(1, &poleEBO);

    glDeleteVertexArrays(1, &shadeVAO);
    glDeleteBuffers(1, &shadeVBO);
    glDeleteBuffers(1, &shadeEBO);

    glDeleteProgram(shaderProgram);

    glfwTerminate();

    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.