在
http://blog.csdn.net/yulinxx/article/details/77894764
基础上添加
参考:
1
OpenGL ES 3.0: 图元重启(Primitive restart) - 皮斯卡略夫 - 博客园
作者:psklf
出处: http://www.cnblogs.com/psklf/p/5750783.html
2
OpenGL Separating Polygons Inside VBO - Stack Overflow
出处: https://stackoverflow.com/questions/26944959/opengl-separating-polygons-inside-vbo
You can use primitive restart. The downside of this is that you need an index array, which may not have been necessary otherwise. Apart from that, it’s straightforward. You enable it with:
glPrimitiveRestartIndex(0xffff);
glEnable(GL_PRIMITIVE_RESTART);
You can use any index you want as the restart index, but it’s common policy to use the maximum possible index, which is 0xffff if you use indices of type GL_UNSIGNED_SHORT. If you use at least OpenGL 4.3, or OpenGL ES 3.0, you can also replace the above with:
glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
Then you set up an index array where you insert a 0xffff value at every position you want to start a new polygon, and bind the index array as usual. Then you can draw all the polygons with a single glDrawElements() call.
3.
Best Practices for Working with Vertex Data
出处: https://developer.apple.com/library/content/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/TechniquesforWorkingwithVertexData/TechniquesforWorkingwithVertexData.html
在此,主要步骤为:
1.
生成顶点索引
glGenBuffers(1, &nIBO); // Index
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, nIBO);
{
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(nIndexArray), nIndexArray, GL_STATIC_DRAW);
}
2.
制定索引数据
static GLushort nIndexArray[] = {
0, 1, 3, 0xFFFF, 1, 2, 3
};
3.
开启并绘制
glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glDrawElements(GL_TRIANGLES, sizeof(nIndexArray), GL_UNSIGNED_SHORT, 0);
http://blog.csdn.net/yulinxx/article/details/77894764
基础上,main.cpp 修改为:
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <SOIL/SOIL.h>
#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")
#define WIDTH 500
#define HEIGH 500
#define GEOMETRY 0
GLfloat 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::vec4 mousePos;
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);
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 };
// 1.在顶点索引数组中设置重启标志位0xFFFF
static GLushort nIndexArray[] = {
0, 1, 3, 0xFFFF, 1, 2, 3
};
GLuint nVAO, nVBO, nIBO;
glGenVertexArrays(1, &nVAO);
glBindVertexArray(nVAO);
{
glGenBuffers(1, &nVBO);
glBindBuffer(GL_ARRAY_BUFFER, nVBO);
{
glBufferData(GL_ARRAY_BUFFER, sizeof(fPoint), fPoint, GL_STATIC_DRAW);
glEnableVertexAttribArray(0); // vertex
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
// --------Add
glGenBuffers(1, &nIBO); // Index
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, nIBO);
{
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(nIndexArray), 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");
#endif
shader.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);
{
#if GEOMETRY
glDrawArrays(GL_POINTS, 0, sizeof(fPoint) / sizeof(GLfloat) / 6);
#else
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, nIBO);
// 2.启用图元重启
glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// 3.绘制
glDrawElements(GL_TRIANGLES, sizeof(nIndexArray), GL_UNSIGNED_SHORT, 0);
#endif
}
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 <stdio.h>
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;
}
效果: