#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <GL/glut.h>
using namespace std;
/*
* Initialize depth buffer, projection matrix, light source, and lighting
* model. Do not specify a material property here.
*/
//改变颜色
GLushort gl_CI = 1;
GLboolean IsNull = 0;
GLfloat gl_R = 0.0, gl_G = 0.0, gl_B = 0.0;
//改变光源位置
GLfloat gl_L_X = 1.0, gl_L_Y = 1.0, gl_L_Z = 5.0;
//读文件
GLboolean IsEmpty = 1;
GLint Vnum = 0;
GLint Fnum = 0;
GLfloat *Vdata = NULL;
GLint *Fdata = NULL;
//旋转
GLint New_x,New_y;
GLint Old_x,Old_y;
GLfloat gl_R_x =0.0, gl_R_y = 0.0;
//缩放
GLfloat gl_S_e = 1.25;
GLfloat gl_S_s = 0.8;
void init(void)
{
GLfloat ambient[] = {0.0, 0.0, 0.0, 1.0}; //环境光,来自周围的环境没有固定方向的光
GLfloat diffuse[] = {1.0, 1.0, 1.0, 1.0}; //漫射光,来自同一个方向,
GLfloat specular[] = {1.0, 1.0, 1.0, 1.0};//镜面反射
//光源位置
GLfloat position[] = {gl_L_X, gl_L_Y, gl_L_Z, 0.0};
GLfloat lmodel_ambient[] = {0.2, 0.2, 0.2, 1.0};
GLfloat local_view[] = {0.0};
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT0, GL_POSITION, position);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view);
glFrontFace(GL_CW);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
glEnable(GL_DEPTH_TEST);
}
void getMatRGB(int Value, GLfloat *matRGB)
{
Value %= 8;
switch (Value)
{
case 1: // 红色
matRGB[0] = 1.0f;
matRGB[1] = 0.0f;
matRGB[2] = 0.0f;
break;
case 2: // 橙色
matRGB[0] = 1.0f;
matRGB[1] = 0.55f;
matRGB[2] = 0.0f;
break;
case 3: // 黄色
matRGB[0] = 1.0f;
matRGB[1] = 1.0f;
matRGB[2] = 0.0f;
break;
case 4: // 绿色
matRGB[0] = 0.0f;
matRGB[1] = 1.0f;
matRGB[2] = 0.0f;
break;
case 5: // 青色
matRGB[0] = 0.0f;
matRGB[1] = 1.0f;
matRGB[2] = 1.0f;
break;
case 6: // 蓝色
matRGB[0] = 0.0f;
matRGB[1] = 0.0f;
matRGB[2] = 1.0f;
break;
case 7: // 紫色
matRGB[0] = 0.55f;
matRGB[1] = 0.0f;
matRGB[2] = 1.0f;
break;
case 0: // 白色
matRGB[0] = 1.0f;
matRGB[1] = 1.0f;
matRGB[2] = 1.0f;
break;
default: //黑色
matRGB[0] = 0.0f;
matRGB[1] = 0.0f;
matRGB[2] = 0.0f;
}
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(8.0, 8.0, 0.0);//平移
//teapot的颜色
//mat[0][0] = 0.0; mat[1] = 0.0; mat[2] = 0.9;
GLfloat mat[4];
if (IsNull)
{
mat[0] = gl_R;
mat[1] = gl_G;
mat[2] = gl_B;
}
else
{
getMatRGB(gl_CI, mat);
}
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat);
if (IsEmpty)
glutSolidTeapot(3.0);
else
{
glRotatef(5.0, 1.0, 0.0, 0.0);
glRotatef(3.0, 0.0, 1.0, 0.0);
glRotatef(4.0, 0.0, 0.0, 1.0);
int J,K;
glBegin(GL_TRIANGLES);
for (int i=0;i<Fnum;i++)
{
getMatRGB(i,mat);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat);
J = i*3;
K = (Fdata[J]-1)*3;
glVertex3f(20*Vdata[K], 20*Vdata[K+1], 20*Vdata[K+2]);
K = (Fdata[J+1]-1)*3;
glVertex3f(20*Vdata[K], 20*Vdata[K+1], 20*Vdata[K+2]);
K = (Fdata[J+2]-1)*3;
glVertex3f(20*Vdata[K], 20*Vdata[K+1], 20*Vdata[K+2]);
}
//for (int i=0;i<Fnum*3;i++)
//{
// getMatRGB(i,mat);
// glMaterialfv(GL_FRONT, GL_DIFFUSE, mat);
// J = i;
// K = (Fdata[J]-1)*3;
// glVertex3f(Vdata[K],Vdata[K+1],Vdata[K+2]);
//}
glEnd();
}
glPopMatrix();
glFlush();
}
bool readfile(const char* filename)
{
FILE *pFile = fopen(filename,"r");
if (pFile == NULL)
return true;
const int buffsize = 50;
char buff[buffsize];
while (!feof(pFile))
{
memset(buff,0,buffsize);
fgets(buff,buffsize,pFile);
if (buff[0] == 'v')
Vnum++;
if (buff[0] == 'f')
Fnum++;
}
if (Vnum>0)
{
Vdata = new GLfloat[Vnum*3];
if (Fnum>0)
Fdata = new GLint[Fnum*3];
}
fseek(pFile,0,SEEK_SET);
int vi=0,fi=0;
char chTemp;
while (!feof(pFile))
{
chTemp = fgetc(pFile);
if ('v' == chTemp)
{
fscanf_s(pFile, "%f", &Vdata[vi++]);
fscanf_s(pFile, "%f", &Vdata[vi++]);
fscanf_s(pFile, "%f", &Vdata[vi++]);
}
else if ('f' == chTemp)
{
fscanf_s(pFile, "%d", &Fdata[fi++]);
fscanf_s(pFile, "%d", &Fdata[fi++]);
fscanf_s(pFile, "%d", &Fdata[fi++]);
}
}
fclose(pFile);
return false;
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(0.0, 16.0, 0.0, 16.0*(GLfloat)h/(GLfloat)w,
-10.0, 10.0);
else
glOrtho(0.0, 16.0*(GLfloat)w/(GLfloat)h, 0.0, 16.0,
-10.0, 10.0);
glMatrixMode(GL_MODELVIEW);
}
void keyboard(unsigned char key, int x, int y)
{
int a = 0;
switch (key)
{
case 27:
exit(0);
break;
case 'c':
gl_CI++;
if (gl_CI%8 == 0)
{
cout<<"Now you can change color by 'r','g','b'gradually\n";
IsNull = 1;
}
break;
case 'r':
gl_R += 0.1;
if(gl_R>1.0001)
gl_R = 0.0;
break;
case 'g':
gl_G += 0.1;
if(gl_G>1.0001)
gl_G = 0.0;
break;
case 'b':
gl_B += 0.1;
if(gl_B>1.0001)
gl_B = 0.0;
break;
default:
printf("Unhandled key press c\n");
break;
}
if (IsNull)
printf("Current R = %f,G = %f,B = %f\n", gl_R, gl_G, gl_B);
glutPostRedisplay();
}
void mouseMove(int x, int y)
{
New_x = x;
New_y = y;
}
void mouseClick(int button, int state, int x, int y)
{
int DvX = 0, DvY = 9;
switch (button)
{
case GLUT_LEFT_BUTTON:
if (GLUT_DOWN == state)
{
Old_x = x;
Old_y = y;
}
else if (GLUT_UP == state)
{
DvX = x - Old_x;
DvY = y - Old_y;
if (abs(DvX) > abs(DvY) )
{
//glTranslatef(-8.0f, 0.0f, 0.0);
glRotatef(DvX/10.0f, 0.0f, 8.0f, 0.0f);
//glTranslatef(8.0f, 0.0f, 0.0);
}
else
{
//glTranslatef(0.0f, -8.0f, 0.0);
glRotatef(DvY/10.0f, 8.0f, 0.0f, 0.0f);
//glTranslatef(0.0f, 8.0f, 0.0);
}
}
break;
case GLUT_MIDDLE_BUTTON:
if (GLUT_DOWN == state)
{
}
else if (GLUT_UP == state)
{
}
break;
case GLUT_RIGHT_BUTTON:
if (GLUT_DOWN == state)
{
if (GLUT_ACTIVE_SHIFT == glutGetModifiers())
glScalef(gl_S_e, gl_S_e, gl_S_e);
else
glScalef(gl_S_s, gl_S_s, gl_S_s);
}
break;
default:
break;
}
glutPostRedisplay();
}
void procesSpecialKey(int key, int x, int y)
{
GLfloat position[] = {gl_L_X, gl_L_Y, 5.0, 0.0};
switch (key)
{
case GLUT_KEY_LEFT:
gl_L_X += 0.5;
break;
case GLUT_KEY_UP:
gl_L_Y += 0.5;
break;
case GLUT_KEY_RIGHT:
gl_L_X -= 0.5;
break;
case GLUT_KEY_DOWN:
gl_L_Y -= 0.5;
break;
}
glLightfv(GL_LIGHT0, GL_POSITION, position);
glutPostRedisplay();
}
/*
* Main Loop
*/
int main(int argc, char **argv)
{
char filename[20] = {0};
//char filename[] = "cube.obj";
cout<<"请输入.obj文件名或t(茶壶)"<<endl;
cin>>filename;
IsEmpty = readfile(filename);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400);
glutInitWindowPosition(200,200);
glutCreateWindow("hello world");
init();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutKeyboardFunc (keyboard);
glutSpecialFunc(procesSpecialKey);
glutMotionFunc(mouseMove);
glutMouseFunc(mouseClick);
glutMainLoop();
if (Fdata != NULL)
{
delete Fdata;
Fdata = NULL;
}
if (Vdata != NULL)
{
delete Vdata;
Vdata = NULL;
}
return 0;
}