当前位置:网站首页>OpenGL learning (V) modern OpenGL triangle rendering
OpenGL learning (V) modern OpenGL triangle rendering
2022-07-24 18:46:00 【Pony Baby】
And traditional opengl comparison , The main difference is the need for handwriting shaders , See this article specifically Add link description
Below is my Chinese annotated version
hold shader write in main in
#include <iostream>
// GLEW
#define GLEW_STATIC // Linking static libraries requires macro definitions
#include <GL/glew.h>
// GLFW
#include <GLFW/glfw3.h>
// Window size
const int Width = 800, Height = 600;
// When the user presses ESC key , We set up window Window WindowShouldClose The attribute is true, close applications
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
// Shaders
const GLchar* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 position;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(position.x, position.y, position.z, 1.0);\n"
"}\0";
const GLchar* fragmentShaderSource = "#version 330 core\n"
"out vec4 color;\n"
"void main()\n"
"{\n"
"color = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0";
int main(int argc, char** argv)
{
// Init GLFW
glfwInit();
// Set up opengl Basic settings
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);// The highest version
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);// Minimum version
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//Core file
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);// You cannot resize the window
// create a window
GLFWwindow* window = glfwCreateWindow(Width, Height, "A Triangle", nullptr, nullptr);
glfwMakeContextCurrent(window);
// Bind key callback function
glfwSetKeyCallback(window, key_callback);
// Turn on modern opengl
glewExperimental = GL_TRUE;
// initialization glew(modern opengl)
glewInit();
// Set window size
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
// Vertex shader
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
// Bind source file , The first shader created , The second is how many are bound glsl, The third is glsl Source file
// The last one is how many characters each segment occupies , Because it's just a file , So you can leave it blank
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
// Compiling shader objects
glCompileShader(vertexShader);
// Handle error
// Because shaders are likely to be written incorrectly , And shaders go wrong log Manual output is required
GLint success;
GLchar 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 shader
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
// Check for compile time errors
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 shaders
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
// Check for linking errors
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
}
// Delete shader object
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
// The vertices buffer
GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
// VAO:Vertex Array Object
// It's actually an index , Because there may be many different VBO, If it is too troublesome to generate an index for each
// VBO:vertex buffer object
// Every vertex Specific data
GLuint VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
// binding VAO
glBindVertexArray(VAO);
// binding VBO
glBindBuffer(GL_ARRAY_BUFFER, VBO);
// Bound array
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// determine VAO Specific parameters
// The first parameter is in the shader layout, That is, which attribute in the shader this array corresponds to
// The second parameter is to specify the vertex attribute size , Three numbers representing a vertex vec3
// The third parameter is the data type
// The fourth parameter determines whether the data is mapped to 0-1 Between
// The fifth parameter is the step size , Represents the next data byte after
// The sixth data is the offset , That is, the starting position of the array
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
// Turn on VAO, Parameter is index, This index In fact, it is bound VBO Of layout
glEnableVertexAttribArray(0);
// I think so VAO Have gone through VBO The binding , Only after replacement VBO When you need to change the tie
glBindBuffer(GL_ARRAY_BUFFER,0); // Note that this is allowed, the call to glVertexAttribPointer registered VBO as the currently bound vertex buffer object so afterwards we can safely unbind
// Maybe something strange will happen when binding, causing an error , It is best to bind only when drawing
glBindVertexArray(0); // Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs)
// main loop
while (!glfwWindowShouldClose(window))
{
// Polling Events
glfwPollEvents();
// Clear color
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Use the compiled shader program
glUseProgram(shaderProgram);
// binding VAO
glBindVertexArray(VAO);
// Draw triangle , The second parameter is the starting position of the array , The third parameter is the number of fixed points
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
// double buffer
glfwSwapBuffers(window);
}
// Delete VAO and VBO
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
// Release window resources
glfwTerminate();
return 0;
}
Write an extra shader Class to help read shaders
main:
#include <iostream>
#include <shader.h>
// GLEW
#include <GL/glew.h>
// GLFW
#include <GLFW/glfw3.h>
// Window size
const int Width = 800, Height = 600;
// When the user presses ESC key , We set up window Window WindowShouldClose The attribute is true, close applications
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
int main(int argc, char** argv)
{
// Init GLFW
glfwInit();
// Set up opengl Basic settings
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);// The highest version
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);// Minimum version
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//Core file
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);// You cannot resize the window
// create a window
GLFWwindow* window = glfwCreateWindow(Width, Height, "A Triangle", nullptr, nullptr);
glfwMakeContextCurrent(window);
// Bind key callback function
glfwSetKeyCallback(window, key_callback);
// Turn on modern opengl
glewExperimental = GL_TRUE;
// initialization glew(modern opengl)
glewInit();
// Set window size
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
Shader ourShader("Shaders/shader.vert", "Shaders/shader.frag");
// The vertices buffer
GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
// VAO:Vertex Array Object
// It's actually an index , Because there may be many different VBO, If it is too troublesome to generate an index for each
// VBO:vertex buffer object
// Every vertex Specific data
GLuint VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
// binding VAO
glBindVertexArray(VAO);
// binding VBO
glBindBuffer(GL_ARRAY_BUFFER, VBO);
// Bound array
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// determine VAO Specific parameters
// The first parameter is in the shader layout, That is, which attribute in the shader this array corresponds to
// The second parameter is to specify the vertex attribute size , Three numbers representing a vertex vec3
// The third parameter is the data type
// The fourth parameter determines whether the data is mapped to 0-1 Between
// The fifth parameter is the step size , Represents the next data byte after
// The sixth data is the offset , That is, the starting position of the array
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
// Turn on VAO, Parameter is index, This index In fact, it is bound VBO Of layout
glEnableVertexAttribArray(0);
// I think so VAO Have gone through VBO The binding , Only after replacement VBO When you need to change the tie
glBindBuffer(GL_ARRAY_BUFFER, 0); // Note that this is allowed, the call to glVertexAttribPointer registered VBO as the currently bound vertex buffer object so afterwards we can safely unbind
// Maybe something strange will happen when binding, causing an error , It is best to bind only when drawing
glBindVertexArray(0); // Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs)
// main loop
while (!glfwWindowShouldClose(window))
{
// Polling Events
glfwPollEvents();
// Clear color
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Use the compiled shader program
ourShader.Use();
// binding VAO
glBindVertexArray(VAO);
// Draw triangle , The second parameter is the starting position of the array , The third parameter is the number of fixed points
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
// double buffer
glfwSwapBuffers(window);
}
// Delete VAO and VBO
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
// Release window resources
glfwTerminate();
return 0;
}
shader.vertx
#version 330 core
layout (location = 0) in vec3 position;
void main()
{
gl_Position = vec4(position.x, position.y, position.z, 1.0);
};
shader.frag
#version 330 core
out vec4 color;
void main()
{
color = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}
shader.h
#pragma once
#ifndef SHADER_H
#define SHADER_H
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <GL/glew.h>
class Shader
{
public:
GLuint Program;
// Constructor generates the shader on the fly
Shader(const GLchar* vertexPath, const GLchar* fragmentPath)
{
// 1. Retrieve the vertex/fragment source code from filePath
std::string vertexCode;
std::string fragmentCode;
std::ifstream vShaderFile;
std::ifstream fShaderFile;
// ensures ifstream objects can throw exceptions:
vShaderFile.exceptions(std::ifstream::badbit);
fShaderFile.exceptions(std::ifstream::badbit);
try
{
// Open files
vShaderFile.open(vertexPath);
fShaderFile.open(fragmentPath);
std::stringstream vShaderStream, fShaderStream;
// Read file's buffer contents into streams
vShaderStream << vShaderFile.rdbuf();
fShaderStream << fShaderFile.rdbuf();
// close file handlers
vShaderFile.close();
fShaderFile.close();
// Convert stream into string
vertexCode = vShaderStream.str();
fragmentCode = fShaderStream.str();
}
catch (std::ifstream::failure e)
{
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
}
const GLchar* vShaderCode = vertexCode.c_str();
const GLchar* fShaderCode = fragmentCode.c_str();
// 2. Compile shaders
GLuint vertex, fragment;
GLint success;
GLchar infoLog[512];
// Vertex Shader
vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &vShaderCode, NULL);
glCompileShader(vertex);
// Print compile errors if any
glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertex, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
// Fragment Shader
fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1, &fShaderCode, NULL);
glCompileShader(fragment);
// Print compile errors if any
glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragment, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
}
// Shader Program
this->Program = glCreateProgram();
glAttachShader(this->Program, vertex);
glAttachShader(this->Program, fragment);
glLinkProgram(this->Program);
// Print linking errors if any
glGetProgramiv(this->Program, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(this->Program, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
}
// Delete the shaders as they're linked into our program now and no longer necessery
glDeleteShader(vertex);
glDeleteShader(fragment);
}
// Uses the current shader
void Use()
{
glUseProgram(this->Program);
}
};
#endif
边栏推荐
- Ionic4 Learning Notes 6 -- using native ionic4 components in custom components
- leetcode-记忆化深搜/动态规划v2
- Type-C PD protocol chip while charging and listening
- 永恒之蓝MS17-010exp复现
- 使用der格式公钥生成publicKey报错
- core dump
- Typora user manual
- 全国职业院校技能大赛网络安全竞赛之数据分析数字取证-A
- Excel practice notes 1
- Ionic4 learning notes 5-- custom public module
猜你喜欢

Principle and application of database

4. Basic type and reference type?

QT - animation frame

OPENGL学习(三)GLUT二维图像绘制

微信小程序逆向

Easily learn pytoch transfer learning to realize surface defect inspection

全国职业院校技能大赛网络安全竞赛之数据分析数字取证-A

理解corners_align,两种看待像素的视角

Calling startActivity() from outside of an Activity context requires the FLAG_ ACTIVITY_ NEW_ TASK flag

32-bit stack overflow advanced
随机推荐
Go小白实现一个简易的go mock server
Latex数学公式
Add column by column selection for JTable
BUUCTF-pwn[1]
Easily learn pytoch transfer learning to realize surface defect inspection
SATA protocol OOB essay
04-分布式资源管理系统YARN
JS to achieve progress steps (small exercise)
ETL开发工具Kettle下载安装环境搭建及使用教程
FPGA 20个例程篇:9.DDR3内存颗粒初始化写入并通过RS232读取(下)
【TkInter】常用组件(一)
QT—动画框架
What are the benefits of knowledge management in enterprises?
Understand corners_ Align, two perspectives for viewing pixels
1. Typeof view variable type?
【历史上的今天】7 月 24 日:Caldera 诉微软案;AMD 宣布收购 ATI;谷歌推出 Chromecast
vim相关介绍
Vsftpd2.3.4-端口渗透 6200 irc_3281_backdoor
Excel practice notes 1
Escape character in JS?