对于正常人好的教材、学习顺序不一定适合你,并且这概率真不低,原因可能是越复杂庞大的教材环节越多,每个环节都有一定概率破你防,所以你一定需要多个材料并且有重复看过
通用概念
-
render loop
-
graphic pipeline
-
shader
-
object
创建窗口
固定工作流暂且不论
#include<glad/glad.h>
#include<GLFW/glfw3.h>
#include<iostream>
void processInput(GLFWwindow*);
int main() {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//用GLFW创建的窗口是从glfwInit()初始化到glfwTerminate()中止。
//glfwWindowHint()用于设置所有窗口的属性,通过用宏作属性设置的标签进行,典型的C风格,和WinAPI也相似。
//这里称为Hint-Value风格。可以认为Hint的意思是提示信息、小标签等,后续步骤将要使用这些提示信息选择相应分支。
GLFWwindow* window = glfwCreateWindow(600, 800, "Learn", NULL, NULL);
if (window == NULL) {
std::cerr << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
//窗口创建。
//glfwMakeContextCurrent()使窗口在某线程中活跃,“设置当前的(current)环境(context)为window”。
//还有更好的解释:在执行该函数前,GLFW还没有一个current context。
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cerr << "Failed to initialize GLAD" << std::endl;
return -1;
}
//初始化GLAD后,才能正常使用任何OpenGL函数。
//或者说初始化了GLAD才能将接口从原来的OpenGL接口gl...转移到重新封装的接口glad_...。
glfwSetFramebufferSizeCallback(window,
[](GLFWwindow* window, int width, int height) {glViewport(0, 0, width, height); });
//视口创建,并完成能改变窗口大小的功能。
while (!glfwWindowShouldClose(window))
{
processInput(window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
glfwPollEvents();
}
//Render Loop。
//glfwWindowShouldClose()在窗口已经被指示关闭时返回0。
//glfwSwapBuffers()更新缓冲区,也称作color buffer。opengl默认双缓冲区。
//glfwPollEvents()是事件驱动模型的核心,从事件队列中取出事件并执行,执行依靠的是回调函数。
//C风格,回调机制。
glfwTerminate();
return 0;
//常规结束,整个程序从glfwInit()到glfwTerminate()。
//而窗口则从glfwCreateWindow()开始到glfwPollEvents()执行了退出的事件,并指示了窗口的关闭。
//或者认为在结束事件后,“window has been instructed close”。
//也就是说判断循环是否应退出时关闭已经完成。
}
void processInput(GLFWwindow* window) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
}
//用一个函数监视设备状态,并由对应状态进行一些操作。
//竟然不是通过设备触发事件来控制的。。。
//从这里的函数命名看出,GLFW封装的获取设备状态、设置窗口属性的函数,都具有Set/Get前缀。
//它们都适宜用在event的callback中,或者input的process中。(两个模型?)
//WinAPI虽然有设置属性的函数但是好像建议是只触发修改属性的事件。
//C#忘光光了不过好像由于有event类型所以把修改属性的函数挂到event上。
//可以看出OpenGL和GLFW的编程思想:它们既是接口的集合,也通过内部变量存储状态的形式成为一个对象。
画三角形的程序
OpenGL is by itself a large state machine: a collection of variables that define how OpenGL should currently operate. The state of OpenGL is commonly referred to as the OpenGL context. When using OpenGL, we often change its state by setting some options, manipulating some buffers and then render using the current context.
(一直感觉在图形界面里面用的“设备”和“上下文”的概念翻译了没翻译一样)
用到VBO、EBO。(vertex buffer object、element buffer object)
它们用来代表对应object,是unsigned int类型。
通过gen(生成)、bind(绑定)、data(配置)三步完成处理,具体数据最好用c风格数组存,因为后面要用指针。。。
VAO是vertex array object,作用事实上是把VBO或EBO组织起来。
comment 评论区
star_outline 咱快来抢个沙发吧!