OpenGL|OpenGL 顶点索引 绘制

在:
http://blog.csdn.net/yulinxx/article/details/59538755
的基础上,添加以 顶点索引 方式进行绘制
main.cpp 如下:

#define GLEW_STATIC #include #include #include #include #include #include #include "Shader.h"#pragma comment(lib, "SOIL.lib")#pragma comment (lib, "opengl32.lib") #pragma comment (lib, "glew32s.lib") #pragma comment (lib, "glfw3.lib") #pragma comment (lib, "glfw3dll.lib") #pragma comment (lib, "glew32mxs.lib") #pragma comment (lib, "assimp.lib")#defineWIDTH 500 #defineHEIGH 500#define GEOMETRY 0GLfloat g_nX = 0; GLfloat g_nY = 0; GLfloat g_nZ = 0; glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f); glm::vec3 cameraTarg = glm::vec3(0.0f, 0.0f, 0.0f); glm::vec4mousePos; GLfloat fRotateAngle = 0.0f; void keyFun(GLFWwindow* pWnd, int nKey, int nScanCode, int nAction, int nMode); void mouseFun(GLFWwindow* pWnd, int, int, int); void cursorFun(GLFWwindow* window, double x, double y); int main() { glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); GLFWwindow* pWnd = glfwCreateWindow(WIDTH, HEIGH, "OGL Geometry Shader", nullptr, nullptr); glfwMakeContextCurrent(pWnd); glfwSetKeyCallback(pWnd, keyFun); glfwSetCursorPosCallback(pWnd, cursorFun); glfwSetMouseButtonCallback(pWnd, mouseFun); glewExperimental = GL_TRUE; glewInit(); glViewport(0, 0, WIDTH, HEIGH); // --------Add顶点索引数组 static GLfloat cube[] = { -1.0f, -1.0f, -5.0f, //前面的正方形 1.0f, -1.0f,-5.0f, 1.0f, 1.0f, -5.0f, -1.0f, 1.0f, -5.0f, -1.0f, -1.0f, -10.0f,//背面的正方形 1.0f, -1.0f, -10.0f, 1.0f, 1.0f, -10.0f, -1.0f, 1.0f, -10.0f }; // --------Add Endstatic GLubyte nIndexArray[] = { 0, 1, 2, 3, //前面 0, 3, 7, 4, //左面 5, 6, 2, 1, //右面 7, 6, 5, 4, //后面 //3, 2, 6, 7, //上面 //1, 0, 4, 5 //地面 3, 7, 6, 2, 0, 4, 1, 5 }; GLuint nVAO, nVBO, nIBO; glGenVertexArrays(1, &nVAO); glBindVertexArray(nVAO); { glGenBuffers(1, &nVBO); glBindBuffer(GL_ARRAY_BUFFER, nVBO); { glBufferData(GL_ARRAY_BUFFER, sizeof(cube), cube, GL_STATIC_DRAW); glEnableVertexAttribArray(0); // vertex glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0); } glBindBuffer(GL_ARRAY_BUFFER, 0); // --------Add glGenBuffers(1, &nIBO); // Index glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, nIBO); { glBufferData(GL_ELEMENT_ARRAY_BUFFER, 24, nIndexArray, GL_STATIC_DRAW); } // --------Add End } glBindVertexArray(0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glEnable(GL_PROGRAM_POINT_SIZE); #if GEOMETRY Shader shader("./Shader/vertex.vx", "./Shader/geo.geo", "./Shader/frag.fg"); #else Shader shader("./Shader/vertex.vx", "./Shader/frag.fg"); #endifshader.userShaderProg(); glm::mat4 model; // 模型矩阵 glm::mat4 view; // 视图矩阵 // 后移(观察点与物体在同一平面)否则无法显示物体 view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f)); // 投影矩阵视角宽高比近远截面 glm::mat4 proj = glm::perspective(45.0f, GLfloat(WIDTH / HEIGH), 0.1f, 100.0f); // 获取Shader中 uniform 变量位置 GLint nModelLoc = glGetUniformLocation(shader.getProg(), "model"); GLint nViewLoc = glGetUniformLocation(shader.getProg(), "view"); GLint nProjLoc = glGetUniformLocation(shader.getProg(), "projection"); // 将矩阵传至Shader glUniformMatrix4fv(nModelLoc, 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv(nViewLoc, 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(nProjLoc, 1, GL_FALSE, glm::value_ptr(proj)); GLfloat radius = 6.0f; while (!glfwWindowShouldClose(pWnd)) { glfwPollEvents(); glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); GLfloat camX = sin(glfwGetTime()) * radius; GLfloat camZ = cos(glfwGetTime()) * radius; view = glm::lookAt(cameraPos, cameraTarg, glm::vec3(0.0, 1.0, 0.0)); glUniformMatrix4fv(nViewLoc, 1, GL_FALSE, glm::value_ptr(view)); glBindVertexArray(nVAO); { //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, nIBO); glDrawElements(GL_LINES, 24, GL_UNSIGNED_BYTE, 0); } glBindVertexArray(0); glfwSwapBuffers(pWnd); }return 0; }void keyFun(GLFWwindow* pWnd, int nKey, int nScanCode, int nAction, int nMode) { if (nAction == GLFW_PRESS) { if (nKey == GLFW_KEY_W) { // 物体到相机的单位向量 glm::vec3 direction = glm::normalize(cameraTarg - cameraPos); direction *= 0.2; // 移动0.2个单位向量 cameraPos += direction; } else if (nKey == GLFW_KEY_S) { glm::vec3 direction = glm::normalize(cameraTarg - cameraPos); direction *= 0.2; cameraPos -= direction; } else if (nKey == GLFW_KEY_A) { // 物体到相机的单位向量 glm::vec3 direction = glm::normalize(cameraTarg - cameraPos); // 物体到相机的单位向量 与 相机的向上向量相乘,得到垂直向量,即平移向量 glm::vec3 vertical = glm::normalize(glm::cross(direction, glm::vec3(0.0f, 1.0f, 0.0f))); vertical *= 0.2; cameraPos += vertical; // 移动相机位置 cameraTarg += vertical; //相机的指向位置也一起平衡(不平移则以原来的目标转圈)} else if (nKey == GLFW_KEY_D) { glm::vec3 direction = glm::normalize(cameraTarg - cameraPos); glm::vec3 vertical = glm::normalize(glm::cross(direction, glm::vec3(0.0f, 1.0f, 0.0f))); vertical *= 0.2; cameraPos -= vertical; cameraTarg -= vertical; } else if (nKey == GLFW_KEY_Q) { GLfloat radius = glm::distance(cameraPos, cameraTarg); fRotateAngle += 0.2; GLfloat camX = sin(fRotateAngle) * radius + cameraTarg.x; GLfloat camZ = cos(fRotateAngle) * radius + cameraTarg.z; cameraPos = glm::vec3(camX, 0.0, camZ); } else if (nKey == GLFW_KEY_E) { GLfloat radius = glm::distance(cameraPos, cameraTarg); fRotateAngle -= 0.2; GLfloat camX = sin(fRotateAngle) * radius + cameraTarg.x; GLfloat camZ = cos(fRotateAngle) * radius + cameraTarg.z; cameraPos = glm::vec3(camX, 0.0, camZ); } else if (nKey == GLFW_KEY_X)// 还原视图 { cameraPos = glm::vec3(0.0f, 0.0f, 3.0f); cameraTarg = glm::vec3(0.0f, 0.0f, 0.0f); } } }#include void mouseFun(GLFWwindow* window, int button, int action, int mods) { if (action == GLFW_PRESS) { switch (button) { case GLFW_MOUSE_BUTTON_LEFT: { printf("%.3f %.3f\t\t%.3f, %.3f\t\t\tLeft button clicked!\n", mousePos.x, mousePos.y, mousePos.z, mousePos.w); } break; case GLFW_MOUSE_BUTTON_MIDDLE: printf("Middle button clicked!\n"); break; case GLFW_MOUSE_BUTTON_RIGHT: printf("Right button clicked!\n"); break; default: printf("Default \n"); return; } } return; }void cursorFun(GLFWwindow* window, double x, double y) { float xpos = float((x - WIDTH / 2) / WIDTH) * 2; float ypos = float(0 - (y - HEIGH / 2) / HEIGH) * 2; printf("Mouse position move to [ %.3f : %.3f ]\n", xpos, ypos); mousePos = glm::vec4(x, y, xpos, ypos); return; }

OpenGL|OpenGL 顶点索引 绘制
文章图片

OpenGL|OpenGL 顶点索引 绘制
文章图片

OpenGL|OpenGL 顶点索引 绘制
文章图片

主要添加点:
顶点索引
// --------Add glGenBuffers(1, &nIBO); // Index glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, nIBO); { glBufferData(GL_ELEMENT_ARRAY_BUFFER, 24, nIndexArray, GL_STATIC_DRAW); } // --------Add End

绘图部分
glBindVertexArray(nVAO); { //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, nIBO); glDrawElements(GL_LINES, 24, GL_UNSIGNED_BYTE, 0); } glBindVertexArray(0);

源码:
http://download.csdn.net/download/yulinxx/9970120
其它:
若顶点为:
GLfloat fPoint[] = { -0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.0f,0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.0f,0.0f, 0.4f, 1.0f, -0.5f, 0.5f, 0.0f,1.0f, 0.30f, 1.0f };

索引为:
static GLubyte nIndexArray[] = { 0, 1, 3, 1,2, 3 };

绘制为:
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glDrawElements(GL_TRIANGLES, sizeof(nIndexArray), GL_UNSIGNED_BYTE, 0);

结果:
OpenGL|OpenGL 顶点索引 绘制
文章图片

【OpenGL|OpenGL 顶点索引 绘制】OpenGL|OpenGL 顶点索引 绘制
文章图片

    推荐阅读