当前位置: 首页 > news >正文

将光源信息应用到立方体(一)

在接下来的博客中,我们还需要写一个shader的加载器,告别如下的形式:

const char *vertexShaderSource1 = "#version 330 core\n"
"layout (location=0) in vec3 aPos;\n"
"uniform mat4 model;\n"
"uniform mat4 view;\n"
"uniform mat4 projection;\n"
"void main()\n"
"{"
"     gl_Position = projection * view * model * vec4(aPos,1.0);\n"
"}\n";

告别这种创建、读取、编译shader的固定流程。

    int vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);

这里首先封装一个Shader类。
这里写图片描述

第一个函数:构造函数Shader(pram…),形式如下:
ID
参数解释一下,前面在可编程的渲染管线中,其中介绍哪些是可以编程的部分,一个是顶点着色器、一个是像素着色器、一个是几何着色器,而几何着色器所在的阶段是哪里呢?
这里写图片描述
是在图元组装阶段之后,它可以产生新的顶点,然后产生新的形状。比如上图中,在几何阶段,产生了新的顶点,然后图形中多了一个三角形。
一般这一步,我们很少去学习几何着色器,所以暂且放下,默认的指针为null。
接下来的就是有一个读文件的东西,然后从文件里面读出东西来,存放在一个字符串中去。
这里写图片描述
通过上一步操作,我们最终从文件里面读到了一个字符串vertexCode。
同理,又是同理,我们也能够获得fragment的字符串。如下所示:
这里写图片描述
有了这两个字符串vertexCode和fragmentCode之后,我们就可以创建shader程序进行连接和编译了。

下面我们以创建顶点着色器为例子,看看其如何进行操作的。
这里写图片描述

完整的shader代码如下:

#ifndef SHADER_H
#define SHADER_H

#include <glad/glad.h>
#include <glm/glm.hpp>

#include <string>
#include <fstream>
#include <sstream>
#include <iostream>

using namespace std;

class Shader
{
public:
    unsigned int ID;
    // constructor generates the shader on the fly
    // ------------------------------------------------------------------------
    Shader(const char* vertexPath, const char* fragmentPath, const char* geometryPath = nullptr)
    {
        string vertexCode;
        string fragmentCode;
        ifstream vShaderFile;
        ifstream fShaderFile;

        try
        {
            vShaderFile.open(vertexPath);
            fShaderFile.open(fragmentPath);
            stringstream vShaderStream, fShaderStream;
            vShaderStream << vShaderFile.rdbuf();
            fShaderStream << fShaderFile.rdbuf();

            vShaderFile.close();
            fShaderFile.close();

            vertexCode = vShaderStream.str();
            fragmentCode = fShaderStream.str();
        }
        catch (std::ifstream::failure ex)
        {
            cout << "load file occurs error!" << endl;
        }

        const char* vShaderCode = vertexCode.c_str();
        const char* fShaderCode = fragmentCode.c_str();

        unsigned int vertex, fragment;
        vertex = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertex, 1, &vShaderCode, NULL);
        glCompileShader(vertex);

        fragment = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragment, 1, &fShaderCode, NULL);
        glCompileShader(fragment);

        ID = glCreateProgram();
        glAttachShader(ID, vertex);
        glAttachShader(ID, fragment);
        glLinkProgram(ID);

        glDeleteShader(vertex);
        glDeleteShader(fragment);

    }
    // activate the shader
    // ------------------------------------------------------------------------
    void use()
    {
        glUseProgram(ID);
    }
    // utility uniform functions
    // ------------------------------------------------------------------------
    void setBool(const std::string &name, bool value) const
    {
        glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
    }
    // ------------------------------------------------------------------------
    void setInt(const std::string &name, int value) const
    {
        glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
    }
    // ------------------------------------------------------------------------
    void setFloat(const std::string &name, float value) const
    {
        glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
    }
    // ------------------------------------------------------------------------
    void setVec2(const std::string &name, const glm::vec2 &value) const
    {
        glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
    }
    void setVec2(const std::string &name, float x, float y) const
    {
        glUniform2f(glGetUniformLocation(ID, name.c_str()), x, y);
    }
    // ------------------------------------------------------------------------
    void setVec3(const std::string &name, const glm::vec3 &value) const
    {
        glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
    }
    void setVec3(const std::string &name, float x, float y, float z) const
    {
        glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z);
    }
    // ------------------------------------------------------------------------
    void setVec4(const std::string &name, const glm::vec4 &value) const
    {
        glUniform4fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
    }
    void setVec4(const std::string &name, float x, float y, float z, float w)
    {
        glUniform4f(glGetUniformLocation(ID, name.c_str()), x, y, z, w);
    }
    // ------------------------------------------------------------------------
    void setMat2(const std::string &name, const glm::mat2 &mat) const
    {
        glUniformMatrix2fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
    }
    // ------------------------------------------------------------------------
    void setMat3(const std::string &name, const glm::mat3 &mat) const
    {
        glUniformMatrix3fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
    }
    // ------------------------------------------------------------------------
    void setMat4(const std::string &name, const glm::mat4 &mat) const
    {
        glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
    }

private:
    // utility function for checking shader compilation/linking errors.
    // ------------------------------------------------------------------------
    void checkCompileErrors(GLuint shader, std::string type)
    {
        GLint success;
        GLchar infoLog[1024];
        if (type != "PROGRAM")
        {
            glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
            if (!success)
            {
                glGetShaderInfoLog(shader, 1024, NULL, infoLog);
                std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
            }
        }
        else
        {
            glGetProgramiv(shader, GL_LINK_STATUS, &success);
            if (!success)
            {
                glGetProgramInfoLog(shader, 1024, NULL, infoLog);
                std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
            }
        }
    }
};
#endif

然后此时测试代码:

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

using namespace std;

const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;

int main()
{
    //初始化和创建窗口
    glfwInit();
    GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);

    //设置
    glfwMakeContextCurrent(window);
    gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);


    //三角形的三个顶点数据
    float vertices[] = {
        -0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
        0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
        0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
        0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
        -0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f, 0.0f, 0.0f,

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

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

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

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

        -0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
        0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
        0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
        0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
        -0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
        -0.5f, 0.5f, -0.5f, 0.0f, 1.0f
    };

    glm::vec3 cubePosition[] = {
        glm::vec3(0.0f, 0.0f, 0.0f),
        glm::vec3(0.01f, 0.0f, 0.0f),
        glm::vec3(0.0f, 0.01f, 0.0f),
        glm::vec3(-0.01f, 0.0f, 0.0f),
    };

    unsigned int VBO, VAO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);

    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);

    Shader ourShader("vertex.vs", "fragment.fs");

    unsigned int texture1;
    glGenTextures(1, &texture1);
    glBindTexture(GL_TEXTURE_2D, texture1);

    stbi_set_flip_vertically_on_load(true);
    int width, height, nrChannels;
    unsigned char *data = stbi_load("timg.jpg", &width, &height, &nrChannels, 0);
    if (data)
    {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
    }
    else
    {
        std::cout << "Failed to load texture" << std::endl;
    }

    ourShader.use();
    ourShader.setInt("texture1",0);

    glEnable(GL_DEPTH_TEST);

    while (!glfwWindowShouldClose(window))
    {
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture1);

        ourShader.use();

        glm::mat4 view;
        glm::mat4 projection;
        projection = glm::perspective(glm::radians(45.0f), (float)800 / (float)600, 0.1f, 100.0f);
        view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));

        unsigned int transformLoc1 = glGetUniformLocation(ourShader.ID, "projection");
        glUniformMatrix4fv(transformLoc1, 1, GL_FALSE, glm::value_ptr(projection));

        unsigned int transformLoc2 = glGetUniformLocation(ourShader.ID, "view");
        glUniformMatrix4fv(transformLoc2, 1, GL_FALSE, glm::value_ptr(view));

        glBindVertexArray(VAO);

        for (int i = 0; i < 4; ++i)
        {
            glm::mat4 model;
            model = glm::translate(model, cubePosition[i]);
            model = glm::rotate(model, 20 * (float)glfwGetTime()*glm::radians(50.0f), glm::vec3(1.0f, 0.3f, 0.5f));
            unsigned int transformLoc3 = glGetUniformLocation(ourShader.ID, "model");
            glUniformMatrix4fv(transformLoc3, 1, GL_FALSE, glm::value_ptr(model));
            glDrawArrays(GL_TRIANGLES, 0, 36);
        }

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    return 0;
} 

下面是vertex.vs

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 inTexcoord;

out vec2 outTexcoord;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
   gl_Position = projection * view * model * vec4(aPos/200.0,1.0);
   outTexcoord = vec2(inTexcoord.x, inTexcoord.y);
};

fragment.fs

#version 330 core
out vec4 FragColor;
in vec2 outTexcoord;

uniform sampler2D texture1;

void main()
{
   FragColor = texture(texture1, outTexcoord);
}

运行结果,和之前的一样:
这里写图片描述

相关文章:

  • unity包内的内容读取
  • 栈和局部变量操作 将常量压入栈的指令
  • 将光源信息应用到立方体(二)
  • c++总结
  • DNS劫持
  • reflect vector
  • 113007
  • parallax mapping
  • 京东JData算法大赛高潜用户购买意向预测——复现(并没有),提供数据集
  • java 规范
  • 判定你的java应用是否正常(是否内存、线程泄漏)的一个简单方法
  • Java集合(本篇主要介绍List接口)
  • Shade4PointLights
  • 【笔记】Python集成开发环境——PyCharm 2018.3下载、注册、帮助文档
  • cocos2d lua 之骨骼动画
  • 《深入 React 技术栈》
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • Android单元测试 - 几个重要问题
  • co.js - 让异步代码同步化
  • Docker容器管理
  • download使用浅析
  • HomeBrew常规使用教程
  • iOS仿今日头条、壁纸应用、筛选分类、三方微博、颜色填充等源码
  • Java的Interrupt与线程中断
  • Laravel Telescope:优雅的应用调试工具
  • node.js
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • spring security oauth2 password授权模式
  • 当SetTimeout遇到了字符串
  • 对象引论
  • 如何用vue打造一个移动端音乐播放器
  • 使用Envoy 作Sidecar Proxy的微服务模式-4.Prometheus的指标收集
  • 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
  • 微服务框架lagom
  • 微信开源mars源码分析1—上层samples分析
  • 微信小程序:实现悬浮返回和分享按钮
  • 一天一个设计模式之JS实现——适配器模式
  • 原生JS动态加载JS、CSS文件及代码脚本
  • RDS-Mysql 物理备份恢复到本地数据库上
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • ###C语言程序设计-----C语言学习(3)#
  • ###C语言程序设计-----C语言学习(6)#
  • #stm32驱动外设模块总结w5500模块
  • $.ajax()方法详解
  • $L^p$ 调和函数恒为零
  • (10)工业界推荐系统-小红书推荐场景及内部实践【排序模型的特征】
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (libusb) usb口自动刷新
  • (编译到47%失败)to be deleted
  • (附源码)spring boot火车票售卖系统 毕业设计 211004
  • (附源码)springboot美食分享系统 毕业设计 612231
  • (三分钟)速览传统边缘检测算子
  • (一)RocketMQ初步认识
  • (转)es进行聚合操作时提示Fielddata is disabled on text fields by default
  • (转)Java socket中关闭IO流后,发生什么事?(以关闭输出流为例) .