EBO
EBO(Element Buffer Object):元素緩沖對象,用于存儲頂點繪制順序索引號的GPU顯存區域
unsigned int indices[] = {0, 1, 2,2, 1, 3};//EBO創建和綁定GLuint ebo = 0;glGenBuffers(1, &ebo);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);//VAO創建和綁定GLuint vao = 0;glGenVertexArrays(1, &vao);glBindVertexArray(vao);//加入ebo到當前的vaoglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
綁定vao之后,GL狀態機就認為后續操作針對的是當前這個vao,在當前vao狀態下綁定任何vbo或者ebo,都會被記錄到當前vao當中。
glDrawElements
#include <glad/glad.h>//glad必須在glfw頭文件之前包含
#include <GLFW/glfw3.h>
#include <iostream>void frameBufferSizeCallbakc(GLFWwindow* window, int width, int height)
{glViewport(0, 0, width, height);
}
void glfwKeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
}GLuint program = 0;
GLuint vao = 0;
void prepareVAO()
{//1 準備positionsfloat positions[] = {-0.5f, -0.5f, 0.0f,0.5f, -0.5f, 0.0f,0.0f, 0.5f, 0.0f,0.5f, 0.5f, 0.0f,};unsigned int indices[] = {0, 1, 2,2, 1, 3};//2 VBO創建GLuint vbo = 0;glGenBuffers(1, &vbo);glBindBuffer(GL_ARRAY_BUFFER, vbo);glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);//3 EBO創建GLuint ebo = 0;glGenBuffers(1, &ebo);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);//4 VAO創建vao = 0;glGenVertexArrays(1, &vao);glBindVertexArray(vao);//5 綁定vbo ebo 加入屬性描述信息//5.1 加入位置屬性描述信息glBindBuffer(GL_ARRAY_BUFFER, vbo);glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);//5.2 加入ebo到當前的vaoglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);glBindVertexArray(0);
}
void prepareShader() {//1 完成vs與fs的源代碼,并且裝入字符串const char* vertexShaderSource ="#version 330 core\n""layout (location = 0) in vec3 aPos;\n""void main()\n""{\n"" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n""}\0";const char* fragmentShaderSource ="#version 330 core\n""out vec4 FragColor;\n""void main()\n""{\n"" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n""}\n\0";//2 創建Shader程序(vs、fs)GLuint vertex, fragment;vertex = glCreateShader(GL_VERTEX_SHADER);fragment = glCreateShader(GL_FRAGMENT_SHADER);//3 為shader程序輸入shader代碼glShaderSource(vertex, 1, &vertexShaderSource, NULL);glShaderSource(fragment, 1, &fragmentShaderSource, NULL);int success = 0;char infoLog[1024];//4 執行shader代碼編譯 glCompileShader(vertex);//檢查vertex編譯結果glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(vertex, 1024, NULL, infoLog);std::cout << "Error: SHADER COMPILE ERROR --VERTEX" << "\n" << infoLog << std::endl;}glCompileShader(fragment);//檢查fragment編譯結果glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(fragment, 1024, NULL, infoLog);std::cout << "Error: SHADER COMPILE ERROR --FRAGMENT" << "\n" << infoLog << std::endl;}//5 創建一個Program殼子program = glCreateProgram();//6 將vs與fs編譯好的結果放到program這個殼子里glAttachShader(program, vertex);glAttachShader(program, fragment);//7 執行program的鏈接操作,形成最終可執行shader程序glLinkProgram(program);//檢查鏈接錯誤glGetProgramiv(program, GL_LINK_STATUS, &success);if (!success) {glGetProgramInfoLog(program, 1024, NULL, infoLog);std::cout << "Error: SHADER LINK ERROR " << "\n" << infoLog << std::endl;}//清理glDeleteShader(vertex);glDeleteShader(fragment);
}void render()
{//執行opengl畫布清理操作glClear(GL_COLOR_BUFFER_BIT);//1.綁定當前的programglUseProgram(program);//2 綁定當前的vaoglBindVertexArray(vao);//3 發出繪制指令//glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)(3 * sizeof(int)));
}
int main()
{//初始化glfw環境glfwInit();//設置opengl主版本號glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);//設置opengl次版本號glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);//設置opengl啟用核心模式glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//創建窗體對象GLFWwindow* window = glfwCreateWindow(800, 600, "lenarnOpenGL", nullptr, nullptr);//設置當前窗體對象為opengl的繪制舞臺glfwMakeContextCurrent(window);//窗體大小回調glfwSetFramebufferSizeCallback(window, frameBufferSizeCallbakc);//鍵盤相應回調glfwSetKeyCallback(window, glfwKeyCallback);//使用glad加載所有當前版本opengl的函數if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){std::cout << "初始化glad失敗" << std::endl;return -1;};//設置opengl視口大小和清理顏色glViewport(0, 0, 800, 600);glClearColor(0.2f, 0.3f, 0.3f, 1.0f);//著色器prepareShader();//vaoprepareVAO();//執行窗體循環while (!glfwWindowShouldClose(window)){//接受并分發窗體消息//檢查消息隊列是否有需要處理的鼠標、鍵盤等消息//如果有的話就將消息批量處理,清空隊列glfwPollEvents();//渲染操作render();//切換雙緩存glfwSwapBuffers(window);}//推出程序前做相關清理glfwTerminate();return 0;
}
glDrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
mode:繪制模式GL_TRIANGLES,GL_LINES
count:繪制索引數組中的幾個點
type:索引的數據類型
indices:
如果使用了ebo,通常填寫0;
如果使用了ebo,其不填寫0,則表示索引內偏移
如果不使用ebo,可以直接傳入索引數組