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")

#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;
}

OpenGL 顶点索引 绘制_第1张图片

OpenGL 顶点索引 绘制_第2张图片

OpenGL 顶点索引 绘制_第3张图片

主要添加点:

顶点索引

// --------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 顶点索引 绘制_第4张图片




OpenGL 顶点索引 绘制_第5张图片

你可能感兴趣的:(OpenGL,opengl)