LearnOpenGL 入门
一、说明
1、使用glad3.3的版本,则开开始的时候初始化的版本为3.3
glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
2、创建窗口,设置窗口需要的各种监听和特性
m_window = glfwCreateWindow(GLFWManager::getScreenWidth(), GLFWManager::getScreenHeight(), "test", NULL, NULL); glfwMakeContextCurrent(m_window); glfwSetFramebufferSizeCallback(m_window, GLFWframebuffersizeCallback); glfwSetCursorPosCallback(m_window, GLFWCursorposCallback); glfwSetScrollCallback(m_window, GLFWScrollCallback); glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
设置当前窗口在当前的线程执行glfwMakeContextCurrent(m_window);
不管是什么类型的窗口(不止是opengl,其他的windows窗口),均要在指定的单一线程上面渲染等操作。因为界面的操作不存在线程安全。
如果要多个窗口,这里可以创建多个window并且在不同的线程做makecontextcurrent的操作
glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);设置界面的光标不可见
3、使用glad来管理opengl的函数指针
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
通过gladLoadGLLoader 将gl的函数load进来,比如在glad.c中
1 | glad_glGenSamplers = (PFNGLGENSAMPLERSPROC)load( "glGenSamplers" ); |
然后在glad.h中
GLAPI PFNGLGENSAMPLERSPROC glad_glGenSamplers; #define glGenSamplers glad_glGenSamplers
这样子就可以执行glGenSamplers 函数了
注意:gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);需要在对应存在的上下文load,否则会出现失败
可参见glfw的官方文档:https://www.glfw.org/docs/latest/group__context.html
A context must be current on the calling thread. Calling this function without a current context will cause a GLFW_NO_CURRENT_CONTEXT error.
Remarks
The address of a given function is not guaranteed to be the same between contexts.
This function may return a non-NULL address despite the associated version or extension not being available. Always check the context version or extension string first.
并且还特别标明了在不同的context可能地址还会不一样
二、关于glEnableVertexAttribArray的使用
1、在了解该参数的使用之前,要先明白cpu跟gpu之间是如何传输数据
1、在定点着色器中定义的某个in 的参数aPos;在我们看来该参数叫aPos,但是在GPU看来却是某个index;所以对该参数赋值数据要先获取该参数对应的索引
unsigned int index = glGetAttribLocation(shaderId, "aPos");
2、将gpu中要设置到该参数的缓冲区数据绑定到当前的VAO 即
glBindBuffer(GL_ARRAY_BUFFER, VBO);
3、当前的VAO已经有缓冲区数据,则可以将顶点着色器的in参数aPos索引指到该缓冲区中需要指定的位置即
glVertexAttribPointer(index, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);
该操作指定了:索引、大小、类型、是否需要标准化参数、大小乘以类型所占用的空间,从哪个位置开始读取
注意:1、大小是指vertex的个数;2、标准化参数是指将所有的数据均转化为0到1之间(如果有符号则是-1到1);3、从哪个位置开始读取是计算字节数,而不是计算vertex的个数
4、当完成上面的1,2,3步骤之后,aPos已经正确的指定到了对应的缓冲区了;但是此时如果绘制依旧无法正确绘制出图形,这是因为aPos对应的索引没有使能,这时就需要执行
glEnableVertexAttribArray(index);
为何这里还要使能该索引才行呢? 这是因为在初始的时候gpu将所有的状态都设置为false。设为false是出于性能考虑,所有顶点着色器的属性(Attribute)变量都是关闭的
1、正常的流程
1、glEnableVertexAttribArray的作用是为了让shader对应的参数能够读取到数据
二、遇到的坑
1、将texture设置进shader的时候(使用 glUniform1i 进行设置texture),value直接使用了textureId,而不是textureIndex导致图片出不来,总是一片黑色
使用textureindex而不是textureid的原因:
要知道我们是要将纹理挂在纹理单元上面,然后shader在纹理单元上面进行读取。
所以我们要做的是:
1、指定shader中每个texture的纹理单元
2、当要使用某个纹理单元的时候,先激活指定的纹理单元,再将对应textureId绑定到对应的纹理单元;这样子shader就可通过纹理单元获取到对应的纹理
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!