一、视频链接
【最好的OpenGL教程之一】https://www.bilibili.com/video/BV1MJ411u7Bc?p=5&vd_source=44b77bde056381262ee55e448b9b1973
二、相关网站
docs.gl
三、代码整理
c++
#include <GL/glew.h>
#include <GLFW/glfw3.h>#include<iostream>int main(void)
{GLFWwindow* window;//初始化glfwif (!glfwInit())return -1;//创建一个窗口模式的窗口并设置OpenGL上下文window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);if (!window)//如果窗口创建失败,则终止程序{glfwTerminate();//释放glfw资源return -1;}//设置当前窗口的上下文,之后所有的OpenGL调用都会在这个上下文中进行glfwMakeContextCurrent(window);//初始化GLEWif (glewInit() != GLEW_OK)std::cout << "Error!" << std::endl;//打印OpenGL版本信息std::cout << glGetString(GL_VERSION) << std::endl;//通过GL顶点属性指针的函数告诉OpenGL的数据是如何布局的//这里我们告诉OpenGL,position数据是两个float,每个float占4字节//第一个float表示x坐标,第二个float表示y坐标//由于我们的数据是2D坐标,所以这里的stride为8字节// 参数:// 1.顶点属性的索引,这里是0// 2.数据类型,这里是GL_FLOAT// 3.数据类型占用字节数,这里是4// 4.是否归一化,这里是GL_FALSE// 5.stride,这里是8,表示两个float的大小// 6.偏移量,这里是0,表示数据从开头开始// 注意:这里的顶点属性指针的设置必须在启用顶点属性数组之前// glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 8, 0);//启用顶点属性数组// 参数: // 1.顶点属性的索引,这里是0// glEnableVertexAttribArray(0);//准备数据float position[6] = {0.0f, 0.5f,- 0.5f, -0.5f,0.5f, -0.5f};//可以将需要的图形(如三角形)绑定缓冲区,传递缓冲区的id给OpenGL,然后通过OpenGL渲染//shader语法以字符串的形式给出,再由gl解析后让GPU执行GLSL程序unsigned int buffer;//功能:生成缓冲区,并将缓冲区绑定到OpenGL的指定目标//参数://1.缓冲区数量,表示要生成的缓冲区数量//2.指向无符号整数的指针,表示生成的缓冲区id的存储位置glGenBuffers(1,&buffer);//功能:绑定缓冲区到OpenGL的指定目标//参数://1.目标,数组缓冲区,表示绑定到OpenGL的缓冲区//2.缓冲区id,表示要绑定的缓冲区的idglBindBuffer(GL_ARRAY_BUFFER, buffer);//功能:将数据写入缓冲区//参数://1.目标,数组缓冲区,表示要写入的缓冲区//2.数据大小,表示要写入的数据的大小//3.数据指针,表示要写入的数据的指针//4.写入模式,表示数据写入的模式,这里是静态写入。// 静态写入:数据不会被修改,仅仅是一次性写入,写入后缓冲区内容不会改变。// 动态写入:数据会被修改,写入后缓冲区内容会改变。// 一般情况下,静态写入效率更高。glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), position, GL_STATIC_DRAW);//渲染循环,直到窗口被关闭while (!glfwWindowShouldClose(window)){//这部分主要:渲染窗口内容glClear(GL_COLOR_BUFFER_BIT);/*//方法一:通过顶点属性指针渲染glBegin(GL_TRIANGLES);glVertex2f(0.0f, 0.5f);glVertex2f(-0.5f, -0.5f);glVertex2f(0.5f, -0.5f);glEnd();*//*//方法二//功能:指定如何从缓冲区中读取数据//参数// mode// 指定要渲染的原始类型。接受符号常量// GL_POINTS、GL_LINE_STRIP、GL_LINE_LOOP、GL_LINES、// GL_TRIANGLE_STRIP、GL_TRIANGLE_FAN 和 GL_TRIANGLES。// first// 指定在启用的数组中的起始索引。// count// 指定要渲染的索引数量。glDrawArrays(GL_TRIANGLES, 0, 3);*//*//方法三:通过索引缓冲区渲染//功能:指定如何从缓冲区中读取数据//参数// mode// 指定要渲染的原始类型。符号常量 GL_POINTS、GL_LINE_STRIP、// GL_LINE_LOOP、GL_LINES、GL_LINE_STRIP_ADJACENCY、GL_LINES_ADJACENCY、// GL_TRIANGLE_STRIP、GL_TRIANGLE_FAN、GL_TRIANGLES、// GL_TRIANGLE_STRIP_ADJACENCY、GL_TRIANGLES_ADJACENCY // 和 GL_PATCHES 被接受。// count// 指定要渲染的元素数量。// type// 指定 indices 中值的类型。必须是 GL_UNSIGNED_BYTE、GL_UNSIGNED_SHORT // 或 GL_UNSIGNED_INT 中的一种。// indices// 指定缓冲区当前绑定到GL_ELEMENT_ARRAY_BUFFER目标的数据存储中数组第一个索引的偏移量。glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);*///刷新缓冲区并交换窗口glfwSwapBuffers(window);//处理窗口事件,如键盘输入、鼠标移动等glfwPollEvents();}glfwTerminate();return 0;
}