介绍
首先需要GLFW和GLAD
GLFW:
opengl的C库
地址:链接: https://www.glfw.org/download.html.
.
GLAD:
用来简化调用的,这个需要对应GLFW版本去生成
地址:链接: https://glad.dav1d.de/.
工程内需要包含两个库
OpenGL32.Lib
glfw3.lib
初始化
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
...
glfwTerminate();
创建GLFW窗口
glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share);
//例
GLFWwindow* window = GLFWwindow* window = glfwCreateWindow(400, 300, "gl", NULL, NULL);
后边两个直接填NULL就好,暂时不用管
创建完后在调用下边函数将GLFW窗口上下文设置为当前上下文
glfwMakeContextCurrent(window);
初始化GLAD
if (gladLoadGLLoader((GLADloadproc)glfwGetProcAddress) == 0)
{
std::cout << "glfwGetProcAddress failed" << std::endl;
return;
}
CV就完事了
视口
说白了就是窗口内可见部分,在初始化GLAD后调用
//x y w h
glViewport(0, 0, 400, 300);
着色器
一个窗口至少要指定一个顶点着色器和一个片段着色器
//创建顶点着色器
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);//附加到对象
glCompileShader(vertexShader);//编译
glCreateShader 用来创建着色器
参数选择:
GL_VERTEX_SHADER //顶点
GL_FRAGMENT_SHADER //片段
然后通过glShaderSource将着色器代码附加到着色器上
再就通过glCompileShader编译该着色器
.
下边是判断着色器是否编译成功
//判断是否编译错误
int success;
char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (success == 0)
{
//编译定点着色器失败
glGetShaderInfoLog(vertexShader, sizeof(infoLog), NULL, infoLog);
std::cout << "编译顶点着色器失败: " << infoLog << std::endl;
}
glGetShaderiv 获取编译状态
glGetShaderInfoLog 获取错误信息
CV就行
链接着色器
//链接着色器
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
然后判断是否连接错误
//判断是否链接错误
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (success == 0)
{
glGetProgramInfoLog(shaderProgram, sizeof(infoLog), NULL, infoLog);
std::cout << "链接着色器失败: " << infoLog << std::endl;
}
最后可以删除着色器了
//删除着色器
glDeleteShader(fragmentShader);
glDeleteShader(vertexShader);
后边懒得写了
Demo
void t1()
{
//创建GLFW
GLFWwindow* window = glfwCreateWindow(400, 300, "gl", NULL, NULL);
if (window == NULL)
{
std::cout << "glfwCreateWindow failed" << std::endl;
return;
}
glfwMakeContextCurrent(window);
//窗口变动回调
glfwSetFramebufferSizeCallback(window, frame_buffer_size_cb);
//初始化GLAD
if (gladLoadGLLoader((GLADloadproc)glfwGetProcAddress) == 0)
{
std::cout << "glfwGetProcAddress failed" << std::endl;
return;
}
//视口
glViewport(0, 0, 400, 300);
//顶点着色器语言
const char* vertexShaderSource =
"#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"layout (location = 1) in vec4 aColor;\n"
"out vec4 vertexColor;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos, 1.0f);\n"
" vertexColor = vec4(0.0f, 0.0f, 1.0f, 1.0f);\n"
" vertexColor = aColor;\n"
"}\0";
//片段着色器语言
const char* fragmentShaderSource =
"#version 330 core\n"
"out vec4 FragColor;\n"
"in vec4 vertexColor;\n"
"uniform vec4 uniColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(1.0f, 0.5, 0.2f, 1.0f);\n"
" FragColor = vertexColor;\n"
//" FragColor = uniColor;\n"
"}\0";
//创建顶点着色器
GLuint 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 == 0)
{
//编译定点着色器失败
glGetShaderInfoLog(vertexShader, sizeof(infoLog), NULL, infoLog);
std::cout << "编译顶点着色器失败: " << infoLog << std::endl;
}
//创建片段着色器
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);//附加到对象
glCompileShader(fragmentShader);//编译
//判断是否编译错误
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (success == 0)
{
//编译定点着色器失败
glGetShaderInfoLog(fragmentShader, sizeof(infoLog), NULL, infoLog);
std::cout << "编译片段着色器失败: " << infoLog << std::endl;
}
//链接着色器
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
//判断是否链接错误
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (success == 0)
{
glGetProgramInfoLog(shaderProgram, sizeof(infoLog), NULL, infoLog);
std::cout << "链接着色器失败: " << infoLog << std::endl;
}
//删除着色器
glDeleteShader(fragmentShader);
glDeleteShader(vertexShader);
//顶点数据
float vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
float vertices2[] = {
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开始!
0, 1, 3, // 第一个三角形
1, 2, 3 // 第二个三角形
};
//顶点数据
float vertices3[] = {
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f
};
GLuint VAO, VBO, EBO;
//创建VAO VBO EBO
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
//首次绑定VAO
glBindVertexArray(VAO);
//顶点数组配置VBO中
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices3), vertices3, GL_STATIC_DRAW);
//顶点索引配置到EBO中
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
//glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
//设置顶点属性指针
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 7, NULL);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 7, (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
while (glfwWindowShouldClose(window) == false)
{
//获取按键
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
{
//设置窗口关闭
glfwSetWindowShouldClose(window, true);
}
//渲染
glClearColor(1.0f, 0.1f, 0.1f, 0.1f);
glClear(GL_COLOR_BUFFER_BIT);
//使用着色器程序
glUseProgram(shaderProgram);
//float timeValue = glfwGetTime();
//float greenValue = (sin(timeValue) / 2.0f) + 0.5f;
获取uniform位置
//int vertexColorLocation = glGetUniformLocation(shaderProgram, "uniColor");
//if (vertexColorLocation == -1)
//{
// std::cout << "glGetUniformLocation failed!" << std::endl;
//}
更新uniform
//glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);
//绑定VAO
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
//glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);
glBindVertexArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
//删除EBO VAO VBO 着色器程序
glDeleteBuffers(1, &EBO);
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(shaderProgram);
}
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
t3();
glfwTerminate();
return 0;
}
PS: 参考的learnopengl