一、視頻鏈接
【最好的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;
}