显示obj信息

这篇博客主要介绍在读取WRL转换的OBJ文件后,如何显示OBJ信息,并详细阐述了如何还原WRL的视角设置。同时,由于模型在显示过程中会自动旋转,博主探讨了如何保存这一状态。提供了相关源码文件如tmp.h和test.h,并附带了文件下载链接。
摘要由CSDN通过智能技术生成

其实是承接上一篇读取obj之后的显示。


说明:由于我读取的是wrl转换的obj,所以我还要还原wrl的视角。就是viewpoint。另外,模型自动旋转,又由于需要保存,会自动保存。


tmp.h

#include <Windows.h>
#include <gl/glut.h>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;

#include "readobj.h"

#define max_points 10000
#define max_face 10000
#define max_material 50

//data
static float vn_list[max_points][3];
static float v_list[max_points][3];
static float vt_list[max_points][2];
static float f_list[max_points][10];
static int f_num = 0;

//vertex box
static GLfloat v_box[6];

//texture
static GLuint tex_index[max_material];
static int m_num = 0;

//viewpoint
static viewpoint view =
{
	{-1, -1, -1},
	{-1, -1, -1, -1},
	-1
};

//rotate, mouse
static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;

//move, keyboard
static GLfloat ySignal = 0;

//pic
//save
static string objame;
static char picname[100];
static int picnum = 0;
static int picrows = 0;
static int piccols = 0;

void savePic()
{
	GLint viewPort[4] = {0};
	glGetIntegerv(GL_VIEWPORT, viewPort);

	int nowcols = viewPort[2];
	int nowrows = viewPort[3];

	GLbyte *colorArr = new GLbyte[nowrows*nowcols*3];
	glReadPixels(viewPort[0], viewPort[1], viewPort[2], viewPort[3], GL_RGB, GL_UNSIGNED_BYTE, colorArr);
	for(int i=0; i<nowcols * nowrows * 3; i ++)
	{
		if(colorArr[i] == -1)
		{
			colorArr[i] = 255;
		}
	}

	Mat show = Mat(nowrows, nowcols, CV_8UC3, Scalar::all(0));
	for (int i = 0; i< nowrows; i++)
	{
		for (int j = 0; j< nowcols; j++)
		{
			show.at<Vec3b>(nowrows-i-1, j) = Vec3b(colorArr[(i*nowcols+j)*3+2], colorArr[(i*nowcols+j)*3+1], colorArr[(i*nowcols+j)*3]);
		}
	}

	char tmpname[100];
	sprintf(tmpname, "pic/%s%s%05d.png", objame.c_str(), "_", picnum);
	imwrite(tmpname, show);

	delete []colorArr;
}


void getTex(vector<material> m_vector_list)
{
	//texture
	glEnable(GL_TEXTURE_2D);
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);//默认只显示纹理

	//单字节对齐
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

	//tex_index = new GLuint[m_vector_list.size()];
	assert(m_vector_list.size() < max_material);
	glGenTextures(m_vector_list.size(), tex_index);
	m_num = m_vector_list.size();

	for (int i = 0; i< m_vector_list.size(); i++)
	{
		Mat Src = imread(m_vector_list[i].map_Kd);
		assert(!Src.empty());
		//imshow("Src", Src);
		//waitKey();

		int row = Src.rows;
		int col = Src.cols;

		GLbyte *texture = new GLbyte[row*col*4];

		for (int j = row-1; j>= 0; j--)
		{
			for (int k = 0; k< col; k++)
			{
				texture[((row-j-1)*col+k)*4+0] = Src.at<Vec3b>(j, k)[2];
				texture[((row-j-1)*col+k)*4+1] = Src.at<Vec3b>(j, k)[1];
				texture[((row-j-1)*col+k)*4+2] = Src.at<Vec3b>(j, k)[0];
				texture[((row-j-1)*col+k)*4+3] = 255;
			}
		}

		glBindTexture(GL_TEXTURE_2D, tex_index[i]);//绑定对象
		glTexImage2D
			(
			GL_TEXTURE_2D,
			0,
			GL_RGBA,
			col,
			row,
			0,
			GL_RGBA,
			GL_UNSIGNED_BYTE,
			texture
			);

		//when texture area is small, bilinear filter the closest mipmap
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		//when texture area is large, bilinear filter the first mipmap
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

		//delete []texture;
	}

	cout<<m_num<<"\tmaterials\n";

	for (int i = 0; i< m_num; i++)
	{
		if (glIsTexture(tex_index[i]));
		{
			cout<<"material\t"<<i<<"\tis loaded"<<endl;
		}
	}
}

void getData
	(
	vector<vertex_normal> vn_vector_list,
	vector<vertex> v_vector_list,
	vector<vertex_texture> vt_vector_list,
	vector<face> f_vector_list,
	vector<material> m_vector_list
	)
{
	//data

	//vn
	//vn_list = new float[vn_vector_list.size()][3];
	assert(vn_vector_list.size() < max_points);

	float tmp_vn_length = 0;

	for (int i = 0; i< vn_vector_list.size(); i++)
	{
		tmp_vn_length = 0;
		for (int j = 0; j< 3; j++)
			tmp_vn_length += vn_vector_list[i][j]*vn_vector_list[i][j];

		tmp_vn_length = sqrt(tmp_vn_length);

		assert(tmp_vn_length != 0);

		for (int j = 0; j< 3; j++)
			vn_list[i][j] = vn_vector_list[i][j]/tmp_vn_length;

	}

	//v_box
	v_box[0] = v_box[2] = v_box[4] = 100000000;
	v_box[1] = v_box[3] = v_box[5] = -100000000;

	for (int i = 1; i< v_vector_list.size(); i++)
	{
		float a, b, c;
		a = v_vector_list[i][0];
		b = v_vector_list[i][1];
		c = v_vector_list[i][2];

		if (a < v_box[0])
		{
			v_box[0] = a;
		}

		if (a > v_box[1])
		{
			v_box[1] = a;
		}

		if (b < v_box[2])
		{
			v_box[2] = b;
		}

		if (b > v_box[3])
		{
			v_box[3] = b;
		}

		if (c < v_box[4])
		{
			v_box[4] = c;
		}

		if (c > v_box[5])
		{
			v_box[5] = c;
		}
	}

	//v,归一化
	//v_list = new float[v_vector_list.size()][3];
	assert(v_vector_list.size() < max_points);

	/*
	for (int i = 0; i< v_vector_list.size(); i++)
		for (int j = 0; j< 3; j++)
			v_list[i][j] = (v_vector_list[i][j] - v_box[2*j])/(v_box[2*j+1] - v_box[2*j])*2-1;
		*/

	//不归一化
	for (int i = 0; i< v_vector_list.size(); i++)
		for (int j = 0; j< 3; j++)
			v_list[i][j] = v_vector_list[i][j];

	//vt
	//vt_list = new float[vt_vector_list.size()][2];
	assert(vt_vector_list.size() < max_points);

	for (int i = 0; i< vt_vector_list.size(); i++)
		for (int j = 0; j< 2; j++)
			vt_list[i][j] = vt_vector_list[i][j];

	//f
	//f_list = new float[f_vector_list.size()][10];
	assert(f_vector_list.size() < max_face);

	for (int i = 0; i< f_vector_list.size(); i++)
		for (int j = 0; j< 10; j++)
			f_list[i][j] = f_vector_list[i][j];

	f_num = f_vector_list.size();

	//texture
	getTex(m_vector_list);
}

void SetupRC(	vector<vertex_normal> vn_vector_list,
	vector<vertex> v_vector_list,
	vector<vertex_texture> vt_vector_list,
	vector<face> f_vector_list,
	vector<material> m_vector_list)
{
	getData(vn_vector_list,
		v_vector_list,
		vt_vector_list,
		f_vector_list,
		m_vector_list);

	//light
	//Light values and coordinates
	GLfloat  ambientLight[] = { 0.2f, 0.2f, 0.2f, 1.0f };
	GLfloat  diffuseLight[] = { 1.0f, 1.0f, 1.0f, 1.0f };
	GLfloat  specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
	GLfloat  specref[] = { 1.0f, 1.0f, 1.0f, 1.0f };

	glEnable(GL_DEPTH_TEST);// Hidden surface removal
	glDepthFunc(1);//设置深度测试函数

	glFrontFace(GL_CCW);		// Counter clock-wise polygons face out
	//glEnable(GL_CULL_FACE);		// Do not calculate inside of jet

	// Enable lighting
	glEnable(GL_LIGHTING);

	// Setup and enable light 0
	glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight);
	glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);
	glLightfv(GL_LIGHT0,GL_SPECULAR, specular);
	glEnable(GL_LIGHT0);

	//只考虑光照,设不设都一样
	// Enable color tracking
	glEnable(GL_COLOR_MATERIAL);

	// Set Material properties to follow glColor values
	glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

	// All materials hereafter have full specular reflectivity
	// with a high shine
	glMaterialfv(GL_FRONT, GL_SPECULAR, specref);
	glMateriali(GL_FRONT, GL_SHININESS, 32);

	// Light blue background
	// 浅紫色 222,160,228
	GLfloat clearColor[3] = {0/255, 0/255, 139.0/255};
	glClearColor(clearColor[0], clearColor[1], clearColor[2], 1.0f );
	glClearDepth(1);

	glEnable(GL_NORMALIZE);
}

void ChangeSize(int w, int h)
{
	//Prevent a divide by zero
	if(h == 0)
		h = 1;

	//Set Viewport to window dimensions
	glViewport(0, 0, w, h);

	//Reset coordinate system
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	float aspect = w*1.0/h;
	gluPerspective(view.fieldOfView/3.141590*180, aspect, v_box[4], v_box[5]);

	//glOrtho (-1, 1, -1, 1, -100, 100);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

// Called to draw scene
void RenderScene(void)
{
	// Black blue background
	//glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
	//glClearDepth(1);

	// Clear the window with current clearing color
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Save the matrix state and do the rotations
	glPushMatrix();

	glTranslatef((v_box[0]+v_box[1])/2, 0, (v_box[4]+v_box[5])/2);
	glRotatef(xRot, 1.0f, 0.0f, 0.0f);
	glRotatef(yRot, 0.0f, 1.0f, 0.0f);
	glTranslatef(-(v_box[0]+v_box[1])/2, 0, -(v_box[4]+v_box[5])/2);

	glPushMatrix();

	glTranslatef(-view.position[0], -view.position[1], -view.position[2]);
	glRotatef(view.orientation[3]/3.141590*180, view.orientation[0], view.orientation[1], view.orientation[2]);
	

	glColor3f(1.0, 1.0, 1.0);

	//M3DVector3f vNormal;	// Storeage for calculated surface normal

	for (int m_now = 0; m_now< m_num; m_now++)
	{
		glBindTexture(GL_TEXTURE_2D, tex_index[m_now]);

		glBegin(GL_TRIANGLES);

		

		for (int i = 0; i< f_num; i++)
		{
			if (f_list[i][9] != m_now)
			{
				continue;
			}

			int vindex[3];
			int nindex[3];
			int tindex[3];

			for (int j = 0; j< 3; j++)
			{
				vindex[j] = f_list[i][3*j];
				tindex[j] = f_list[i][3*j+1];
				nindex[j] = f_list[i][3*j+2];
			}

			for (int j = 0; j< 3; j++)
			{
				glTexCoord2f(vt_list[tindex[j]][0], vt_list[tindex[j]][1]);

				glVertex3f(v_list[vindex[j]][0], v_list[vindex[j]][1], v_list[vindex[j]][2]);
			}
		}
		
		glEnd();
	}

	glPopMatrix();

	// Restore the matrix state
	glPopMatrix();

	// Buffer swap
	glutSwapBuffers();
}

// Respond to arrow keys
void SpecialKeys(int key, int x, int y)
{
	if(key == GLUT_KEY_UP)
		xRot-= 5.0f;

	if(key == GLUT_KEY_DOWN)
		xRot += 5.0f;

	if(key == GLUT_KEY_LEFT)
		yRot -= 5.0f;

	if(key == GLUT_KEY_RIGHT)
		yRot += 5.0f;

	//xRot = (GLfloat)(xRot % 360);
	//yRot = (GLfloat)(yRot % 360);

	// Refresh the Window
	glutPostRedisplay();
}

///
// Called by GLUT library when idle (window not being
// resized or moved)
void TimerFunction(int value)
{
	if (picnum >= 1
		&&picnum <= 121)
	{
		savePic();
	}

	if (picnum >121)
	{
		exit(0);
	}

	picnum++;

	if (ySignal < 3.0f)
	{
		yRot += 0.1f;   // Update Rotation
		ySignal += 0.1f;
	}
	else if (ySignal >= 3.0f 
		&&ySignal < 9)
	{
		yRot -= 0.1f;
		ySignal += 0.1f;
	}
	else if (ySignal >= 9.0f 
		&&ySignal < 12.0f)
	{
		yRot += 0.1f;
		ySignal += 0.1f;
	}

	//xRot = (GLfloat)(xRot % 360);
	//yRot = (GLfloat)(yRot % 360);

	// Redraw the scene
	glutPostRedisplay();

	// Reset timer
	glutTimerFunc(33, TimerFunction, 1);
}

void showobj
	(
	vector<vertex_normal> vn_vector_list,
	vector<vertex> v_vector_list,
	vector<vertex_texture> vt_vector_list,
	vector<face> f_vector_list,
	vector<material> m_vector_list,
	char *objname,
	viewpoint tmp
	)
{
	view = tmp;

	objame = string(objname);

	int w_col = 800;
	int w_row = 600;

	glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
	glutInitWindowSize(w_col, w_row);
	glutInitWindowPosition(200, 200);
	glutCreateWindow("Fuck OpenGL");

	glutReshapeFunc(ChangeSize);
	glutSpecialFunc(SpecialKeys);
	glutDisplayFunc(RenderScene);
	glutTimerFunc(33, TimerFunction, 1);

	SetupRC(vn_vector_list,
		v_vector_list,
		vt_vector_list,
		f_vector_list,
		m_vector_list);

	glutMainLoop();
}

test.h

#include "tmp.h"

int main()
{
	char* objname = "p1010770.obj";
	//char* objname = "candies.obj";

	viewpoint tmp =
	{
		{-0.00, 176.64, -0.00},
		{0, 1, 0, 3.141590},
		0.78
	};

	vector<vertex_normal> vn_vector_list;
	vector<vertex> v_vector_list;
	vector<vertex_texture> vt_vector_list;	
	vector<face> f_vector_list;

	vector<material> m_list;

	readobj(
		objname,
		vn_vector_list,
		v_vector_list,
		vt_vector_list,
		f_vector_list,
		m_list
		);

	cout<<"\n"<<v_vector_list.size()-1<<" vertices, ";
	cout<<vn_vector_list.size()-1<<" vertices normals"<<endl;

	cout<<f_vector_list.size()<<" faces, ";
	cout<<vt_vector_list.size()-1<<" coords texture"<<endl;

	cout<<"\n"<<m_list.size()<<" material\n"<<endl;

	//system("pause");

	showobj(vn_vector_list, v_vector_list, vt_vector_list, f_vector_list, m_list, objname, tmp);

	//system("pause");

	return 0;
}

over。另外,文件包在这里,http://download.csdn.net/detail/lcbwlx/7147385




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值