obj 文件读取 openGL 显示3D图
程序员文章站
2022-03-26 18:25:46
...
// GenericModel.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <glut.h>
#include "objLoader/AccessObj.h"
/*
cube.obj 文件内容:
# cube
v 1.0000 1.0000 1.0000
v -1.0000 1.0000 1.0000
v -1.0000 -1.0000 1.0000
v 1.0000 -1.0000 1.0000
v 1.0000 1.0000 -1.0000
v -1.0000 1.0000 -1.0000
v -1.0000 -1.0000 -1.0000
v 1.0000 -1.0000 -1.0000
f 1 2 3 4
f 1 5 6 2
f 2 6 7 3
f 3 7 8 4
f 4 8 5 1
f 5 8 7 6
*/
/// 最简单的显示一个cube
void cubeDisplay1()
{
/// 导入obj文件
CAccessObj OBJ;
OBJ.LoadOBJ("cube.obj");
/// 初始化
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/// 为了将图像显示在窗口,看x,y,z轴上的最大值最小值
float x1 = OBJ.m_vMax.x;
float y1 = OBJ.m_vMax.y;
float z1 = OBJ.m_vMax.z;
float x2 = OBJ.m_vMin.x;
float y2 = OBJ.m_vMin.y;
float z2 = OBJ.m_vMin.z;
float ratio[3] = {x1-x2, y1-y2, z1-z2};
/// 依次画每一个面,每个面就是一个三角形
for ( int m=0; m<OBJ.m_pModel->nTriangles; m++ )
{
/// 开始绘制
glBegin(GL_TRIANGLES);
/// 顶点——v
unsigned int *pVertIdx = ( OBJ.m_pModel->pTriangles )[m].VertIdx;
/// 依次画三角形的三个点
for ( int i=0; i<3; i++ )
{
/// 设置颜色
glColor3f(m&i&0x04, m&i&0x02, m&i&0x01);
/// 这里注意,为了显示要除以一个数
float x = ( OBJ.m_pModel->vpVertices )[pVertIdx[i]].x / ratio[0] ;
float y = ( OBJ.m_pModel->vpVertices )[pVertIdx[i]].y / ratio[1] ;
float z = ( OBJ.m_pModel->vpVertices )[pVertIdx[i]].z / ratio[2] ;
glVertex3f( x, y, z );
}
glEnd();
}
/// 旋转
float degree = 45;
glRotatef(degree, 1, 1, 1 );
glFlush();
}
/// 显示一个cube, 加了纹理
void cubeDisplay2()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/// 新建纹理
static float T0[64][64][4];
static GLuint Tname0;
int i, j, c;
// 纹理,渐变绿色,*64
for (i = 0; i < 64; i++) {
for (j = 0; j < 64; j++) {
T0[i][j][0] = (float) 0;
T0[i][j][1] = (float) i * 5 + j * 5;
T0[i][j][2] = (float) 255;
T0[i][j][3] = (float) 255;
}
}
/// 导入obj文件
CAccessObj OBJ;
OBJ.LoadOBJ("cube.obj");
/// 为了将图像显示在窗口,看x,y,z轴上的最大值最小值
float x1 = OBJ.m_vMax.x;
float y1 = OBJ.m_vMax.y;
float z1 = OBJ.m_vMax.z;
float x2 = OBJ.m_vMin.x;
float y2 = OBJ.m_vMin.y;
float z2 = OBJ.m_vMin.z;
float ratio[3] = {x1-x2, y1-y2, z1-z2};
/// 依次画每一个面,每个面就是一个三角形
for ( int m=0; m<OBJ.m_pModel->nTriangles; m++ )
{
glBegin(GL_TRIANGLES);
/// 顶点——v
unsigned int *pVertIdx = ( OBJ.m_pModel->pTriangles )[m].VertIdx;
/// 纹理坐标 texture point ——vt
unsigned int *pTexIdx = ( OBJ.m_pModel->pTriangles )[m].TexIdx;//< 在texture中找对应的点
/// 曲面法线——vn
unsigned int *pNormIdx = ( OBJ.m_pModel->pTriangles )[m].NormIdx;
/// 依次画三角形的三个点
for ( int i=0; i<3; i++ )
{
/// 这里注意,为了显示要除以一个数
float x = ( OBJ.m_pModel->vpVertices )[pVertIdx[i]].x / ratio[0] ;
float y = ( OBJ.m_pModel->vpVertices )[pVertIdx[i]].y / ratio[1] ;
float z = ( OBJ.m_pModel->vpVertices )[pVertIdx[i]].z / ratio[2] ;
/// 我们设定的纹理
int t1 = (x+0.5)*64;
int t2 = (y+0.5)*64;
glColor3f( T0[t1][t2][0], T0[t1][t2][1], T0[t1][t2][2] );
/// 顶点
glVertex3f( x, y, z );
}
glEnd();
}
float degree = 45;
glRotatef(degree, 1, 1, 1 );
/// 旋转
glFlush();
}
/// 显示example10.obj
void ExampleDisplay()
{
/// 导入obj文件
CAccessObj OBJ;
OBJ.LoadOBJ("example10.obj");
/// 为了将图像显示在窗口,看x,y,z轴上的最大值最小值
float x1 = OBJ.m_vMax.x;
float y1 = OBJ.m_vMax.y;
float z1 = OBJ.m_vMax.z;
float x2 = OBJ.m_vMin.x;
float y2 = OBJ.m_vMin.y;
float z2 = OBJ.m_vMin.z;
float ratio[3] = {x1-x2, y1-y2, z1-z2};
///////////////////////////////////////////////////////////
/// 用这幅图像作为纹理
IplImage *img = cvLoadImage( "example10.bmp" );
img->origin = 0;
int w = img->width;
int h = img->height;
///////////////////////////////////////////////////////////
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for ( int m=0; m<OBJ.m_pModel->nTriangles; m++ )
{
glBegin(GL_TRIANGLES);
/// 顶点
unsigned int *pVertIdx = ( OBJ.m_pModel->pTriangles )[m].VertIdx;
/// 纹理坐标 texture point
unsigned int *pTexIdx = ( OBJ.m_pModel->pTriangles )[m].TexIdx; ///< 在texture中找对应的点
for ( int i=0; i<3; i++ )
{
float x = 0;
float y = 0;
float z = 0;
x = ( OBJ.m_pModel->vpTexCoords )[pTexIdx[i]].x * h;
y = ( OBJ.m_pModel->vpTexCoords )[pTexIdx[i]].y * w;
uchar* temp_ptr = &((uchar*)(img->imageData + img->widthStep*((int)y)))[(int)x*3];
glColor3f( (float)temp_ptr[2]/256, (float)temp_ptr[1]/256, (float)temp_ptr[0]/256 );///< 注意顺序
x = ( OBJ.m_pModel->vpVertices )[pVertIdx[i]].x / ratio[0] ;
y = ( OBJ.m_pModel->vpVertices )[pVertIdx[i]].y / ratio[1] ;
z = ( OBJ.m_pModel->vpVertices )[pVertIdx[i]].z / ratio[2] ;
glVertex3f( x, y, z );
}
glEnd();
}
/*float degree = 45;
glRotatef(degree, 1, 1, 1 );*/
glFlush();
cvReleaseImage( &img );
}
int _tmain(int argc, char* argv[])
{
/// 对GLUT进行初始化,这个函数必须在其它的GLUT使用之前调用一次。其格式比较死板,一般照抄这句glutInit(&argc, argv)就可以了。
glutInit( &argc, argv );
/// 设置显示方式
/// GLUT_RGB表示使用RGB颜色,与之对应的还有GLUT_INDEX(表示使用索引颜色)。
/// GLUT_SINGLE表示使用单缓冲,与之对应的还有GLUT_DOUBLE(使用双缓冲)。
glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE );
glutInitWindowPosition( 100, 100 );
glutInitWindowSize( 400, 400 );
glutCreateWindow( "Test" );
/// 这里选择要显示的对象,即上面的三个函数——cubeDisplay1,cubeDisplay2,ExampleDisplay
// glutDisplayFunc( &cubeDisplay1 );
// glutDisplayFunc( &cubeDisplay2 );
glutDisplayFunc( &ExampleDisplay );
glutMainLoop();
return 0;
}
/*
没搞定的几个函数:
glGenTextures(1, &Tname0); // 获取纹理名字
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, T0); // 设置纹理对象内容
glEnable(GL_TEXTURE_2D); // 使纹理可用
glBindTexture(GL_TEXTURE_2D, Tname0); // **纹理
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); // 设置纹理贴图方式
*/
这里调用了网上的一个读obj文件的类。
版权声明:转载http://www.blogbus.com/shijuanfeng-logs/226093549.html上一篇: Android 详解Gradle(3.1.4)实现多渠道打包
下一篇: 94. 二叉树的中序遍历