zoukankan      html  css  js  c++  java
  • QT_OPENGL-------- 5.model

    在qt中实现opengl obj模型导入:

    main.cpp

    #include<GL/glew.h>
    #include <GLFW/glfw3.h>
    #include<stdio.h>
    #include<glm/glm.hpp>
    #include<glm/ext.hpp>
    #include"misc.h"
    #include"model.h"
    GLfloat deltaTime = 0.0f;
    GLfloat lastFrame = 0.0f;
    
    
    GLint CreateGPUProgram(const char*vsShaderPath,const char*fsShaderPath)
    {
        GLuint vsShader=glCreateShader(GL_VERTEX_SHADER);
        GLuint fsShader=glCreateShader(GL_FRAGMENT_SHADER);
        const char*vsCode=LoadFileContent(vsShaderPath);
        const char*fsCode=LoadFileContent(fsShaderPath);
        glShaderSource(vsShader,1,&vsCode,nullptr);
        glShaderSource(fsShader,1,&fsCode,nullptr);
        glCompileShader(vsShader);
        glCompileShader(fsShader);
        GLuint program=glCreateProgram();
        glAttachShader(program,vsShader);
        glAttachShader(program,fsShader);
        glLinkProgram(program);
        glDetachShader(program,vsShader);
        glDetachShader(program,fsShader);
        glDeleteShader(vsShader);
        glDeleteShader(fsShader);
        return program;
    }
    void framebuffer_size_callback(GLFWwindow* window, int width, int height)
    {
        glViewport(0, 0, width, height);
    }
    int main(void)
    {
        GLFWwindow* window;
    
    
        if (!glfwInit())
            return -1;
    
        window = glfwCreateWindow(480, 320, "Hello World", NULL, NULL);
        if (!window)
        {
            glfwTerminate();
            return -1;
        }
        glfwMakeContextCurrent(window);
        glewExperimental = GL_TRUE;
        // 还需要注册这个函数,告诉GLFW我们希望每当窗口调整大小的时候调用这个函数。
        glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
    
        glewInit();
        GLuint program = CreateGPUProgram("/home/jun/OpenGL/model/sample.vs", "/home/jun/OpenGL/model/sample.fs");
        GLint posLocation, texcoordLocation,normalLocation, MLocation, VLocation, PLocation;
        posLocation = glGetAttribLocation(program, "pos");
        texcoordLocation = glGetAttribLocation(program, "texcoord");
        normalLocation = glGetAttribLocation(program, "normal");
    
        MLocation = glGetUniformLocation(program, "M");
        VLocation = glGetUniformLocation(program, "V");
        PLocation = glGetUniformLocation(program, "P");
    
    
        unsigned int *indexes = nullptr;
        int vertexCount = 0, indexCount = 0;
        VertexData*vertexes = LoadObjModel("/home/jun/OpenGL/model/MODEL/niutou.obj", &indexes, vertexCount, indexCount);
        if (vertexes==nullptr)
        {
            printf("load obj model fail
    ");
        }
        //obj model -> vbo & ibo
        GLuint vbo = CreateBufferObject(GL_ARRAY_BUFFER, sizeof(VertexData) * vertexCount, GL_STATIC_DRAW, vertexes);
        GLuint ibo = CreateBufferObject(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * indexCount, GL_STATIC_DRAW, indexes);
        printf("vertex count %d index count %d
    ",vertexCount,indexCount);
    
        glClearColor(41.0f / 255.0f, 71.0f / 255.0f, 121.0f / 255.0f, 1.0f);
    
        //ShowWindow(hwnd, SW_SHOW);
        //UpdateWindow(hwnd);
    
        float identity[] = {
            1,0,0,0,
            0,1,0,0,
            0,0,1,0,
            0,0,0,1
        };
       //创建一个投影矩阵
       glm::mat4 model;
       model = glm::translate(model, glm::vec3(0.0f, 0.0f, -54.0f));
        model = glm::scale(model, glm::vec3(0.2f, 0.2f, 0.2f));
       glm::mat4 projection=glm::perspective(45.0f,800.0f/600.0f,0.1f,1000.0f);
    
    
       glEnable(GL_DEPTH_TEST);
       glEnable(GL_CULL_FACE);
    
        while (!glfwWindowShouldClose(window))
        {
            GLfloat currentFrame = (GLfloat)glfwGetTime();
            deltaTime = currentFrame - lastFrame;
            lastFrame = currentFrame;
            glfwPollEvents();
    
           // glClearColor(1.0f, 0.04f, 0.14f, 1.0f);
    
            glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
            glUseProgram(program);
            glUniformMatrix4fv(MLocation, 1, GL_FALSE, glm::value_ptr(model));
            glUniformMatrix4fv(VLocation, 1, GL_FALSE, identity);
            glUniformMatrix4fv(PLocation, 1, GL_FALSE, glm::value_ptr(projection));
    
            glBindBuffer(GL_ARRAY_BUFFER, vbo);
            glEnableVertexAttribArray(posLocation);
            glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)0);
            glEnableVertexAttribArray(texcoordLocation);
            glVertexAttribPointer(texcoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)(sizeof(float) * 3));
            glEnableVertexAttribArray(normalLocation);
            glVertexAttribPointer(normalLocation, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)(sizeof(float) * 5));
    
            glBindBuffer(GL_ARRAY_BUFFER, 0);
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
            glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, 0);
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
            glUseProgram(0);
            glfwSwapBuffers(window);
    
    
        }
    
        glfwTerminate();
        return 0;
    }

    mish.h

    #include<GL/glew.h>
    GLuint CreateBufferObject(GLenum bufferType, GLsizeiptr size, GLenum usage, void*data = nullptr);
    char *LoadFileContent(const char*path);

    mish.cpp

    #include "misc.h"
    #include <stdio.h>
    
    GLuint CreateBufferObject(GLenum bufferType, GLsizeiptr size, GLenum usage, void*data /* = nullptr */)
    {
        GLuint object;
        glGenBuffers(1, &object);
        glBindBuffer(bufferType, object);
        glBufferData(bufferType, size, data, usage);
        glBindBuffer(bufferType, 0);
        return object;
    }
    
    
    char *LoadFileContent(const char*path)
    {
        FILE*pFile = fopen(path, "rb");
        if (pFile)
        {
            fseek(pFile, 0, SEEK_END);
            int nLen = ftell(pFile);
            char*buffer = nullptr;
            if (nLen!=0)
            {
                buffer=new char[nLen + 1];
                rewind(pFile);
                fread(buffer, nLen, 1, pFile);
                buffer[nLen] = '';
            }
            else
            {
                printf("load file fail %s content len is 0
    ", path);
            }
            fclose(pFile);
            return buffer;
        }
        else
        {
            printf("open file %s fail
    ",path);
        }
        fclose(pFile);
        return nullptr;
    }

    model.h

    struct VertexData
    {
        float position[3];
        float texcoord[2];
        float normal[3];
    };
    
    VertexData*LoadObjModel(const char* filePath,unsigned int **indexes,int&vertexCount,int&indexCount);

    model.cpp

    #include "model.h"
    #include "misc.h"
    #include <stdio.h>
    #include <string.h>
    #include <sstream>
    #include <vector>
    
    VertexData*LoadObjModel(const char* filePath, unsigned int **indexes, int&vertexCount, int&indexCount)
    {
        char*fileContent = LoadFileContent(filePath);
        if (fileContent!=nullptr)
        {
            //obj model decode
            struct VertexInfo
            {
                float v[3];
            };
    
            struct VertexDefine
            {
                int positionIndex;
                int texcoordIndex;
                int normalIndex;
            };
            std::vector<VertexInfo> positions;
            std::vector<VertexInfo> texcoords;
            std::vector<VertexInfo> normals;
    
            std::vector<unsigned int> objIndexes;// -> opengl indexes
            std::vector<VertexDefine> vertices;// -> opengl vertexes
    
            std::stringstream ssObjFile(fileContent);
            char szOneLine[256];
            std::string temp;
            while (!ssObjFile.eof())
            {
                memset(szOneLine, 0, 256);
                ssObjFile.getline(szOneLine,256);
                if (strlen(szOneLine)>0)
                {
                    std::stringstream ssOneLine(szOneLine);
    
                    if (szOneLine[0]=='v')
                    {
                        if (szOneLine[1]=='t')
                        {
                            //vertex coord
                            ssOneLine >> temp;
                            VertexInfo vi;
                            ssOneLine >> vi.v[0];
                            ssOneLine >> vi.v[1];
                            texcoords.push_back(vi);
                            printf("%s %f,%f
    ", temp.c_str(), vi.v[0], vi.v[1]);
                        }
                        else if(szOneLine[1]=='n')
                        {
                            //normal
                            ssOneLine >> temp;
                            VertexInfo vi;
                            ssOneLine >> vi.v[0];
                            ssOneLine >> vi.v[1];
                            ssOneLine >> vi.v[2];
                            normals.push_back(vi);
                            printf("%s %f,%f,%f
    ", temp.c_str(), vi.v[0], vi.v[1], vi.v[2]);
                        }
                        else
                        {
                            //position
                            ssOneLine >> temp;
                            VertexInfo vi;
                            ssOneLine >> vi.v[0];
                            ssOneLine >> vi.v[1];
                            ssOneLine >> vi.v[2];
                            positions.push_back(vi);
                            printf("%s %f,%f,%f
    ",temp.c_str(), vi.v[0], vi.v[1], vi.v[2]);
                        }
                    }
                    else if (szOneLine[0] == 'f')
                    {
                        //face
                        ssOneLine >> temp;// 'f'
                        std::string vertexStr;
                        for (int i=0;i<3;i++)
                        {
                            ssOneLine >> vertexStr;
                            size_t pos = vertexStr.find_first_of('/');
                            std::string positionIndexStr = vertexStr.substr(0, pos);
                            size_t pos2 = vertexStr.find_first_of('/', pos + 1);
                            std::string texcoordIndexStr = vertexStr.substr(pos + 1, pos2 - pos - 1);
                            std::string normalIndexStr = vertexStr.substr(pos2 + 1, vertexStr.length() - pos2 - 1);
                            VertexDefine vd;
                            vd.positionIndex = atoi(positionIndexStr.c_str())-1;
                            vd.texcoordIndex = atoi(texcoordIndexStr.c_str()) - 1;
                            vd.normalIndex = atoi(normalIndexStr.c_str()) - 1;
    
                            int nCurrentIndex = -1;//indexes
                            //check if exist
                            size_t nCurrentVerticeCount = vertices.size();
                            for (size_t j = 0; j < nCurrentVerticeCount; j++)
                            {
                                if (vertices[j].positionIndex == vd.positionIndex&&
                                    vertices[j].texcoordIndex == vd.texcoordIndex&&
                                    vertices[j].normalIndex == vd.normalIndex)
                                {
                                    nCurrentIndex = j;
                                    break;
                                }
                            }
                            if (nCurrentIndex==-1)
                            {
                                //create new vertice
                                nCurrentIndex = vertices.size();
                                vertices.push_back(vd);//vertexes define
                            }
                            objIndexes.push_back(nCurrentIndex);
                        }
                    }
                }
            }
            printf("face count %u
    ",objIndexes.size()/3);
            //objIndexes->indexes buffer -> ibo
            indexCount = (int)objIndexes.size();
            *indexes = new unsigned int[indexCount];
            for (int i=0;i<indexCount;i++)
            {
                (*indexes)[i] = objIndexes[i];
            }
            //vertices -> vertexes -> vbo
            vertexCount = (int)vertices.size();
            VertexData*vertexes = new VertexData[vertexCount];
            for (int i=0;i<vertexCount;++i)
            {
                memcpy(vertexes[i].position, positions[vertices[i].positionIndex].v, sizeof(float) * 3);
                memcpy(vertexes[i].texcoord, texcoords[vertices[i].texcoordIndex].v, sizeof(float) * 2);
                memcpy(vertexes[i].normal, normals[vertices[i].normalIndex].v, sizeof(float) * 3);
            }
            return vertexes;
        }
        return nullptr;
    }

    model.pro

    TEMPLATE = app
    CONFIG += console c++11
    CONFIG -= app_bundle
    CONFIG -= qt
    
    SOURCES += main.cpp 
        misc.cpp 
        model.cpp
    
    LIBS+= -L/usr/lib64 -lGLEW
    LIBS +=-L/usr/local/lib -lglfw3 -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -lGL -lpthread -ldl
    
    HEADERS += 
        misc.h 
        model.h

    最后的效果:

  • 相关阅读:
    聊聊Flame Graph(火焰图)的那些事
    Dynamometer:HDFS性能扩展测试工具
    论分布式系统中单一锁控制的优化
    聊聊磁盘数据的损坏
    分级副本存储:一种更具效益成本的数据容错策略
    分布式存储系统中的Data Scrubbing机理
    论一个成熟分布式系统的工具类设计
    聊聊Raft一致性协议以及Apache Ratis
    ListenableFuture的状态同步和原子更新
    2018-9-1-win10-uwp-轻量级-MVVM-框架入门-2.1.5.3199
  • 原文地址:https://www.cnblogs.com/fuhang/p/10037953.html
Copyright © 2011-2022 走看看