写在前面:最近闲来无事,学习OpenGL,在此记下代码,督促自己好好学习!
中文OpenGL学习网站:https://learnopengl-cn.github.io
一、画一个橘色的三角形
1.1代码
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
const unsigned int WIDTH = 800;
const unsigned int HEIGHT = 600;
void callbackFramebufferSize(GLFWwindow* vWindow,int vWidth,int vHeight)
{
glViewport(0, 0, vWidth, vHeight);
}
void processInput(GLFWwindow* vWindow)
{
if (glfwGetKey(vWindow, GLFW_KEY_ESCAPE) == GLFW_PRESS)
{
glfwSetWindowShouldClose(vWindow, true);
}
}
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"
"void main()\n"
"{\n"
" FragColor=vec4(1.0f,0.5f,0.2f,1.0f);\n"
"}\n\0";
int main()
{
//配置glfw
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//
GLFWwindow *Window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", NULL, NULL);
if (Window == NULL)
{
std::cout << "failed to create glfw window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(Window);
//窗口回调函数,当窗口发生变化的时候回调callbackFramebufferSize函数
glfwSetFramebufferSizeCallback(Window, callbackFramebufferSize);
//初始化glad
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "failed to initialize glad" << std::endl;
return -1;
}
//顶点着色器的编译
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;
}
//片段着色器的编译
int FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(FragmentShader, 1, &FragmentShaderSource, NULL);
glCompileShader(FragmentShader);
glGetShaderiv(FragmentShader, GL_COMPILE_STATUS, &Success);
if (!Success)
{
glGetShaderInfoLog(FragmentShader, 512, NULL, InfoLog);
std::cout << "error::shader::fragment::compilation failed\n" << InfoLog << std::endl;
}
//链接着色器程序
int ShaderProgram = glCreateProgram();
glAttachShader(ShaderProgram, VertexShader);
glAttachShader(ShaderProgram, FragmentShader);
glLinkProgram(ShaderProgram);
glGetProgramiv(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);
float Vertices[] =
{
-0.5f,-0.5f,0.0f,
0.5f,-0.5f,0.0f,
0.0f,0.5f,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, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
//开始渲染
while (!glfwWindowShouldClose(Window))
{
processInput(Window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(ShaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(Window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glfwTerminate();
return 0;
}
1.2结果
二、使用索引缓冲对象绘制橘色矩形
2.1代码
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
const unsigned int WIDTH = 800;
const unsigned int HEIGHT = 600;
void callbackFramebufferSize(GLFWwindow* vWindow,int vWidth,int vHeight)
{
glViewport(0, 0, vWidth, vHeight);
}
void processInput(GLFWwindow* vWindow)
{
if (glfwGetKey(vWindow, GLFW_KEY_ESCAPE) == GLFW_PRESS)
{
glfwSetWindowShouldClose(vWindow, true);
}
}
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"
"void main()\n"
"{\n"
" FragColor=vec4(1.0f,0.5f,0.2f,1.0f);\n"
"}\n\0";
//使用索引缓冲对象绘制一个橘色的矩形
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow *Window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", NULL, NULL);
if (Window == NULL)
{
std::cout << "failed to create glfw window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(Window);
glfwSetFramebufferSizeCallback(Window, callbackFramebufferSize);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "failed to initialize glad" << std::endl;
return -1;
}
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;
}
int FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(FragmentShader, 1, &FragmentShaderSource, NULL);
glCompileShader(FragmentShader);
glGetShaderiv(FragmentShader, GL_COMPILE_STATUS, &Success);
if (!Success)
{
glGetShaderInfoLog(FragmentShader, 512, NULL, InfoLog);
std::cout << "error::shader::fragment::compilation failed \n" << InfoLog << std::endl;
}
int ShaderProgram = glCreateProgram();
glAttachShader(ShaderProgram, VertexShader);
glAttachShader(ShaderProgram, FragmentShader);
glLinkProgram(ShaderProgram);
glGetProgramiv(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);
float Vertices[] =
{
0.5f,0.5f,0.0f,
0.5f,-0.5f,0.0f,
-0.5f,-0.5f,0.0f,
-0.5f,0.5f,0.0f
};
unsigned int Indices[] =
{
0,1,3,
1,2,3
};
//新建顶点顶点数组对象、顶点缓冲对象、索引缓冲对象
unsigned int VAO, VBO, EBO;
glGenVertexArrays(1,&VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
//先绑定顶点数组对象,然后绑定和设置顶点缓冲区,最后配置顶点属性
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindVertexArray(0);
while (!glfwWindowShouldClose(Window))
{
processInput(Window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(ShaderProgram);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(Window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
glfwTerminate();
return 0;
}
2.2结果
三、绘制两个彼此相连的橘色三角形
3.1代码
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
const unsigned int WIDTH = 800;
const unsigned int HEIGHT = 600;
void callbackFramebufferSize(GLFWwindow* vWindow,int vWidth,int vHeight)
{
glViewport(0, 0, vWidth, vHeight);
}
void processInput(GLFWwindow* vWindow)
{
if (glfwGetKey(vWindow, GLFW_KEY_ESCAPE) == GLFW_PRESS)
{
glfwSetWindowShouldClose(vWindow, true);
}
}
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"
"void main()\n"
"{\n"
" FragColor=vec4(1.0f,0.5f,0.2f,1.0f);\n"
"}\n\0";
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow *Window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", NULL, NULL);
if (Window == NULL)
{
std::cout << "failed to create glfw window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(Window);
glfwSetFramebufferSizeCallback(Window, callbackFramebufferSize);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "failed to initialize glad" << std::endl;
return -1;
}
int VertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(VertexShader, 1, &VertexShaderSource, NULL);
glCompileShader(VertexShader);
int FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(FragmentShader, 1, &FragmentShaderSource, NULL);
glCompileShader(FragmentShader);
int ShaderProgram = glCreateProgram();
glAttachShader(ShaderProgram, VertexShader);
glAttachShader(ShaderProgram, FragmentShader);
glLinkProgram(ShaderProgram);
glDeleteShader(VertexShader);
glDeleteShader(FragmentShader);
float Vertice[] =
{
0.0f,0.8f,0.0f,
0.0f,0.0f,0.0f,
-0.8f,0.0f,0.0f,
0.0f,0.4f,0.0f,
0.0f,0.0f,0.0f,
0.8f,0.0f,0.0f
};
unsigned int VAO, VBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertice), Vertice, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
while (!glfwWindowShouldClose(Window))
{
processInput(Window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(ShaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glfwSwapBuffers(Window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glfwTerminate();
return 0;
}
3.2 结果
四、创建两个相同的三角形,使用不同的VAO和VBO
4.1代码
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
const unsigned int WIDTH = 800;
const unsigned int HEIGHT = 600;
void callbackFramebufferSize(GLFWwindow* vWindow,int vWidth,int vHeight)
{
glViewport(0, 0, vWidth, vHeight);
}
void processInput(GLFWwindow* vWindow)
{
if (glfwGetKey(vWindow, GLFW_KEY_ESCAPE) == GLFW_PRESS)
{
glfwSetWindowShouldClose(vWindow, true);
}
}
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"
"void main()\n"
"{\n"
" FragColor=vec4(1.0f,0.5f,0.2f,1.0f);\n"
"}\n\0";
//创建相同的两个三角形,但对它们的数据使用不同的VAO和VBO
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow *Window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", NULL, NULL);
if (Window == NULL)
{
std::cout << "failed to create glfw window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(Window);
glfwSetFramebufferSizeCallback(Window, callbackFramebufferSize);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "failed to initialize glad" << std::endl;
return -1;
}
float Vertices1[] =
{
0.0f,0.5f,0.0f,
0.0f,0.0f,0.0f,
-0.5f,0.0f,0.0f
};
float Vertices2[]=
{
0.0f,0.5f,0.0f,
0.0f,0.0f,0.0f,
0.5f,0.0f,0.0f
};
unsigned int VAO[2], VBO[2];
glGenVertexArrays(2, VAO);
glGenBuffers(2, VBO);
glBindVertexArray(VAO[0]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindVertexArray(VAO[1]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
int VertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(VertexShader, 1, &VertexShaderSource, NULL);
glCompileShader(VertexShader);
int FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(FragmentShader, 1, &FragmentShaderSource, NULL);
glCompileShader(FragmentShader);
int ShaderProgram = glCreateProgram();
glAttachShader(ShaderProgram, VertexShader);
glAttachShader(ShaderProgram, FragmentShader);
glLinkProgram(ShaderProgram);
glDeleteShader(VertexShader);
glDeleteShader(FragmentShader);
while (!glfwWindowShouldClose(Window))
{
processInput(Window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(ShaderProgram);
glBindVertexArray(VAO[0]);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(VAO[1]);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(Window);
glfwPollEvents();
}
glDeleteVertexArrays(2, VAO);
glDeleteBuffers(2, VBO);
glfwTerminate();
return 0;
}
4.2结果
五、创建两个着色器程序,第二个程序使用一个不同的片段着色器,输出黄色;再次绘制这两个三角形,让其中一个输出为黄色
5.1代码
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
const unsigned int WIDTH = 800;
const unsigned int HEIGHT = 600;
void callbackFramebufferSize(GLFWwindow* vWindow,int vWidth,int vHeight)
{
glViewport(0, 0, vWidth, vHeight);
}
void processInput(GLFWwindow* vWindow)
{
if (glfwGetKey(vWindow, GLFW_KEY_ESCAPE) == GLFW_PRESS)
{
glfwSetWindowShouldClose(vWindow, true);
}
}
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"
"void main()\n"
"{\n"
" FragColor=vec4(1.0f,0.5f,0.2f,1.0f);\n"
"}\n\0";
const char *FragmentShaderSourceYe =
"#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor=vec4(1.0f,1.0f,0.0f,1.0f);\n"
"}\n\0";
//创建两个着色器程序,第二个程序使用一个不同的片段着色器,输出黄色;
//再次绘制这两个三角形,让其中一个输出为黄色
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow *Window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", NULL, NULL);
if (Window == NULL)
{
std::cout << "failed to create window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(Window);
glfwSetFramebufferSizeCallback(Window, callbackFramebufferSize);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "failed to initialize glad" << std::endl;
return -1;
}
int VertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(VertexShader, 1, &VertexShaderSource, NULL);
glCompileShader(VertexShader);
int FragmentShader1 = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(FragmentShader1, 1, &FragmentShaderSource, NULL);
glCompileShader(FragmentShader1);
int FragmentShader2 = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(FragmentShader2, 1, &FragmentShaderSourceYe, NULL);
glCompileShader(FragmentShader2);
int ShaderProgram1 = glCreateProgram();
glAttachShader(ShaderProgram1, VertexShader);
glAttachShader(ShaderProgram1, FragmentShader1);
glLinkProgram(ShaderProgram1);
int ShaderProgram2 = glCreateProgram();
glAttachShader(ShaderProgram2, VertexShader);
glAttachShader(ShaderProgram2, FragmentShader2);
glLinkProgram(ShaderProgram2);
glDeleteShader(VertexShader);
glDeleteShader(FragmentShader1);
glDeleteShader(FragmentShader2);
float Vertices1 []=
{
0.0f,0.5f,0.0f,
0.0f,0.0f,0.0f,
-0.5f,0.0f,0.0f
};
float Vertices2[] =
{
0.0f,0.5f,0.0f,
0.0f,0.0f,0.0f,
0.5f,0.0f,0.0f
};
unsigned int VAO[2], VBO[2];
glGenVertexArrays(2, VAO);
glGenBuffers(2, VBO);
glBindVertexArray(VAO[0]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices1), Vertices1, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindVertexArray(VAO[1]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
while (!glfwWindowShouldClose(Window))
{
processInput(Window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(ShaderProgram1);
glBindVertexArray(VAO[0]);
glDrawArrays(GL_TRIANGLES, 0, 3);
glUseProgram(ShaderProgram2);
glBindVertexArray(VAO[1]);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(Window);
glfwPollEvents();
}
glDeleteVertexArrays(2, VAO);
glDeleteBuffers(2, VBO);
glfwTerminate();
return 0;
}
5.2 结果
六、结语
第一课花费了好几天的学习,以后尽量做到一天学习一课。