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就可通过纹理单元获取到对应的纹理

 

posted @   LCAC  阅读(560)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
点击右上角即可分享
微信分享提示