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;
}
文章图片
文章图片
文章图片
主要添加点:
顶点索引
// --------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 顶点索引 绘制】
文章图片
推荐阅读
- 15、IDEA学习系列之其他设置(生成javadoc、缓存和索引的清理等)
- mysql中视图事务索引与权限管理
- mysql|一文深入理解mysql
- 2.关于OpenGL|2.关于OpenGL 坐标系以及渲染流程
- 17个搜索引擎
- 搜索引擎有哪些
- OpenGL|OpenGL ES之LUT(滤镜基准图)
- OpenGL|OpenGL 绘制甜甜圈深度测试、多边形偏移、裁剪、 混合
- FFmpeg|FFmpeg 开发(07)(FFmpeg + OpenGLES 实现 3D 全景播放器)
- Metal|Metal 案例03(大批量顶点数据的图形渲染)