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,,&vsCode,nullptr);
glShaderSource(fsShader,,&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(, , width, height);
}
int main(void)
{
GLFWwindow* window; if (!glfwInit())
return -; window = glfwCreateWindow(, , "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -;
}
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 = , indexCount = ;
VertexData*vertexes = LoadObjModel("/home/jun/OpenGL/model/MODEL/niutou.obj", &indexes, vertexCount, indexCount);
if (vertexes==nullptr)
{
printf("load obj model fail\n");
}
//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\n",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[] = {
,,,,
,,,,
,,,,
,,,
};
//创建一个投影矩阵
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, , GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(VLocation, , GL_FALSE, identity);
glUniformMatrix4fv(PLocation, , GL_FALSE, glm::value_ptr(projection)); glBindBuffer(GL_ARRAY_BUFFER, vbo);
glEnableVertexAttribArray(posLocation);
glVertexAttribPointer(posLocation, , GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*));
glEnableVertexAttribArray(texcoordLocation);
glVertexAttribPointer(texcoordLocation, , GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)(sizeof(float) * ));
glEnableVertexAttribArray(normalLocation);
glVertexAttribPointer(normalLocation, , GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)(sizeof(float) * )); glBindBuffer(GL_ARRAY_BUFFER, );
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, );
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, );
glUseProgram();
glfwSwapBuffers(window); } glfwTerminate();
return ;
}
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(, &object);
glBindBuffer(bufferType, object);
glBufferData(bufferType, size, data, usage);
glBindBuffer(bufferType, );
return object;
} char *LoadFileContent(const char*path)
{
FILE*pFile = fopen(path, "rb");
if (pFile)
{
fseek(pFile, , SEEK_END);
int nLen = ftell(pFile);
char*buffer = nullptr;
if (nLen!=)
{
buffer=new char[nLen + ];
rewind(pFile);
fread(buffer, nLen, , pFile);
buffer[nLen] = '\0';
}
else
{
printf("load file fail %s content len is 0\n", path);
}
fclose(pFile);
return buffer;
}
else
{
printf("open file %s fail\n",path);
}
fclose(pFile);
return nullptr;
}
model.h
struct VertexData
{
float position[];
float texcoord[];
float normal[];
}; 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[];
}; 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[];
std::string temp;
while (!ssObjFile.eof())
{
memset(szOneLine, , );
ssObjFile.getline(szOneLine,);
if (strlen(szOneLine)>)
{
std::stringstream ssOneLine(szOneLine); if (szOneLine[]=='v')
{
if (szOneLine[]=='t')
{
//vertex coord
ssOneLine >> temp;
VertexInfo vi;
ssOneLine >> vi.v[];
ssOneLine >> vi.v[];
texcoords.push_back(vi);
printf("%s %f,%f\n", temp.c_str(), vi.v[], vi.v[]);
}
else if(szOneLine[]=='n')
{
//normal
ssOneLine >> temp;
VertexInfo vi;
ssOneLine >> vi.v[];
ssOneLine >> vi.v[];
ssOneLine >> vi.v[];
normals.push_back(vi);
printf("%s %f,%f,%f\n", temp.c_str(), vi.v[], vi.v[], vi.v[]);
}
else
{
//position
ssOneLine >> temp;
VertexInfo vi;
ssOneLine >> vi.v[];
ssOneLine >> vi.v[];
ssOneLine >> vi.v[];
positions.push_back(vi);
printf("%s %f,%f,%f\n",temp.c_str(), vi.v[], vi.v[], vi.v[]);
}
}
else if (szOneLine[] == 'f')
{
//face
ssOneLine >> temp;// 'f'
std::string vertexStr;
for (int i=;i<;i++)
{
ssOneLine >> vertexStr;
size_t pos = vertexStr.find_first_of('/');
std::string positionIndexStr = vertexStr.substr(, pos);
size_t pos2 = vertexStr.find_first_of('/', pos + );
std::string texcoordIndexStr = vertexStr.substr(pos + , pos2 - pos - );
std::string normalIndexStr = vertexStr.substr(pos2 + , vertexStr.length() - pos2 - );
VertexDefine vd;
vd.positionIndex = atoi(positionIndexStr.c_str())-;
vd.texcoordIndex = atoi(texcoordIndexStr.c_str()) - ;
vd.normalIndex = atoi(normalIndexStr.c_str()) - ; int nCurrentIndex = -;//indexes
//check if exist
size_t nCurrentVerticeCount = vertices.size();
for (size_t j = ; j < nCurrentVerticeCount; j++)
{
if (vertices[j].positionIndex == vd.positionIndex&&
vertices[j].texcoordIndex == vd.texcoordIndex&&
vertices[j].normalIndex == vd.normalIndex)
{
nCurrentIndex = j;
break;
}
}
if (nCurrentIndex==-)
{
//create new vertice
nCurrentIndex = vertices.size();
vertices.push_back(vd);//vertexes define
}
objIndexes.push_back(nCurrentIndex);
}
}
}
}
printf("face count %u\n",objIndexes.size()/);
//objIndexes->indexes buffer -> ibo
indexCount = (int)objIndexes.size();
*indexes = new unsigned int[indexCount];
for (int i=;i<indexCount;i++)
{
(*indexes)[i] = objIndexes[i];
}
//vertices -> vertexes -> vbo
vertexCount = (int)vertices.size();
VertexData*vertexes = new VertexData[vertexCount];
for (int i=;i<vertexCount;++i)
{
memcpy(vertexes[i].position, positions[vertices[i].positionIndex].v, sizeof(float) * );
memcpy(vertexes[i].texcoord, texcoords[vertices[i].texcoordIndex].v, sizeof(float) * );
memcpy(vertexes[i].normal, normals[vertices[i].normalIndex].v, sizeof(float) * );
}
return vertexes;
}
return nullptr;
}
model.pro
TEMPLATE = app
CONFIG += console c++
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
最后的效果:

QT_OPENGL-------- 5.model的更多相关文章
- Spring Boot笔记一
Spring Boot 入门 Spring Boot 简介 > 简化Spring应用开发的一个框架:> 整个Spring技术栈的一个大整合:> J2EE开发的一站式解决方案: 微服务 ...
- 【疯狂造轮子-iOS】JSON转Model系列之二
[疯狂造轮子-iOS]JSON转Model系列之二 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇<[疯狂造轮子-iOS]JSON转Model系列之一> ...
- 【疯狂造轮子-iOS】JSON转Model系列之一
[疯狂造轮子-iOS]JSON转Model系列之一 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 之前一直看别人的源码,虽然对自己提升比较大,但毕竟不是自己写的,很容易遗 ...
- 详解树莓派Model B+控制蜂鸣器演奏乐曲
步进电机以及无源蜂鸣器这些都需要脉冲信号才能够驱动,这里将用GPIO的PWM接口驱动无源蜂鸣器弹奏乐曲,本文基于树莓派Mode B+,其他版本树莓派实现时需参照相关资料进行修改! 1 预备知识 1.1 ...
- 【AutoMapper官方文档】DTO与Domin Model相互转换(上)
写在前面 AutoMapper目录: [AutoMapper官方文档]DTO与Domin Model相互转换(上) [AutoMapper官方文档]DTO与Domin Model相互转换(中) [Au ...
- 拨开迷雾,找回自我:DDD 应对具体业务场景,Domain Model 到底如何设计?
写在前面 除了博文内容之外,和 netfocus 兄的讨论,也可以让你学到很多(至少我是这样),不要错过哦. 阅读目录: 迷雾森林 找回自我 开源地址 后记 毫无疑问,领域驱动设计的核心是领域模型,领 ...
- 使用mybatis-generator在自动生成Model类和Mapper文件
使用mybatis-generator插件可以很轻松的实现mybatis的逆向工程,即,能通过表结构自动生成对应的java类及mapper文件,可以大大提高工作效率,并且它提供了很多自定义的设置可以应 ...
- “RazorEngine.Templating.TemplateParsingException”类型的异常在 RazorEngine.NET4.0.dll 中发生,但未在用户代码中进行处理 其他信息: Expected model identifier.
这个问题是由于在cshtml中 引用了model这个单词 它可能和Model在解析时有冲突. 解决方法:把model换成别的单词就可以了.
- QT内省机制、自定义Model、数据库
本文将介绍自定义Model过程中数据库数据源的获取方法,我使用过以下三种方式获取数据库数据源: 创建 存储对应数据库所有字段的 结构体,将结构体置于容器中返回,然后根据索引值(QModelIndex) ...
- iOS自定义model排序
在开发过程中,可能需要按照model的某种属性排序. 1.自定义model @interface Person : NSObject @property (nonatomic,copy) NSStri ...
随机推荐
- java代码乱序问题
java两个线程互相访问的时候并不能按照你的思路运行,因为执行语句可能有前后快慢之分,比如a=1和flag=true.下面线程B访问的时候 这两个赋值语句不一定按顺序执行 产生这种原因是因为指令重排序 ...
- python 与 selenium 学习笔记
在写自动运行测试用例,并且生成HTML报告的时候,遇到了这个报错: UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in positi ...
- Liferay 7:Liferay DXP全套教程内附源码
分享是美德 都是英文教程,有不明白的问题可以随时咨询我. http://www.javasavvy.com/liferay-7-hooks-tutorials/
- element ui table 去掉边框
// /deep/ .el-table { // thead { // .cell { // text-align: left; // table 表头 左对齐 // } // } // .delet ...
- Django项目:CRM(客户关系管理系统)--26--18PerfectCRM实现King_admin搜索关键字
search_fields = ('name','qq',) 登陆密码设置参考 http://www.cnblogs.com/ujq3/p/8553784.html search_fields = ( ...
- TZ_09_自定义Spring-security
1.Spring Security 的前身是 Acegi Security ,是 Spring 项目组中用来提供安全认证服务的框架 2.安全包括两个主要操作. “认证”,是为用户建立一个他所声明的主体 ...
- 理解es6箭头函数
箭头函数知识点很少,但是要理解清楚,不然看代码会很不适应的. 1. 最简单的写法 x => x*x 可以理解为 我的x要被转化为x*x,所以实际相当于下边的这个 function (x){ re ...
- tumblr arch information
http://developer.51cto.com/art/201305/395757.htm 每月超过30%的增长当然不可能没有挑战,其中可靠性问题尤为艰巨.每天5亿次浏览量,峰值每秒4万次请求, ...
- Linux巨好用的
受不了了windows下配置烦死人.linux一站式搞定,无敌 安装python3 机子上py2 py3共存没问题 安装virtualenv (py3)分割实验环境非常稳 安装mysql 先安装了一 ...
- python实例 输出字符串和数字
但有趣的是,在javascript里我们会理想当然的将字符串和数字连接,因为是动态语言嘛.但在Python里有点诡异,如下: #! /usr/bin/python a=2 b="test&q ...