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

OpenGL_Learn04

我这边并不是教程,只是学习记录,方便后面回顾,代码均是100%可以运行成功的。 

1. 渐变三角形

#include <glad/glad.h>
#include <GLFW/glfw3.h>#include <iostream>
#include <cmath>void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
"   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"uniform vec4 ourColor;\n"
"void main()\n"
"{\n"
"   FragColor = ourColor;\n"
"}\n\0";
int main() {//1.初始化配置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, GLFW_TRUE);
#endif // __APPLE__//2.gltf 窗口创建GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LeranOpenGL", NULL, NULL);if (window == NULL) {std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);//3. 加载所有GL函数指针if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {std::cout << "Failed to initialize GLAD" << std::endl;return -1;}//4. 构建和编译shader 程序//vertex shaderunsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);glCompileShader(vertexShader);int success;char infoLog[512];glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;}//fragment shaderunsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;}//link shadersunsigned int shaderProgram = glCreateProgram();glAttachShader(shaderProgram, vertexShader);glAttachShader(shaderProgram, fragmentShader);glLinkProgram(shaderProgram);// check for linking errorsglGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);if (!success) {glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;}glDeleteShader(vertexShader);glDeleteShader(fragmentShader);//4. 设置顶点数据float vertices[] = {0.5f, -0.5f, 0.0f,  // bottom right-0.5f, -0.5f, 0.0f,  // bottom left0.0f,  0.5f, 0.0f   // top };unsigned int VBO, VAO;glGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);glBindVertexArray(VAO);//复制顶点数组到缓冲区中供opengl使用glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//设置顶点属性指针glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);glEnableVertexAttribArray(0);glBindVertexArray(VAO);//5. 循环渲染while (!glfwWindowShouldClose(window)) {processInput(window);// renderglClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);//当我们渲染一个物体要使用着色器程序glUseProgram(shaderProgram);double timeValue = glfwGetTime();float greenValue = static_cast<float>(sin(timeValue) / 2.0 + 0.5);int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);glDrawArrays(GL_TRIANGLES, 0, 3);glfwSwapBuffers(window);glfwPollEvents();}glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glDeleteProgram(shaderProgram);glfwTerminate();return 0;}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow* window)
{if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)glfwSetWindowShouldClose(window, true);
}// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{// make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays.glViewport(0, 0, width, height);
}

 相比于渲染一个固定颜色的三角形,需要注意点:

而不是

const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"uniform vec4 ourColor;\n"
"void main()\n"
"{\n"
"   FragColor = ourColor;\n"
"}\n\0";

    //5. 循环渲染
    while (!glfwWindowShouldClose(window)) {
        processInput(window);

        // render
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        //当我们渲染一个物体要使用着色器程序
        glUseProgram(shaderProgram);
        double timeValue = glfwGetTime();
        float greenValue = static_cast<float>(sin(timeValue) / 2.0 + 0.5);
        int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");
        glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);

        glDrawArrays(GL_TRIANGLES, 0, 3);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

2、不同顶点渲染不同的颜色

#include <glad/glad.h>
#include <GLFW/glfw3.h>#include <iostream>
#include <cmath>void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;const char* vertexShaderSource = "#version 330 core\n""layout (location = 0) in vec3 aPos;\n"// 位置变量的属性位置值为 0 "layout (location = 1) in vec3 aColor;\n"// 颜色变量的属性位置值为 1"out vec3 ourColor;\n"// 向片段着色器输出一个颜色"void main()\n""{\n""   gl_Position = vec4(aPos, 1.0);\n""   ourColor = aColor;\n"// 将ourColor设置为我们从顶点数据那里得到的输入颜色"}\0";const char* fragmentShaderSource = "#version 330 core\n""out vec4 FragColor;\n""in vec3 ourColor;\n""void main()\n""{\n""   FragColor = vec4(ourColor, 1.0f);\n""}\n\0";int main() {//1.初始化配置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, GLFW_TRUE);
#endif // __APPLE__//2.gltf 窗口创建GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LeranOpenGL", NULL, NULL);if (window == NULL) {std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);//3. 加载所有GL函数指针if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {std::cout << "Failed to initialize GLAD" << std::endl;return -1;}//4. 构建和编译shader 程序//vertex shaderunsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);glCompileShader(vertexShader);int success;char infoLog[512];glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;}//fragment shaderunsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;}//link shadersunsigned int shaderProgram = glCreateProgram();glAttachShader(shaderProgram, vertexShader);glAttachShader(shaderProgram, fragmentShader);glLinkProgram(shaderProgram);// check for linking errorsglGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);if (!success) {glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;}glDeleteShader(vertexShader);glDeleteShader(fragmentShader);//4. 设置顶点数据float vertices[] = {// 位置              // 颜色0.5f, -0.5f, 0.0f,  1.0f, 0.0f, 0.0f,   // 右下-0.5f, -0.5f, 0.0f,  0.0f, 1.0f, 0.0f,   // 左下0.0f,  0.5f, 0.0f,  0.0f, 0.0f, 1.0f    // 顶部};unsigned int VBO, VAO;glGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);glBindVertexArray(VAO);//复制顶点数组到缓冲区中供opengl使用glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//设置顶点属性指针glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);glEnableVertexAttribArray(0);//设置颜色属性指针glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));glEnableVertexAttribArray(1);glBindVertexArray(VAO);//5. 循环渲染while (!glfwWindowShouldClose(window)) {processInput(window);// renderglClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);//当我们渲染一个物体要使用着色器程序glUseProgram(shaderProgram);glDrawArrays(GL_TRIANGLES, 0, 3);glfwSwapBuffers(window);glfwPollEvents();}glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glDeleteProgram(shaderProgram);glfwTerminate();return 0;}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow* window)
{if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)glfwSetWindowShouldClose(window, true);
}// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{// make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays.glViewport(0, 0, width, height);
}

写这些shaderSource的时候注意“;”,换行等

3、模块化绘制三角形

shader.h

#pragma once#include <glad/glad.h>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>class Shader {
public://程序IDunsigned int ID;//构造器读取并构建着色器Shader(const char* vertexPath, const char* fagmentPath) {std::string vertexCode;std::string fragmentCode;std::ifstream vShaderFile;std::ifstream fShaderFile;vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);try {vShaderFile.open(vertexPath);fShaderFile.open(fagmentPath);std::stringstream vShaderStream, fShaderStream;vShaderStream << vShaderFile.rdbuf();fShaderStream << fShaderFile.rdbuf();vShaderFile.close();fShaderFile.close();vertexCode = vShaderStream.str();fragmentCode = fShaderStream.str();}catch (std::ifstream::failure& e) {std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ: " << e.what() << std::endl;}const char* vShaderCode = vertexCode.c_str();const char* fShaderCode = fragmentCode.c_str();//2.complie shadersunsigned int vertex, fragment;//vertex shadervertex = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertex, 1, &vShaderCode, NULL);glCompileShader(vertex);checkCompileErros(vertex, "VERTEX");//fragment Shaderfragment = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragment, 1, &fShaderCode, NULL);glCompileShader(fragment);checkCompileErros(fragment, "FRAGMENT");//shader ProgramID = glCreateProgram();glAttachShader(ID, vertex);glAttachShader(ID, fragment);glLinkProgram(ID);checkCompileErros(ID, "PROGAM");glDeleteShader(vertex);glDeleteShader(fragment);}//使用/激活程序void use() {glUseProgram(ID);}//uniform工具函数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);}private:void checkCompileErros(unsigned int shader, std::string type) {int success;char 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;}}}
};

shader.vs

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;out vec3 ourColor;void main()
{gl_Position = vec4(aPos, 1.0);ourColor = aColor;
}

shader.fs

#version 330 core
out vec4 FragColor;in vec3 ourColor;void main()
{FragColor = vec4(ourColor, 1.0f);
}

main.cpp

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include "shader.h"
#include <iostream>void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;int main() {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);if (window == NULL){std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);// glad: load all OpenGL function pointers// ---------------------------------------if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){std::cout << "Failed to initialize GLAD" << std::endl;return -1;}//构建和编译Shader ourShader("./shader.vs", "./shader.fs");float vertices[] = {// positions         // colors0.5f, -0.5f, 0.0f,  1.0f, 0.0f, 0.0f,  // bottom right-0.5f, -0.5f, 0.0f,  0.0f, 1.0f, 0.0f,  // bottom left0.0f,  0.5f, 0.0f,  0.0f, 0.0f, 1.0f   // top };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, 6 * sizeof(float), (void*)0);glEnableVertexAttribArray(0);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3*sizeof(float)));glEnableVertexAttribArray(1);while (!glfwWindowShouldClose(window)){// input// -----processInput(window);// render// ------glClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);// render the triangleourShader.use();glBindVertexArray(VAO);glDrawArrays(GL_TRIANGLES, 0, 3);// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)// -------------------------------------------------------------------------------glfwSwapBuffers(window);glfwPollEvents();}glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glfwTerminate();return 0;
}// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow* window)
{if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)glfwSetWindowShouldClose(window, true);
}// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{// make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays.glViewport(0, 0, width, height);
}

 

着色器 - LearnOpenGL CN (learnopengl-cn.github.io)

http://www.lryc.cn/news/216053.html

相关文章:

  • 【嵌入式】HC32F07X CAN通讯配置和使用配置不同缓冲器以连续发送
  • Linux的常见指令(一)
  • Jenkins 参数动态获取目录里面的内容
  • centos 搭建内网ntp时间服务器
  • FreeRTOS-消息队列的使用
  • 喜欢 Android 14 的 14 个理由
  • 图解系列--路由器和它庞大的功能
  • DBeaver 23.2.3发布,带来多项增强和修复
  • Proteus仿真--基于51单片机的按键选播电子音乐(仿真文件+程序)
  • node使用http模块
  • Golang Study 进阶
  • Shopee买家通系统详细功能介绍
  • git生成gitee和github两个不同的公钥
  • 基于SSM的同学录网站
  • 第十五节——观察者watch
  • tauri 访问静态资源,响应头为Content-Type:‘text/html‘
  • 【佳学基因检测】Node.js中如何读取并调用内容
  • java根据音频流或者音频的地址获取分贝的工具类
  • Pycharm出现的一些问题和解决办法
  • 进程优先级(nice值,top指令),独立性,竞争性,进程切换(时间片),抢占与出让,并发并行概念
  • 若依微服务集成Mybatis-plus详细教程
  • WebSocket:实现实时双向通信的利器
  • 【uniapp】html和css-20231031
  • Docker Tomcat 搭建文件服务器
  • 无感刷新 token
  • 【MISRA C 2012】Rule 2.6 函数不应该包含未使用的标签声明
  • Ubuntu:使用apache2部署Vue开发的网站
  • 使用IO完成端口实现简单回显服务器
  • 【ROS】Nav2源码之nav2_behavior_tree详解
  • SpringBoot---myBatis数据库操作