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

main.cpp

  1. #include<GL/glew.h>
  2. #include <GLFW/glfw3.h>
  3. #include<stdio.h>
  4. #include<glm/glm.hpp>
  5. #include<glm/ext.hpp>
  6. #include"misc.h"
  7. #include"model.h"
  8. GLfloat deltaTime = 0.0f;
  9. GLfloat lastFrame = 0.0f;
  10.  
  11. GLint CreateGPUProgram(const char*vsShaderPath,const char*fsShaderPath)
  12. {
  13. GLuint vsShader=glCreateShader(GL_VERTEX_SHADER);
  14. GLuint fsShader=glCreateShader(GL_FRAGMENT_SHADER);
  15. const char*vsCode=LoadFileContent(vsShaderPath);
  16. const char*fsCode=LoadFileContent(fsShaderPath);
  17. glShaderSource(vsShader,,&vsCode,nullptr);
  18. glShaderSource(fsShader,,&fsCode,nullptr);
  19. glCompileShader(vsShader);
  20. glCompileShader(fsShader);
  21. GLuint program=glCreateProgram();
  22. glAttachShader(program,vsShader);
  23. glAttachShader(program,fsShader);
  24. glLinkProgram(program);
  25. glDetachShader(program,vsShader);
  26. glDetachShader(program,fsShader);
  27. glDeleteShader(vsShader);
  28. glDeleteShader(fsShader);
  29. return program;
  30. }
  31. void framebuffer_size_callback(GLFWwindow* window, int width, int height)
  32. {
  33. glViewport(, , width, height);
  34. }
  35. int main(void)
  36. {
  37. GLFWwindow* window;
  38.  
  39. if (!glfwInit())
  40. return -;
  41.  
  42. window = glfwCreateWindow(, , "Hello World", NULL, NULL);
  43. if (!window)
  44. {
  45. glfwTerminate();
  46. return -;
  47. }
  48. glfwMakeContextCurrent(window);
  49. glewExperimental = GL_TRUE;
  50. // 还需要注册这个函数,告诉GLFW我们希望每当窗口调整大小的时候调用这个函数。
  51. glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
  52.  
  53. glewInit();
  54. GLuint program = CreateGPUProgram("/home/jun/OpenGL/model/sample.vs", "/home/jun/OpenGL/model/sample.fs");
  55. GLint posLocation, texcoordLocation,normalLocation, MLocation, VLocation, PLocation;
  56. posLocation = glGetAttribLocation(program, "pos");
  57. texcoordLocation = glGetAttribLocation(program, "texcoord");
  58. normalLocation = glGetAttribLocation(program, "normal");
  59.  
  60. MLocation = glGetUniformLocation(program, "M");
  61. VLocation = glGetUniformLocation(program, "V");
  62. PLocation = glGetUniformLocation(program, "P");
  63.  
  64. unsigned int *indexes = nullptr;
  65. int vertexCount = , indexCount = ;
  66. VertexData*vertexes = LoadObjModel("/home/jun/OpenGL/model/MODEL/niutou.obj", &indexes, vertexCount, indexCount);
  67. if (vertexes==nullptr)
  68. {
  69. printf("load obj model fail\n");
  70. }
  71. //obj model -> vbo & ibo
  72. GLuint vbo = CreateBufferObject(GL_ARRAY_BUFFER, sizeof(VertexData) * vertexCount, GL_STATIC_DRAW, vertexes);
  73. GLuint ibo = CreateBufferObject(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * indexCount, GL_STATIC_DRAW, indexes);
  74. printf("vertex count %d index count %d\n",vertexCount,indexCount);
  75.  
  76. glClearColor(41.0f / 255.0f, 71.0f / 255.0f, 121.0f / 255.0f, 1.0f);
  77.  
  78. //ShowWindow(hwnd, SW_SHOW);
  79. //UpdateWindow(hwnd);
  80.  
  81. float identity[] = {
  82. ,,,,
  83. ,,,,
  84. ,,,,
  85. ,,,
  86. };
  87. //创建一个投影矩阵
  88. glm::mat4 model;
  89. model = glm::translate(model, glm::vec3(0.0f, 0.0f, -54.0f));
  90. model = glm::scale(model, glm::vec3(0.2f, 0.2f, 0.2f));
  91. glm::mat4 projection=glm::perspective(45.0f,800.0f/600.0f,0.1f,1000.0f);
  92.  
  93. glEnable(GL_DEPTH_TEST);
  94. glEnable(GL_CULL_FACE);
  95.  
  96. while (!glfwWindowShouldClose(window))
  97. {
  98. GLfloat currentFrame = (GLfloat)glfwGetTime();
  99. deltaTime = currentFrame - lastFrame;
  100. lastFrame = currentFrame;
  101. glfwPollEvents();
  102.  
  103. // glClearColor(1.0f, 0.04f, 0.14f, 1.0f);
  104.  
  105. glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  106. glUseProgram(program);
  107. glUniformMatrix4fv(MLocation, , GL_FALSE, glm::value_ptr(model));
  108. glUniformMatrix4fv(VLocation, , GL_FALSE, identity);
  109. glUniformMatrix4fv(PLocation, , GL_FALSE, glm::value_ptr(projection));
  110.  
  111. glBindBuffer(GL_ARRAY_BUFFER, vbo);
  112. glEnableVertexAttribArray(posLocation);
  113. glVertexAttribPointer(posLocation, , GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*));
  114. glEnableVertexAttribArray(texcoordLocation);
  115. glVertexAttribPointer(texcoordLocation, , GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)(sizeof(float) * ));
  116. glEnableVertexAttribArray(normalLocation);
  117. glVertexAttribPointer(normalLocation, , GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)(sizeof(float) * ));
  118.  
  119. glBindBuffer(GL_ARRAY_BUFFER, );
  120. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
  121. glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, );
  122. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, );
  123. glUseProgram();
  124. glfwSwapBuffers(window);
  125.  
  126. }
  127.  
  128. glfwTerminate();
  129. return ;
  130. }

mish.h

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

mish.cpp

  1. #include "misc.h"
  2. #include <stdio.h>
  3.  
  4. GLuint CreateBufferObject(GLenum bufferType, GLsizeiptr size, GLenum usage, void*data /* = nullptr */)
  5. {
  6. GLuint object;
  7. glGenBuffers(, &object);
  8. glBindBuffer(bufferType, object);
  9. glBufferData(bufferType, size, data, usage);
  10. glBindBuffer(bufferType, );
  11. return object;
  12. }
  13.  
  14. char *LoadFileContent(const char*path)
  15. {
  16. FILE*pFile = fopen(path, "rb");
  17. if (pFile)
  18. {
  19. fseek(pFile, , SEEK_END);
  20. int nLen = ftell(pFile);
  21. char*buffer = nullptr;
  22. if (nLen!=)
  23. {
  24. buffer=new char[nLen + ];
  25. rewind(pFile);
  26. fread(buffer, nLen, , pFile);
  27. buffer[nLen] = '\0';
  28. }
  29. else
  30. {
  31. printf("load file fail %s content len is 0\n", path);
  32. }
  33. fclose(pFile);
  34. return buffer;
  35. }
  36. else
  37. {
  38. printf("open file %s fail\n",path);
  39. }
  40. fclose(pFile);
  41. return nullptr;
  42. }

model.h

  1. struct VertexData
  2. {
  3. float position[];
  4. float texcoord[];
  5. float normal[];
  6. };
  7.  
  8. VertexData*LoadObjModel(const char* filePath,unsigned int **indexes,int&vertexCount,int&indexCount);

model.cpp

  1. #include "model.h"
  2. #include "misc.h"
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <sstream>
  6. #include <vector>
  7.  
  8. VertexData*LoadObjModel(const char* filePath, unsigned int **indexes, int&vertexCount, int&indexCount)
  9. {
  10. char*fileContent = LoadFileContent(filePath);
  11. if (fileContent!=nullptr)
  12. {
  13. //obj model decode
  14. struct VertexInfo
  15. {
  16. float v[];
  17. };
  18.  
  19. struct VertexDefine
  20. {
  21. int positionIndex;
  22. int texcoordIndex;
  23. int normalIndex;
  24. };
  25. std::vector<VertexInfo> positions;
  26. std::vector<VertexInfo> texcoords;
  27. std::vector<VertexInfo> normals;
  28.  
  29. std::vector<unsigned int> objIndexes;// -> opengl indexes
  30. std::vector<VertexDefine> vertices;// -> opengl vertexes
  31.  
  32. std::stringstream ssObjFile(fileContent);
  33. char szOneLine[];
  34. std::string temp;
  35. while (!ssObjFile.eof())
  36. {
  37. memset(szOneLine, , );
  38. ssObjFile.getline(szOneLine,);
  39. if (strlen(szOneLine)>)
  40. {
  41. std::stringstream ssOneLine(szOneLine);
  42.  
  43. if (szOneLine[]=='v')
  44. {
  45. if (szOneLine[]=='t')
  46. {
  47. //vertex coord
  48. ssOneLine >> temp;
  49. VertexInfo vi;
  50. ssOneLine >> vi.v[];
  51. ssOneLine >> vi.v[];
  52. texcoords.push_back(vi);
  53. printf("%s %f,%f\n", temp.c_str(), vi.v[], vi.v[]);
  54. }
  55. else if(szOneLine[]=='n')
  56. {
  57. //normal
  58. ssOneLine >> temp;
  59. VertexInfo vi;
  60. ssOneLine >> vi.v[];
  61. ssOneLine >> vi.v[];
  62. ssOneLine >> vi.v[];
  63. normals.push_back(vi);
  64. printf("%s %f,%f,%f\n", temp.c_str(), vi.v[], vi.v[], vi.v[]);
  65. }
  66. else
  67. {
  68. //position
  69. ssOneLine >> temp;
  70. VertexInfo vi;
  71. ssOneLine >> vi.v[];
  72. ssOneLine >> vi.v[];
  73. ssOneLine >> vi.v[];
  74. positions.push_back(vi);
  75. printf("%s %f,%f,%f\n",temp.c_str(), vi.v[], vi.v[], vi.v[]);
  76. }
  77. }
  78. else if (szOneLine[] == 'f')
  79. {
  80. //face
  81. ssOneLine >> temp;// 'f'
  82. std::string vertexStr;
  83. for (int i=;i<;i++)
  84. {
  85. ssOneLine >> vertexStr;
  86. size_t pos = vertexStr.find_first_of('/');
  87. std::string positionIndexStr = vertexStr.substr(, pos);
  88. size_t pos2 = vertexStr.find_first_of('/', pos + );
  89. std::string texcoordIndexStr = vertexStr.substr(pos + , pos2 - pos - );
  90. std::string normalIndexStr = vertexStr.substr(pos2 + , vertexStr.length() - pos2 - );
  91. VertexDefine vd;
  92. vd.positionIndex = atoi(positionIndexStr.c_str())-;
  93. vd.texcoordIndex = atoi(texcoordIndexStr.c_str()) - ;
  94. vd.normalIndex = atoi(normalIndexStr.c_str()) - ;
  95.  
  96. int nCurrentIndex = -;//indexes
  97. //check if exist
  98. size_t nCurrentVerticeCount = vertices.size();
  99. for (size_t j = ; j < nCurrentVerticeCount; j++)
  100. {
  101. if (vertices[j].positionIndex == vd.positionIndex&&
  102. vertices[j].texcoordIndex == vd.texcoordIndex&&
  103. vertices[j].normalIndex == vd.normalIndex)
  104. {
  105. nCurrentIndex = j;
  106. break;
  107. }
  108. }
  109. if (nCurrentIndex==-)
  110. {
  111. //create new vertice
  112. nCurrentIndex = vertices.size();
  113. vertices.push_back(vd);//vertexes define
  114. }
  115. objIndexes.push_back(nCurrentIndex);
  116. }
  117. }
  118. }
  119. }
  120. printf("face count %u\n",objIndexes.size()/);
  121. //objIndexes->indexes buffer -> ibo
  122. indexCount = (int)objIndexes.size();
  123. *indexes = new unsigned int[indexCount];
  124. for (int i=;i<indexCount;i++)
  125. {
  126. (*indexes)[i] = objIndexes[i];
  127. }
  128. //vertices -> vertexes -> vbo
  129. vertexCount = (int)vertices.size();
  130. VertexData*vertexes = new VertexData[vertexCount];
  131. for (int i=;i<vertexCount;++i)
  132. {
  133. memcpy(vertexes[i].position, positions[vertices[i].positionIndex].v, sizeof(float) * );
  134. memcpy(vertexes[i].texcoord, texcoords[vertices[i].texcoordIndex].v, sizeof(float) * );
  135. memcpy(vertexes[i].normal, normals[vertices[i].normalIndex].v, sizeof(float) * );
  136. }
  137. return vertexes;
  138. }
  139. return nullptr;
  140. }

model.pro

  1. TEMPLATE = app
  2. CONFIG += console c++
  3. CONFIG -= app_bundle
  4. CONFIG -= qt
  5.  
  6. SOURCES += main.cpp \
  7. misc.cpp \
  8. model.cpp
  9.  
  10. LIBS+= -L/usr/lib64 -lGLEW
  11. LIBS +=-L/usr/local/lib -lglfw3 -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -lGL -lpthread -ldl
  12.  
  13. HEADERS += \
  14. misc.h \
  15. model.h

最后的效果:

QT_OPENGL-------- 5.model的更多相关文章

  1. Spring Boot笔记一

    Spring Boot 入门 Spring Boot 简介 > 简化Spring应用开发的一个框架:> 整个Spring技术栈的一个大整合:> J2EE开发的一站式解决方案: 微服务 ...

  2. 【疯狂造轮子-iOS】JSON转Model系列之二

    [疯狂造轮子-iOS]JSON转Model系列之二 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇<[疯狂造轮子-iOS]JSON转Model系列之一> ...

  3. 【疯狂造轮子-iOS】JSON转Model系列之一

    [疯狂造轮子-iOS]JSON转Model系列之一 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 之前一直看别人的源码,虽然对自己提升比较大,但毕竟不是自己写的,很容易遗 ...

  4. 详解树莓派Model B+控制蜂鸣器演奏乐曲

    步进电机以及无源蜂鸣器这些都需要脉冲信号才能够驱动,这里将用GPIO的PWM接口驱动无源蜂鸣器弹奏乐曲,本文基于树莓派Mode B+,其他版本树莓派实现时需参照相关资料进行修改! 1 预备知识 1.1 ...

  5. 【AutoMapper官方文档】DTO与Domin Model相互转换(上)

    写在前面 AutoMapper目录: [AutoMapper官方文档]DTO与Domin Model相互转换(上) [AutoMapper官方文档]DTO与Domin Model相互转换(中) [Au ...

  6. 拨开迷雾,找回自我:DDD 应对具体业务场景,Domain Model 到底如何设计?

    写在前面 除了博文内容之外,和 netfocus 兄的讨论,也可以让你学到很多(至少我是这样),不要错过哦. 阅读目录: 迷雾森林 找回自我 开源地址 后记 毫无疑问,领域驱动设计的核心是领域模型,领 ...

  7. 使用mybatis-generator在自动生成Model类和Mapper文件

    使用mybatis-generator插件可以很轻松的实现mybatis的逆向工程,即,能通过表结构自动生成对应的java类及mapper文件,可以大大提高工作效率,并且它提供了很多自定义的设置可以应 ...

  8. “RazorEngine.Templating.TemplateParsingException”类型的异常在 RazorEngine.NET4.0.dll 中发生,但未在用户代码中进行处理 其他信息: Expected model identifier.

    这个问题是由于在cshtml中 引用了model这个单词  它可能和Model在解析时有冲突. 解决方法:把model换成别的单词就可以了.

  9. QT内省机制、自定义Model、数据库

    本文将介绍自定义Model过程中数据库数据源的获取方法,我使用过以下三种方式获取数据库数据源: 创建 存储对应数据库所有字段的 结构体,将结构体置于容器中返回,然后根据索引值(QModelIndex) ...

  10. iOS自定义model排序

    在开发过程中,可能需要按照model的某种属性排序. 1.自定义model @interface Person : NSObject @property (nonatomic,copy) NSStri ...

随机推荐

  1. 关于Python3 打印中文乱码问题

    解决方案有两种: 在命令行前指定编码 $ PYTHONIOENCODING=utf-8 python test.py hello world 你好,世界 在代码中指定编码 import io impo ...

  2. c++新特性实验(2)类型特性

    1. 基本类型 1.1 增加 long long long long int signed long long signed long long int unsigned long long unsi ...

  3. JS引擎查找属性的原理

    原型继承的原理 不断向上查找 funciton getProperty(obj,prop){ if(obj.hasOwnProperty(prop){ return obj[prop]; }else ...

  4. Thinkphp M方法出错,D方法却可以

    错误回顾: M('Local')->find(); //报错 //错误信息:Table 'test.local' doesn't exist [ SQL语句 ] : SHOW COLUMNS F ...

  5. Linq To SQL和Linq To Object的批量操作InsertAllOnSubmit介绍

    无论是Linq To SQL还是Linq To Object(Entity frameworks)它们都为开发人员提供了Insert操作,及Insert集合操作,即InsertOnSubmit和Ins ...

  6. 安装最新版本 nginx

    有时用操作系统默认安装 yum install apt install , 版本都会低,当然存在的bug 也会有.装最新版本 nginx 需要用他自己的源: sudo add-apt-reposito ...

  7. Python当前进程信息 (os包)

    Python当前进程信息 (os包) 我们在Linux的概念与体系,多次提及进程的重要性.Python的os包中有查询和修改进程信息的函数.学习Python的这些工具也有助于理解Linux体系. (o ...

  8. neo4j遍历和图算法

    阅读更多 这篇blog主要和大家分享一下neo4j中是如何对节点进行遍历,和其中集成的图论的一些常用算法. 遍历 http://docs.neo4j.org.cn/tutorials-java-emb ...

  9. 学习JDK1.8集合源码之--PriorityQueue

    1. PriorityQueue简介 PriorityQueue是一种优先队列,不同于普通队列的先进先出原则,优先队列是按照元素的优先级出列,每次出列都是优先级最高的元素.优先队列的应用很多,最典型的 ...

  10. ubuntu上安装nodejs和npm

    在使用npm时,特别注意nodejs的版本问题. 一般选择源码安装