OpenGL 图元重启

来源:互联网 发布:php批量执行sql 编辑:程序博客网 时间:2024/06/11 22:01


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); // IndexglBindBuffer(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 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::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;}

效果:
这里写图片描述

这里写图片描述

原创粉丝点击