在:
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")
#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);
// --------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 End
static 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");
#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);
{
//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;
}
主要添加点:
顶点索引
// --------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);