OpenGL-- Shader 颜色 光照 3 光照贴图 LightMap

来源:互联网 发布:java 递归查找子节点 编辑:程序博客网 时间:2024/05/17 08:20

这里写图片描述

光照贴图

原理:
用一个图进行纹理贴图,另一张图用于纹理采样进行镜面光照计算

main.cpp

#include <iostream>#include <cmath>// GLEW#define GLEW_STATIC#include <GL/glew.h>// GLFW#include <GLFW/glfw3.h>// Other Libs#include <SOIL/SOIL.h>// GLM Mathematics#include <glm/glm.hpp>#include <glm/gtc/matrix_transform.hpp>#include <glm/gtc/type_ptr.hpp>// Other includes#include "Shader.h"#include "Camera.h"#pragma comment(lib, "./SOIL.lib")#pragma comment (lib, "opengl32.lib")#pragma comment (lib, "glew32s.lib")#pragma comment (lib, "glfw3.lib") #pragma comment (lib, "glfw3dll.lib") #pragma comment (lib, "glew32mxs.lib")// Function prototypesvoid key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);void mouse_callback(GLFWwindow* window, double xpos, double ypos);void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);void do_movement();// Window dimensionsconst GLuint WIDTH = 800, HEIGHT = 600;// CameraCamera  camera(glm::vec3(0.0f, 0.0f, 3.0f));GLfloat lastX = WIDTH / 2.0;GLfloat lastY = HEIGHT / 2.0;bool    keys[1024];// Light attributesglm::vec3 lightPos(1.2f, 1.0f, 2.0f);// DeltatimeGLfloat deltaTime = 0.0f;   // Time between current frame and last frameGLfloat lastFrame = 0.0f;   // Time of last frame// The MAIN function, from here we start the application and run the game loopint main(){    // Init GLFW    glfwInit();    // Set all the required options for GLFW    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);    // Create a GLFWwindow object that we can use for GLFW's functions    GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr);    glfwMakeContextCurrent(window);    // Set the required callback functions    glfwSetKeyCallback(window, key_callback);    glfwSetCursorPosCallback(window, mouse_callback);    glfwSetScrollCallback(window, scroll_callback);    // GLFW Options    //glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);    // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions    glewExperimental = GL_TRUE;    // Initialize GLEW to setup the OpenGL Function pointers    glewInit();    // Define the viewport dimensions    glViewport(0, 0, WIDTH, HEIGHT);    // OpenGL options    glEnable(GL_DEPTH_TEST);    // Set up vertex data (and buffer(s)) and attribute pointers    GLfloat 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    };    // First, set the container's VAO (and VBO)    GLuint VBO, containerVAO;    glGenVertexArrays(1, &containerVAO);    glGenBuffers(1, &VBO);    glBindBuffer(GL_ARRAY_BUFFER, VBO);    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);    glBindVertexArray(containerVAO);    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);    glEnableVertexAttribArray(0);    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));    glEnableVertexAttribArray(1);    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));    glEnableVertexAttribArray(2);    glBindVertexArray(0);    // Then, we set the light's VAO (VBO stays the same. After all, the vertices are the same for the light object (also a 3D cube))    GLuint lightVAO;    glGenVertexArrays(1, &lightVAO);    glBindVertexArray(lightVAO);    // We only need to bind to the VBO (to link it with glVertexAttribPointer), no need to fill it; the VBO's data already contains all we need.    glBindBuffer(GL_ARRAY_BUFFER, VBO);    // Set the vertex attributes (only position data for the lamp))    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0); // Note that we skip over the other data in our buffer object (we don't need the normals/textures, only positions).    glEnableVertexAttribArray(0);    glBindVertexArray(0);    // Load textures    GLuint diffuseMap, specularMap;    glGenTextures(1, &diffuseMap);    glGenTextures(1, &specularMap);    int width, height;    unsigned char* image;    // Diffuse map    image = SOIL_load_image("./img/container.png", &width, &height, 0, SOIL_LOAD_RGB);    glBindTexture(GL_TEXTURE_2D, diffuseMap);    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);    glGenerateMipmap(GL_TEXTURE_2D);    SOIL_free_image_data(image);    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);    // Specular map    image = SOIL_load_image("./img/container_specular.png", &width, &height, 0, SOIL_LOAD_RGB);    glBindTexture(GL_TEXTURE_2D, specularMap);    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);    glGenerateMipmap(GL_TEXTURE_2D);    SOIL_free_image_data(image);    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);    //glBindTexture(GL_TEXTURE_2D, 0);    // Build and compile our shader program    Shader objShader("./shader/obj.vs", "./shader/obj.frag");    Shader lampShader("./shader/lamp.vs", "./shader/lamp.frag");    // Set texture units    objShader.useShaderPrograme();    glUniform1i(glGetUniformLocation(objShader.getPrograme(), "material.diffuse"), 0);    glUniform1i(glGetUniformLocation(objShader.getPrograme(), "material.specular"), 1);    while (!glfwWindowShouldClose(window))    {        // Calculate deltatime of current frame        GLfloat currentFrame = glfwGetTime();        deltaTime = currentFrame - lastFrame;        lastFrame = currentFrame;        glfwPollEvents();        do_movement();        // Clear the colorbuffer        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);        // Use cooresponding shader when setting uniforms/drawing objects        objShader.useShaderPrograme();        GLint lightPosLoc = glGetUniformLocation(objShader.getPrograme(), "light.position");        GLint viewPosLoc = glGetUniformLocation(objShader.getPrograme(), "viewPos");        glUniform3f(lightPosLoc, lightPos.x, lightPos.y, lightPos.z);        glUniform3f(viewPosLoc, camera.Position.x, camera.Position.y, camera.Position.z);        // Set lights properties        glUniform3f(glGetUniformLocation(objShader.getPrograme(), "light.ambient"), 0.2f, 0.2f, 0.2f);        glUniform3f(glGetUniformLocation(objShader.getPrograme(), "light.diffuse"), 0.5f, 0.5f, 0.5f);        glUniform3f(glGetUniformLocation(objShader.getPrograme(), "light.specular"), 1.0f, 1.0f, 1.0f);        // Set material properties        glUniform1f(glGetUniformLocation(objShader.getPrograme(), "material.shininess"), 32.0f);        // Create camera transformations        glm::mat4 view;        view = camera.GetViewMatrix();        glm::mat4 projection = glm::perspective(camera.Zoom, (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 100.0f);        // Get the uniform locations        GLint modelLoc = glGetUniformLocation(objShader.getPrograme(), "model");        GLint viewLoc = glGetUniformLocation(objShader.getPrograme(), "view");        GLint projLoc = glGetUniformLocation(objShader.getPrograme(), "projection");        // Pass the matrices to the shader        glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));        glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));        // Bind diffuse map        glActiveTexture(GL_TEXTURE0);        glBindTexture(GL_TEXTURE_2D, diffuseMap);        // Bind specular map        glActiveTexture(GL_TEXTURE1);        glBindTexture(GL_TEXTURE_2D, specularMap);        // Draw the container (using container's vertex attributes)        glBindVertexArray(containerVAO);        glm::mat4 model;        glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));        glDrawArrays(GL_TRIANGLES, 0, 36);        glBindVertexArray(0);        // Also draw the lamp object, again binding the appropriate shader        lampShader.useShaderPrograme();        // Get location objects for the matrices on the lamp shader (these could be different on a different shader)        modelLoc = glGetUniformLocation(lampShader.getPrograme(), "model");        viewLoc = glGetUniformLocation(lampShader.getPrograme(), "view");        projLoc = glGetUniformLocation(lampShader.getPrograme(), "projection");        // Set matrices        glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));        glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));        model = glm::mat4();        model = glm::translate(model, lightPos);        model = glm::scale(model, glm::vec3(0.2f)); // Make it a smaller cube        glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));        // Draw the light object (using light's vertex attributes)        glBindVertexArray(lightVAO);        glDrawArrays(GL_TRIANGLES, 0, 36);        glBindVertexArray(0);        // Swap the screen buffers        glfwSwapBuffers(window);    }    // Terminate GLFW, clearing any resources allocated by GLFW.    glfwTerminate();    return 0;}// Is called whenever a key is pressed/released via GLFWvoid key_callback(GLFWwindow* window, int key, int scancode, int action, int mode){    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)        glfwSetWindowShouldClose(window, GL_TRUE);    if (key >= 0 && key < 1024)    {        if (action == GLFW_PRESS)            keys[key] = true;        else if (action == GLFW_RELEASE)            keys[key] = false;    }}void do_movement(){    // Camera controls    if (keys[GLFW_KEY_W])        camera.ProcessKeyboard(FORWARD, deltaTime);    if (keys[GLFW_KEY_S])        camera.ProcessKeyboard(BACKWARD, deltaTime);    if (keys[GLFW_KEY_A])        camera.ProcessKeyboard(LEFT, deltaTime);    if (keys[GLFW_KEY_D])        camera.ProcessKeyboard(RIGHT, deltaTime);    if (keys[GLFW_KEY_I])        lightPos.y += 0.1f;    if (keys[GLFW_KEY_K])        lightPos.y -= 0.1f;    if (keys[GLFW_KEY_J])        lightPos.x -= 0.1f;    if (keys[GLFW_KEY_L])        lightPos.x += 0.1f;    if (keys[GLFW_KEY_O])    {        glm::vec3 lightPosRst(1.2f, 1.0f, 2.0f);        lightPos = lightPosRst;    }}bool firstMouse = true;void mouse_callback(GLFWwindow* window, double xpos, double ypos){    if (firstMouse)    {        lastX = xpos;        lastY = ypos;        firstMouse = false;    }    GLfloat xoffset = xpos - lastX;    GLfloat yoffset = lastY - ypos;  // Reversed since y-coordinates go from bottom to left    lastX = xpos;    lastY = ypos;    camera.ProcessMouseMovement(xoffset, yoffset);}void scroll_callback(GLFWwindow* window, double xoffset, double yoffset){    camera.ProcessMouseScroll(yoffset);}

Camera.h

//Camera.h #pragma once// Std. Includes#include <vector>// GL Includes#include <GL/glew.h>#include <glm/glm.hpp>#include <glm/gtc/matrix_transform.hpp>// 摄像机移动方向  程序中用WSAD控制enum Camera_Movement {    FORWARD,    BACKWARD,    LEFT,    RIGHT};// Default camera valuesconst GLfloat YAW = -90.0f;const GLfloat PITCH = 0.0f;const GLfloat SPEED = 3.0f;const GLfloat SENSITIVTY = 0.25f;const GLfloat ZOOM = 45.0f;class Camera{public:    // Camera Attributes    glm::vec3 Position;    glm::vec3 Front;    glm::vec3 Up;    glm::vec3 Right;    glm::vec3 WorldUp;    // Eular Angles    GLfloat Yaw;    GLfloat Pitch;    // Camera options    GLfloat MovementSpeed;    GLfloat MouseSensitivity;    GLfloat Zoom;    // Constructor with vectors    Camera(glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f),         glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), GLfloat yaw = YAW,         GLfloat pitch = PITCH) : Front(glm::vec3(0.0f, 0.0f, -1.0f)),         MovementSpeed(SPEED), MouseSensitivity(SENSITIVTY), Zoom(ZOOM)    {        this->Position = position;        this->WorldUp = up;        this->Yaw = yaw;        this->Pitch = pitch;        this->updateCameraVectors();    }    // Constructor with scalar values    Camera(GLfloat posX, GLfloat posY, GLfloat posZ, GLfloat upX, GLfloat upY,         GLfloat upZ, GLfloat yaw, GLfloat pitch) : Front(glm::vec3(0.0f, 0.0f, -1.0f)),         MovementSpeed(SPEED), MouseSensitivity(SENSITIVTY), Zoom(ZOOM)    {        this->Position = glm::vec3(posX, posY, posZ);        this->WorldUp = glm::vec3(upX, upY, upZ);        this->Yaw = yaw;        this->Pitch = pitch;        this->updateCameraVectors();    }    // Returns the view matrix calculated using Eular Angles and the LookAt Matrix    glm::mat4 GetViewMatrix()    {        return glm::lookAt(this->Position, this->Position + this->Front, this->Up);    }    // 按键处理    void ProcessKeyboard(Camera_Movement direction, GLfloat deltaTime)    {        GLfloat velocity = this->MovementSpeed * deltaTime;        if (direction == FORWARD)            this->Position += this->Front * velocity;        if (direction == BACKWARD)            this->Position -= this->Front * velocity;        if (direction == LEFT)            this->Position -= this->Right * velocity;        if (direction == RIGHT)            this->Position += this->Right * velocity;    }    // 鼠标移动处理    void ProcessMouseMovement(GLfloat xoffset, GLfloat yoffset,         GLboolean constrainPitch = true)    {        xoffset *= this->MouseSensitivity;        yoffset *= this->MouseSensitivity;        this->Yaw += xoffset;        this->Pitch += yoffset;        // Make sure that when pitch is out of bounds, screen doesn't get flipped        if (constrainPitch)        {            if (this->Pitch > 89.0f)                this->Pitch = 89.0f;            if (this->Pitch < -89.0f)                this->Pitch = -89.0f;        }        // Update Front, Right and Up Vectors using the updated Eular angles        this->updateCameraVectors();    }    // Processes input received from a mouse scroll-wheel event.     //      Only requires input on the vertical wheel-axis    void ProcessMouseScroll(GLfloat yoffset)    {        if (this->Zoom >= 1.0f && this->Zoom <= 45.0f)            this->Zoom -= yoffset;        if (this->Zoom <= 1.0f)            this->Zoom = 1.0f;        if (this->Zoom >= 45.0f)            this->Zoom = 45.0f;    }private:    // Calculates the front vector from the Camera's (updated) Eular Angles    void updateCameraVectors()    {        // Calculate the new Front vector        glm::vec3 front;        front.x = cos(glm::radians(this->Yaw)) * cos(glm::radians(this->Pitch));        front.y = sin(glm::radians(this->Pitch));        front.z = sin(glm::radians(this->Yaw)) * cos(glm::radians(this->Pitch));        this->Front = glm::normalize(front);        // Also re-calculate the Right and Up vector        // Normalize the vectors, because their length gets closer to 0 the more         //      you look up or down which results in slower movement.        this->Right = glm::normalize(glm::cross(this->Front, this->WorldUp));          this->Up = glm::normalize(glm::cross(this->Right, this->Front));    }};

Shader.h

//Shader.h #pragma once#ifndef TEXTURE_SHADER_H_#define TEXTURE_SHADER_H_#include <string>#include <fstream>#include <sstream>#include <iostream>#include <gl/glew.h>#include <string>#include <fstream>#include <sstream>#include <iostream>#include <GL/glew.h>class Shader{public:    Shader(const GLchar* vertexPath, const GLchar* fragmentPath);    ~Shader();public:    void useShaderPrograme();    GLuint getPrograme() {        return this->m_nProgram;    }private:    GLuint  m_nProgram;};Shader::Shader(const GLchar* vertexPath, const GLchar* fragmentPath){    std::string vertexCode;    std::string fragmentCode;    std::ifstream vertexShaderF;    std::ifstream fragementShaderF;    vertexShaderF.exceptions(std::ifstream::badbit);    fragementShaderF.exceptions(std::ifstream::badbit);    try    {        vertexShaderF.open(vertexPath);     // 打开文件        fragementShaderF.open(fragmentPath);        std::stringstream vertexShaderStream, fragementShaderStream;        vertexShaderStream << vertexShaderF.rdbuf();    // 读取文件至stringstream中        fragementShaderStream << fragementShaderF.rdbuf();        vertexShaderF.close();        fragementShaderF.close();        vertexCode = vertexShaderStream.str();      // 转换成string类型        fragmentCode = fragementShaderStream.str();    }    catch (std::ifstream::failure e)    {        std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ:" << std::endl;    }    const GLchar* pVertexCode = vertexCode.c_str(); // string 转 char*    const GLchar* pFragementCode = fragmentCode.c_str();    GLuint nVertexShader, nFragementShader;    GLint nRes = 0;    GLchar chLogInfo[512] = { '\0' };    // 创建顶点着色器    nVertexShader = glCreateShader(GL_VERTEX_SHADER);    // 将顶点着色程序的源代码字符数组绑定到顶点着色器对象    glShaderSource(nVertexShader, 1, &pVertexCode, nullptr);    glCompileShader(nVertexShader); // compile shader 编译着色器    // 获取编译结果    glGetShaderiv(nVertexShader, GL_COMPILE_STATUS, &nRes);    if (!nRes)    {        glGetShaderInfoLog(nVertexShader, 512, nullptr, chLogInfo);        std::cout << "ERROR::SHADEF::VERTEX::COMPILATION_FAILED:" << chLogInfo << std::endl;    }    // 创建片断着色器    nFragementShader = glCreateShader(GL_FRAGMENT_SHADER);    // 将片段着色程序的源代码字符数组绑定到片段着色器对象    glShaderSource(nFragementShader, 1, &pFragementCode, nullptr);    glCompileShader(nFragementShader);    glGetShaderiv(nFragementShader, GL_COMPILE_STATUS, &nRes);    if (!nRes)    {        glGetShaderInfoLog(nFragementShader, 512, nullptr, chLogInfo);        std::cout << "ERROR::SHADEF::FRAGEMENT::COMPILATION_FAILED:" << chLogInfo << std::endl;    }    this->m_nProgram = glCreateProgram();   // 创建GLSL程序    glAttachShader(this->m_nProgram, nVertexShader);    // 绑定shader到program    glAttachShader(this->m_nProgram, nFragementShader);    // glLinkProgram操作产生最后的可执行程序,它包含最后可以在硬件上执行的硬件指令    glLinkProgram(this->m_nProgram);        // 链接    glGetProgramiv(this->m_nProgram, GL_LINK_STATUS, &nRes);    if (!nRes)    {        glGetProgramInfoLog(this->m_nProgram, 512, nullptr, chLogInfo);        std::cout << "ERROR::SHADEF::FRAGEMENT::LINK_FAILED:" << chLogInfo << std::endl;    }    glDeleteShader(nVertexShader);    glDeleteShader(nFragementShader);}Shader::~Shader(){}#include <glm/glm.hpp>#include <glm/gtc/matrix_transform.hpp>#include <glm/gtc/type_ptr.hpp>void Shader::useShaderPrograme(){    glUseProgram(this->m_nProgram); // 使用porgram}#endif

Shader部分


obj.vs

#version 330 corelayout (location = 0) in vec3 position;layout (location = 1) in vec3 normal;layout (location = 2) in vec2 texCoords;out vec3 Normal;out vec3 FragPos;out vec2 TexCoords;uniform mat4 model;uniform mat4 view;uniform mat4 projection;void main(){    gl_Position = projection * view *  model * vec4(position, 1.0f);    FragPos = vec3(model * vec4(position, 1.0f));    Normal = mat3(transpose(inverse(model))) * normal;      TexCoords = texCoords;} 

obj.frag

#version 330 corestruct 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;out vec4 color;uniform vec3 viewPos;uniform Material material;uniform Light light;void main(){    // Ambient    vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));    // Diffuse     vec3 norm = normalize(Normal);    vec3 lightDir = normalize(light.position - FragPos);    float diff = max(dot(norm, lightDir), 0.0);    vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));      // 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 * vec3(texture(material.specular, TexCoords));    color = vec4(ambient + diffuse + specular, 1.0f);  } 

lamp.vs

#version 330 corelayout (location = 0) in vec3 position;uniform mat4 model;uniform mat4 projection;void main(){    gl_Position = projection * model * vec4(position, 1.0f);} 

lamp.frag

#version 330 coreout vec4 color;void main(){       color = vec4(1.0f, 1.0f, 1.0f, 1.0f);} 

源码: VS2015
http://download.csdn.net/detail/yulinxx/9851467

原创粉丝点击