当前位置:网站首页>OpenGL Chapter 9 lighting map

OpenGL Chapter 9 lighting map

2022-06-11 03:34:00 Carefree young heart

//LightingMaps
#include "Shader.h"
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>

void mouse_callback(GLFWwindow* window, double xpos, double ypos);
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
void processInput(GLFWwindow* window);

// settings
const unsigned int SCR_WIDTH = 800; // Define the size of screen space 
const unsigned int SCR_HEIGHT = 600;

// camera
glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f);
glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);

bool firstMouse = true;
float yaw = -90.0f;	//  Yaw is initialized to -90.0 degree , Because the yaw is 0.0 Will result in a direction vector pointing to the right , So we initially rotated a little to the left . 
float pitch = 0.0f; // Initialize pitch angle 
float lastX = 800.0f / 2.0;// In order to set the initial position as the center of the screen, take half the size of the screen space 
float lastY = 600.0 / 2.0;
float fov = 45.0f;// Initial field angle 

// timing
float deltaTime = 0.0f;	// time between current frame and last frame
float lastFrame = 0.0f;

//glm::vec3 lightPos(1.2f, 1.0f, 2.0f);

void processInput(GLFWwindow* window);
float vertices[] = {
    
    // positions // normals // texture coords
    -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f,  0.0f,
     0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f,  0.0f,
     0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f,  1.0f,
     0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f,  1.0f,
    -0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f,  1.0f,
    -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f,  0.0f,

    -0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f,  0.0f,  0.0f,
     0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f,  1.0f,  0.0f,
     0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f,  1.0f,  1.0f,
     0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f,  1.0f,  1.0f,
    -0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f,  0.0f,  1.0f,
    -0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f,  0.0f,  0.0f,

    -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  1.0f,  0.0f,
    -0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  1.0f,  1.0f,
    -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  0.0f,  1.0f,
    -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  0.0f,  1.0f,
    -0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  0.0f,  0.0f,
    -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  1.0f,  0.0f,

     0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f,  0.0f,
     0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  1.0f,  1.0f,
     0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  0.0f,  1.0f,
     0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  0.0f,  1.0f,
     0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  0.0f,  0.0f,
     0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f,  0.0f,

    -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  0.0f,  1.0f,
     0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  1.0f,  1.0f,
     0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  1.0f,  0.0f,
     0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  1.0f,  0.0f,
    -0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  0.0f,  0.0f,
    -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  0.0f,  1.0f,

    -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f,  1.0f,
     0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  1.0f,  1.0f,
     0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  1.0f,  0.0f,
     0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  1.0f,  0.0f,
    -0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  0.0f,  0.0f,
    -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f,  1.0f
};
// Define a vec3 Type array to store the displacement matrix 
glm::vec3 cubePositions[] = {
    
glm::vec3(0.0f,  0.0f,  0.0f),
glm::vec3(2.0f,  5.0f, -15.0f),
glm::vec3(-1.5f, -2.2f, -2.5f),
glm::vec3(-3.8f, -2.0f, -12.3f),
glm::vec3(2.4f, -0.4f, -3.5f),
glm::vec3(-1.7f,  3.0f, -7.5f),
glm::vec3(1.3f, -2.0f, -2.5f),
glm::vec3(1.5f,  2.0f, -2.5f),
glm::vec3(1.5f,  0.2f, -1.5f),
glm::vec3(-1.3f,  1.0f, -1.5f)
};
int main()
{
    
    //Glfw: Initialization and configuration 
    // ------------------------------
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

#ifdef __APPLE__
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif

    //glfw Window creation 
    // --------------------
    GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);// Use the size of the defined screen space 
    if (window == NULL)
    {
    
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);

    glfwSetCursorPosCallback(window, mouse_callback);
    glfwSetScrollCallback(window, scroll_callback);


    // First we have to tell GLFW, It should hide the cursor , And capture (Capture) it .
    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);

    // Load all OpenGL A function pointer 
    // ---------------------------------------
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
    
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }

    //  Configure global opengl state 
    // -----------------------------
    glEnable(GL_DEPTH_TEST);

    //  Build and compile our shader Program 
    // ------------------------------------
    Shader ourShader("shaderSampler.vs", "shaderSampler.fs");
    Shader modelShader("LightingMaps.vs", "LightingMaps.fs");
    Shader lightShader("lightShader.vs", "lightShader.fs");

    // Create and compile vertex data ( And buffer ), Configure vertex attributes  
    // ------------------------------------------------------------------

    unsigned int VBO, VAO,VAO2;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

 
    glBindVertexArray(VAO);
    // Location properties 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
  
    // Then in the vertex shader layout (location = 1) in vec3 aNormal;// tell GPU Location 1 Properties of 


    glGenVertexArrays(1, &VAO2);
    glBindVertexArray(VAO2);
    //glBindBuffer(GL_ARRAY_BUFFER, VBO);
    // Location properties 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    // Normal attributes 
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);

    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
    glEnableVertexAttribArray(2);

    //  Load and create a texture 
    // -------------------------
    unsigned int texture1, texture2;
    // texture 1
    // ---------
    glGenTextures(1, &texture1);
    glBindTexture(GL_TEXTURE_2D, texture1);
    //  Set the texture wrapping Parameters  
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    //  Set the texture filtering Parameters  
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    // Load image , Create textures and generate mipmaps // Multi level principle texture 
    int width, height, nrChannels;
    stbi_set_flip_vertically_on_load(true); //  tell stb_image.h stay y Flip the loaded texture on the axis .
                                            // Why do you need to flip Y The axis is because the starting position of the texture image is the upper right and the coordinates of our vertices (0,0) The point is lower left 
    unsigned char* data = stbi_load("container2.png", &width, &height, &nrChannels, 0);
    if (data)
    {
    
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
    }
    else
    {
    
        std::cout << "Failed to load texture" << std::endl;
    }
    stbi_image_free(data);
    // texture 2
    // ---------
    glGenTextures(1, &texture2);
    glBindTexture(GL_TEXTURE_2D, texture2);
    //  Set the texture wrapping Parameters 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    //  Set the texture filtering Parameters  
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    // load image, create texture and generate mipmaps
    //data = stbi_load(("aotu.jpg"), &width, &height, &nrChannels, 0);
    //data = stbi_load(("shanshui.jpg"), &width, &height, &nrChannels, 0);
    data = stbi_load(("container2_specular.png"), &width, &height, &nrChannels, 0);
    if (data)
    {
    
        // If there is no map, please give priority to this RGBA Medium alpha(A) passageway   If your map has alpha Please be sure to use RGBA Otherwise, the map cannot be displayed  
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
    }
    else
    {
    
        std::cout << "Failed to load texture" << std::endl;
    }
    stbi_image_free(data);

    //  Tell... For each sampler opengl Which texture unit does it belong to ( Just do it once ) 
    // -------------------------------------------------------------------------------------------
    modelShader.use();
    modelShader.setInt("material.diffuse", 0);
    modelShader.setInt("material.specular", 1);

   // ourShader.setVec3("lightPos", lightPos);
    // Render loop 
    // -----------
    while (!glfwWindowShouldClose(window))
    {
    
        float currentFrame = glfwGetTime();
        deltaTime = currentFrame - lastFrame;
        lastFrame = currentFrame;
        // -----
        processInput(window);

        //  Rendering 
        // ------
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //  Clears the color buffer of the previous frame   as well as   Depth test buffer 

        // bind textures on corresponding texture units
       

        // Activate shader 
        float angle = 20.0f * 0 * (float)glfwGetTime();// Give me a glfwGetTime Let the model rotate 

       
        glm::mat4 projection = glm::mat4(1.0f);
        glm::mat4 view = glm::mat4(1.0f);
        glm::mat4 model = glm::mat4(1.0f);
        glm::vec3 lightPos = glm::vec3(cubePositions[2]);// Light source location 
 
        ourShader.use();
        projection = glm::perspective(glm::radians(fov), 800.0f / 600.0f, 0.1f, 100.0f);// Projection matrix   Parameters : Viewport size , Screen aspect ratio , as well as near and far
        view = glm::lookAt(cameraPos, cameraPos+cameraFront, cameraUp);//lookAt matrix   Parameters : Camera position  , Observe the position of the target  , A vertical upward direction 
        model = glm::translate(model, cubePositions[0]);// Pass in the array to each new model, which has different displacement in world coordinates 
        model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));
        

        lightShader.use();
        lightPos.x = 1.0f + sin(glfwGetTime()) * 2.0f;
        lightPos.y = sin(glfwGetTime() / 2.0f) * 1.0f;
        model = glm::mat4(1.0f);
        model = glm::translate(model, lightPos);// Pass in the array to each new model, which has different displacement in world coordinates 
        angle = 20.0f * 2 * (float)glfwGetTime();// Give me a glfwGetTime Let the model rotate 
        model = glm::rotate(model, glm::radians(angle) * 0, glm::vec3(1.0f, 0.3f, 0.5f));
        lightShader.setMat4("model", model);
        lightShader.setMat4("projection", projection);
        lightShader.setMat4("view", view);
       
        glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLES, 0, 36);

        modelShader.use();        
        model = glm::mat4(1.0f);        
        model = glm::translate(model, cubePositions[0]);// Pass in the array to each new model, which has different displacement in world coordinates 
        angle = 20.0f * 1 * (float)glfwGetTime();// Give me a glfwGetTime Let the model rotate 
        model = glm::rotate(model, glm::radians(angle)*0, glm::vec3(1.0f, 0.5f, 0.5f));//rotate  Model location   Rotation angle   Rotation axis 
        modelShader.setMat4("model", model);// Set the model transformation matrix 
        modelShader.setMat4("projection", projection);// Set the projection change matrix 
        modelShader.setMat4("view", view);// Set the view change matrix 
        modelShader.setVec3("objectColor",1,0.5,0.5);// Set the color of the object 
        modelShader.setVec3("lightColor", 1, 1, 1);// Set the color of the light source. Of course, you can also set a uniform To set variables 
        modelShader.setVec3("lightPos", lightPos);// Set the light source position 
        modelShader.setVec3("viewPos", cameraPos);// Set the position of the camera to the viewing position 

        // Set each component of the material 
        //modelShader.setVec3("material.ambient", 1.0f, 0.5f, 0.31f);
       // modelShader.setVec3("material.diffuse", 1.0f, 0.5f, 0.31f);
        //modelShader.setVec3("material.specular", 0.5f, 0.5f, 0.5f);
        modelShader.setFloat("material.shininess", 32.0f);
       
        modelShader.setVec3("light.ambient", 1.0f, 1.0f, 1.0f);
        modelShader.setVec3("light.diffuse", 1.0f, 1.0f, 1.0f); //  Dim the light a little to match the scene 
        modelShader.setVec3("light.specular", 1.0f, 1.0f, 1.0f);
        modelShader.setVec3("light.position", lightPos);
        glm::vec3 lightColor;
        lightColor.x = sin(glfwGetTime() * 2.0f);
        lightColor.y = sin(glfwGetTime() * 0.7f);
        lightColor.z = sin(glfwGetTime() * 1.3f);

        glm::vec3 diffuseColor = lightColor * glm::vec3(0.5f); //  Reduce the impact 
        glm::vec3 ambientColor = diffuseColor * glm::vec3(0.2f); //  Very low impact 

        modelShader.setVec3("light.ambient", ambientColor);
        modelShader.setVec3("light.diffuse", diffuseColor);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture1);
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, texture2);

        glBindVertexArray(VAO2);
        glDrawArrays(GL_TRIANGLES, 0, 36);

  

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);

    glfwTerminate();
    return 0;
}


void processInput(GLFWwindow* window)
{
    
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);


    float cameraSpeed = 5.5f * deltaTime;; // adjust accordingly
    if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
        cameraPos += cameraSpeed * cameraFront;
    if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
        cameraPos -= cameraSpeed * cameraFront;
    if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
        cameraPos -= glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
    if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
        cameraPos += glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
    if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS)// Here is a space bar so that we can Y Move on the axis 
        cameraPos += cameraUp * cameraSpeed;

    //cameraPos.y = 0.0f;
    // You can do this by Y The vector in the direction is set to 0 Make him FPS This type of camera can only be used in XZ Move on the plane 

}

void mouse_callback(GLFWwindow* window, double xposIn, double yposIn)
{
    
    float xpos = static_cast<float>(xposIn);
    float ypos = static_cast<float>(yposIn);

    //  This bool The variable is initially set to true Of 
    // We need to set it as the center of the screen at the beginning 
    // If you don't do this   At the beginning of the program, it will call the callback function to point to the position of the screen when you enter the mouse 
    // So it's far from the center 
    if (firstMouse)
    {
    
        lastX = xpos;
        lastY = ypos;
        firstMouse = false;
    }

    // Then, in the mouse callback function, we calculate the offset of the mouse position between the current frame and the previous frame :
    float xoffset = xpos - lastX;
    float yoffset = lastY - ypos; // y The coordinates are from bottom to top  
    lastX = xpos;
    lastY = ypos;

    float sensitivity = 0.1f; // sensitivity This value can be set arbitrarily 
    xoffset *= sensitivity;
    yoffset *= sensitivity;

    yaw += xoffset;
    pitch += yoffset;

    //  To make sure the camera doesn't roll over 
    if (pitch > 89.0f)
        pitch = 89.0f;
    if (pitch < -89.0f)
        pitch = -89.0f;

    // stay xz Look at... On the plane Y Axis 
    // Here we only update y value , Observe carefully x and z The component is also affected . From the triangles, we can see that their value is equal to :
    //direction.x = cos(glm::radians(pitch));
    //direction.y = sin(glm::radians(pitch)); //  Notice that we first turn the angle into radians 
    //direction.z = cos(glm::radians(pitch));// here Y Axis updates do affect Z But I don't quite understand why it's directly equal to cos(pitch)
    // 
    //
    //
    // Here we only update y value , Observe carefully x and z The component is also affected . From the triangles, we can see that their value is equal to :
    //direction.x = cos(glm::radians(yaw));
    //direction.y =1 // Y unchanged 
    //direction.z = sin(glm::radians(yaw));
    // 
    // The following equation is equivalent to first completing the rotation transformation of the pitch angle and then multiplying it by the yaw angle 
    // Combine the above two steps 
    glm::vec3 front;
    front.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
    front.y = sin(glm::radians(pitch));
    front.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
    cameraFront = glm::normalize(front);
}

// glfw: whenever the mouse scroll wheel scrolls, this callback is called
// ----------------------------------------------------------------------
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
    
    //yoffset Is the direction in which our roller rolls vertically 
    if (fov >= 1.0f && fov <= 45.0f)
        fov -= yoffset;
    // Set a boundary for him   stay 1 To 45 Between 
    if (fov < 1.0f)
        fov = 1.0f;
    if (fov > 45.0f)
        fov = 45.0f;
}


//LightingMap.fs
#version 330 core
out vec4 FragColor;

struct Material {
    
    sampler2D diffuse;
    sampler2D specular;    
    float shininess;
}; 

struct Light {
    
    vec3 position;

    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};

in vec3 FragPos;  
in vec3 Normal;  
in vec2 TexCoords;
  
uniform vec3 viewPos;
uniform Material material;
uniform Light light;

void main()
{
    
    // ambient
    vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb;
  	
    // diffuse 
    vec3 norm = normalize(Normal);
    vec3 lightDir = normalize(light.position - FragPos);
    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb;  
    
    // specular
    vec3 viewDir = normalize(viewPos - FragPos);
    vec3 reflectDir = reflect(-lightDir, norm);  
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
    vec3 specular = light.specular * spec * texture(material.specular, TexCoords).rgb;  
        
    vec3 result = ambient + diffuse + specular;
    FragColor = vec4(result, 1.0);
} 
//LightingMap.vs
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;

out vec3 FragPos;
out vec3 Normal;
out vec2 TexCoords;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
    
    FragPos = vec3(model * vec4(aPos, 1.0));
    Normal = mat3(transpose(inverse(model))) * aNormal;  
    TexCoords = aTexCoords;
    
    gl_Position = projection * view * vec4(FragPos, 1.0);
}
原网站

版权声明
本文为[Carefree young heart]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/162/202206110324472965.html