资源描述
#include <stdlib.h>
#include <GL/glut.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include<cmath>
using namespace std;
int v_num = 0; //记录点的数量
int f_num = 0; //记录面的数量
int vn_num = 0;//记录法向量的数量
int vt_num = 0;
GLfloat **vArr; //存放点的二维数组
int **fvArr; //存放面顶点的二维数组
int **fnArr;//存放面法向量的二维数组
int **ftArr;
GLfloat **vtArr;
GLfloat **vnArr;//存放法向量的二维数组
string s1, s2, s3, s4;
GLfloat f2, f3, f4;
void getLineNum(string addrstr) //获取点和面的数量
{
ifstream infile(addrstr.c_str()); //打开指定文件
string sline;//每一行
int i = 0, j = 0;
while (getline(infile, sline)) //从指定文件逐行读取
{
if (sline[0] == 'v')
{
if (sline[1] == 'n')
{
vn_num++;
}
else if
(sline[1] == 't')
{
vt_num++;
}
else
{
v_num++;
}
}
if (sline[0] == 'f')
{
f_num++;
}
}
}
int readfile(string addrstr) //将文件内容读到数组中去
{
//getLineNum(addrstr);
//new二维数组
vArr = new GLfloat*[v_num];
for (int i = 0; i<v_num; i++)
{
vArr[i] = new GLfloat[3];
}
vnArr = new GLfloat*[vn_num];
for (int i = 0; i<vn_num; i++)
{
vnArr[i] = new GLfloat[3];
}
vtArr = new GLfloat*[vt_num];
for (int i = 0; i<vt_num; i++)
{
vtArr[i] = new GLfloat[2];
}
fvArr = new int*[f_num];
fnArr = new int*[f_num];
ftArr = new int*[f_num];
for (int i = 0; i<f_num; i++)
{
fvArr[i] = new int[3];
fnArr[i] = new int[3];
ftArr[i] = new int[2];
}
ifstream infile(addrstr.c_str());
string sline;//每一行
int ii = 0, jj = 0, kk = 0, mm = 0;
while (getline(infile, sline))
{
if (sline[0] == 'v')
{
if (sline[1] == 'n')//vn
{
istringstream sin(sline);
sin >> s1 >> f2 >> f3 >> f4;
vnArr[ii][0] = f2;
vnArr[ii][1] = f3;
vnArr[ii][2] = f4;
ii++;
}
else if (sline[1] == 't')
{
istringstream sin(sline);
sin >> s1 >> f2 >> f3 ;
cout << f2 << f3;
vtArr[mm][0] = f2;
vtArr[mm][1] = f3;
// vtArr[mm][2] = f4;
mm++;
}
else//v
{
istringstream sin(sline);
sin >> s1 >> f2 >> f3 >> f4;
vArr[jj][0] = f2;
vArr[jj][1] = f3;
vArr[jj][2] = f4;
jj++;
}
}
if (sline[0] == 'f') //存储面
{
istringstream in(sline);
GLfloat a;
in >> s1;//去掉f
int i, k;
for (i = 0; i < 3; i++)
{
in >> s1;
cout << s1 << endl;
//取出第一个顶点和法线索引
a = 0;
//int len = sizeof(s1);
int len = s1.length();
cout << len;
for (int m = 0; m <len; m++)
{
if (s1[m] != '/')
{
a = a * 10 + (s1[m] - 48);
fvArr[kk][i] = a;
}
else{
m++;
if (m <=3)
{
if (s1[m] != '/')
{
a = a * 10 + (s1[m] - 48);
ftArr[kk][i] = a;
}
else{
m++;
a = a * 10 + (s1[m] - 48);
fnArr[kk][i] = a;
}
}
else{
// m++;
a = a * 10 + (s1[m] - 48);
fnArr[kk][i] = a;
}
}
}
//for (k = 0; s1[k] != '/'; k++)
// {
//a = a * 10 + (s1[k] - 48);
// }
// fvArr[kk][i] = a;
// a = 0;
//for (k = k + 2; s1[k]; k++)
// {
// a = a * 10 + (s1[k] - 48);
// }
// fnArr[kk][i] = a;
}
kk++;
}
}
return 0;
}
void init(void)
{
getLineNum("Eight.obj");
readfile("Eight.obj");
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 50.0 };//材料的镜面指数,其值越大越精细
GLfloat light_position[] = { 1.0, 1.0f, 1.0, 0.0 };
GLfloat white_light[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat lmodel_ambient[] = { 0.1, 0.1, 0.1, 1.0 };
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);//光源位置
glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);//漫反射光源
glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);//镜面反射光源
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);//环境光源
glEnable(GL_LIGHTING);//启动光照
glEnable(GL_LIGHT0);//启用0度光源
glEnable(GL_DEPTH_TEST);//启动深度测试
/*
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // 黑色背景
glClearDepth(1.0f); // 深度缓冲区设置
glEnable(GL_DEPTH_TEST); // 允许深度测试
glDepthFunc(GL_LEQUAL); // 定义深度测试类型
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculation
*/
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//gluLookAt(-2.0, -2.0, -2.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); //设置观察的位置
glTranslatef(1.0, -0.0, -8.0);
glScalef(0.1, 0.1, 0.1);
for (int i = 0; i<f_num; i++)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glBegin(GL_TRIANGLES);
if (vn_num == 0)
{
//glNormal3f(vnArr[fnArr[i][0] - 1][0], vnArr[fnArr[i][0] - 1][1], vnArr[fnArr[i][0] - 1][2]);
glVertex3f(vArr[fvArr[i][0] - 1][0], vArr[fvArr[i][0] - 1][1], vArr[fvArr[i][0] - 1][2]);
//glNormal3f(vnArr[fnArr[i][1] - 1][0], vnArr[fnArr[i][1] - 1][1], vnArr[fnArr[i][1] - 1][2]);
glVertex3f(vArr[fvArr[i][1] - 1][0], vArr[fvArr[i][1] - 1][1], vArr[fvArr[i][1] - 1][2]);
//glNormal3f(vnArr[fnArr[i][2] - 1][0], vnArr[fnArr[i][2] - 1][1], vnArr[fnArr[i][2] - 1][2]);
glVertex3f(vArr[fvArr[i][2] - 1][0], vArr[fvArr[i][2] - 1][1], vArr[fvArr[i][2] - 1][2]);
}
else
{
glTexCoord2f(vtArr[ftArr[i][0] - 1][0], vtArr[ftArr[i][0] - 1][1]);
// glNormal3f(vnArr[fnArr[i][0] - 1][0], vnArr[fnArr[i][0] - 1][1], vnArr[fnArr[i][0] - 1][2]);
glVertex3f(vArr[fvArr[i][0] - 1][0], vArr[fvArr[i][0] - 1][1], vArr[fvArr[i][0] - 1][2]);
glTexCoord2f(vtArr[ftArr[i][1] - 1][0], vtArr[ftArr[i][1] - 1][1]);
// glNormal3f(vnArr[fnArr[i][1] - 1][0], vnArr[fnArr[i][1] - 1][1], vnArr[fnArr[i][1] - 1][2]);
glVertex3f(vArr[fvArr[i][1] - 1][0], vArr[fvArr[i][1] - 1][1], vArr[fvArr[i][1] - 1][2]);
glTexCoord2f(vtArr[ftArr[i][2] - 1][0], vtArr[ftArr[i][2] - 1][1]);
// glNormal3f(vnArr[fnArr[i][2] - 1][0], vnArr[fnArr[i][2] - 1][1], vnArr[fnArr[i][2] - 1][2]);
glVertex3f(vArr[fvArr[i][2] - 1][0], vArr[fvArr[i][2] - 1][1], vArr[fvArr[i][2] - 1][2]);
}
glEnd();
}
glFlush();//强制绘图
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h); //视口设置
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)//描绘了两种不同情况下的平行修剪空间
glOrtho(-1.5, 1.5, -1.5 * (GLfloat)h / (GLfloat)w, 1.5 * (GLfloat)h / (GLfloat)w, -10.0, 10.0);
else
glOrtho(-1.5*(GLfloat)w / (GLfloat)h, 1.5*(GLfloat)w / (GLfloat)h, -1.5, 1.5, -10.0, 10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);//对GLUT进行初始化
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);//设置显示方式,单缓冲、RGB颜色
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
//glutCreateWindow(argv[0]);
glutCreateWindow("Test");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
◆cube.obj文件
没有运用光照时输出的模型:
①点:
②边:
③面:
运用光照时输出的模型:
①通过顶点法向量画出:
②通过面的法向量画出:
③画出面的法向量
移动某个顶点:
◆bunny.obj文件
没有运用光照时输出的模型:
①点:
②边:
③面:
运用光照时输出的模型:
①通过顶点法向量画出:
②通过面的法向量画出:
③画出面的法向量:
◆Eight.obj文件
没有运用光照时输出的模型:
①点:
②边:
③面:
运用光照时输出的模型:
①通过顶点法向量画出:
②通过面的法向量画出:
③画出面的法向量:
展开阅读全文