光照 + 逆向运动 + 纹理
#include<GL/glut.h>
#include <iostream>
#include <cmath>
using namespace std;
GLfloat no_mat[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat mat_ambient[] = { 0.7, 0.7, 0.7, 1.0 };
GLfloat mat_ambient_color[] = { 0.8, 0.8, 0.2, 1.0 };
GLfloat mat_diffuse[] = { 0.1, 0.2, 0.8, 1.0 };
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat no_shininess[] = { 0.5 };
GLfloat low_shininess[] = { 5.0 };
GLfloat high_shininess[] = { 100.0 };
GLfloat mat_emission[] = { 0.3, 0.2, 0.2, 0.0 };
float pyzy = 0, pyqh = 0, pysx = 0;
float times = 1;
float anglezy = 0, anglesx = 0;
float py_speed = 10;
float xx = 4, yy = 5, zz = 20;
float angle1 = 1.0, angle2 = 1.0, angle3 = 1.0;
float xOffset = 0, yOffset = 0;
float xPre = 0, yPre = 6;
float l1 = 3, l2 = 3;
#define stripeImageWidth 10
GLubyte stripeImage[4 * stripeImageWidth];
static GLuint texName;
/* planes for texture coordinate generation */
static GLfloat xequalzero[] = { 1.0, 0.0, 0.0, 0.0 };
static GLfloat slanted[] = { 1.0, 1.0, 1.0, 0.0 };
static GLfloat *currentCoeff;
static GLenum currentPlane;
static GLint currentGenMode;
void makeStripeImage(void) {
int j;
for (j = 0; j < stripeImageWidth; j++) {
stripeImage[4 * j] = (GLubyte)((j <= 4) ? 255 : 0);
stripeImage[4 * j + 1] = 255;//(GLubyte)((j > 4) ? 255 : 0);
stripeImage[4 * j + 2] = (GLubyte)0;
stripeImage[4 * j + 3] = (GLubyte)255;
}
}
void init(void) {
GLfloat ambient[] = { 0.5f, 0.5f, 0.5f, 1.0f }; //环境光参数,半亮白色
GLfloat diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f }; //漫射光参数,
GLfloat position[] = { -10.0f, 10.0f, 0.0f, 1.0f }; //光源位置
GLfloat lmodel_ambient[] = { 0.7, 0.7, 0.7, 1.0 };
GLfloat local_view[] = { 0.0 };
glClearColor(0, 0, 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);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
}
void draw_belly(void) {
glPushMatrix();
glRotatef(angle1, 0, 0, 1);
glColor3f(0.0, 1.0, 0.0);
glTranslatef(0, 1, 0);
glutSolidCube(2);
glColor3f(0.0, 0.0, 1.0);
glTranslatef(0, 2, 0);
glRotatef(angle2, 0, 0, 1);
glutWireSphere(1, 200, 500);
makeStripeImage();
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_1D, texName);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, stripeImageWidth, 0,
GL_RGBA, GL_UNSIGNED_BYTE, stripeImage);
// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
currentCoeff = xequalzero;
currentGenMode = GL_OBJECT_LINEAR;
currentPlane = GL_OBJECT_PLANE;
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, currentGenMode);
glTexGenfv(GL_S, currentPlane, currentCoeff);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_1D);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
glFrontFace(GL_CW);
glMaterialf(GL_FRONT, GL_SHININESS, 64.0);
glColor3f(0.0, 1.0, 0.0);
glTranslatef(0, 2, 0);
glutSolidCube(2);
glDisable(GL_TEXTURE_1D);
glPopMatrix();
}
void draw_ball() {
glPushMatrix();
glColor3f(0.0, 0.7, 0.7);
glTranslatef(xOffset, yOffset, 0);
glutWireSphere(0.5, 200, 500);
glPopMatrix();
}
void draw_move_leg(void) {
if (xOffset*xOffset + yOffset * yOffset >= 36 || xOffset * xOffset + yOffset * yOffset <= 4) {
printf("Wrong\n");
return;
}
glPushMatrix();
float Ja[2][2];
Ja[0][0] = -1.0 * l1 * sin(angle1) - l2 * sin(angle1 + angle2);
Ja[0][1] = -1.0 * l2 * sin(angle1 + angle2);
Ja[1][0] = l1 * cos(angle1) + l2 * cos(angle1 + angle2);
Ja[1][1] = l2 * cos(angle1 + angle2);
float x_par = Ja[0][0] * Ja[1][1] - Ja[0][1] * Ja[1][0];
float JaI[2][2];
JaI[0][0] = Ja[1][1] / x_par;
JaI[0][1] = -1 * Ja[0][1] / x_par;
JaI[1][0] = -1 * Ja[1][0] / x_par;
JaI[1][1] = Ja[0][0] / x_par;
printf("%f,%f,%f,%f\n", JaI[0][0], JaI[0][0], JaI[0][1], JaI[1][0], JaI[1][1]);
//float dy = yOffset - (6 - l1 * cos(angle1) - l2 * cos(angle1 + angle2));
//float dx = xOffset - (-1* l1 * sin(angle1) - l2 * sin(angle1 + angle2));
float dy = yOffset - yPre;
float dx = xOffset - xPre;
float theta1 = JaI[0][0] * dy + JaI[0][1] * dx;
float theta2 = JaI[1][0] * dy + JaI[1][1] * dx;
angle1 += theta1;
angle2 += theta2;
printf("%f, %f\n", xOffset, yOffset);
printf("%f, %f\n", theta1, theta2);
printf("%f, %f\n", angle1, angle2);
yPre = yOffset;
xPre = xOffset;
glPopMatrix();
}
void draw_move(void) {
if (xOffset*xOffset + yOffset * yOffset >= 36 || xOffset * xOffset + yOffset * yOffset <= 4) {
printf("Wrong\n");
return;
}
if (xOffset > 0) {
yOffset = -1 * yOffset;
}
float summ = yOffset * yOffset + xOffset * xOffset;
float alph3 = acos((summ - l1 * l1 - l2 * l2) / (-2 * l1*l2));
alph3 = alph3 * 180 / 3.14;
angle2 = 180 - alph3;
float alph1 = acos((l2*l2 - l1 * l1 - summ) / (-2 * l1*sqrt(summ)));
float alph2 = atan(yOffset / xOffset);
alph1 = alph1 * 180 / 3.14;
alph2 = alph2 * 180 / 3.14;
angle1 = 90 - alph1 + alph2;
if (xOffset >= 0) {
angle1 = 360 - angle1;
angle2 = 360 - angle2;
yOffset = -1 * yOffset;
}
printf("%f, %f \n", xOffset, yOffset);
printf("%f,%f \n", angle1, angle2);
}
void draw_float(void) {
glPushMatrix();
glColor3f(0.9f, 0.9f, 0.9f);
glBegin(GL_QUADS);
glVertex3f(-100.0f, -5.0f, -100.0f);
glVertex3f(-100.0f, -5.0f, 100.0f);
glVertex3f(100.0f, -5.0f, 100.0f);
glVertex3f(100.0f, -5.0f, -100.0f);
glEnd();
glPopMatrix();
}
void draw_xyz() {
glPushMatrix();
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_LINES);
glVertex3f(0.0f, -10.0f, 0.0f); //直线起始坐标
glVertex3f(0.0f, 10.0f, 0.0f); //直线结束坐标
glEnd();
glBegin(GL_LINES);
glVertex3f(-10.0f, 0.0f, 0.0f); //直线起始坐标
glVertex3f(10.0f, 0.0f, 0.0f); //直线结束坐标
glEnd();
glBegin(GL_LINES);
glVertex3f(0.0f, 0.0f, -10.0f); //直线起始坐标
glVertex3f(0.0f, 0.0f, 10.0f); //直线结束坐标
glEnd();
glPopMatrix();
}
void display(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(pyzy, pyqh, pysx);
glScalef(times, times, times);
glRotatef(anglezy, 0.0, 0.0, 1.0);
glRotatef(anglesx, 1.0, 0.0, 0.0);
draw_float();
draw_xyz();
draw_belly();
draw_ball();
glPopMatrix();
glutSwapBuffers();
}
void reshape(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-15, 15, -15, 15, -50, 30);
// gluPerspective(60, 1.0*w/h, 1, 10);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//gluLookAt(r*cos(c*degree), 5, r*sin(c*degree), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
gluLookAt(xx, yy, zz, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
void keyboard(unsigned char key, int x, int y) {
switch (key) {
case 'a':
angle1 += 10;
glutPostRedisplay();
break;
case 's':
angle2 += 10;
glutPostRedisplay();
break;
case 'd':
angle3 += 10;
glutPostRedisplay();
break;
case 'q':
angle1 -= 10;
glutPostRedisplay();
break;
case 'w':
angle2 -= 10;
glutPostRedisplay();
break;
case 'e':
angle3 -= 10;
glutPostRedisplay();
break;
case 'i':
xx++;
glutPostRedisplay();
break;
case '8':
anglesx -= 10.0;
glutPostRedisplay();
break;
case '2':
anglesx += 10.0;
glutPostRedisplay();
break;
case '4':
anglezy += 10.0;
glutPostRedisplay();
break;
case '6':
anglezy -= 10.0;
glutPostRedisplay();
break;
case '+':
times += 0.02f;
glutPostRedisplay();
break;
case '-':
times -= 0.02f;
glutPostRedisplay();
break;
case 'W':
pyqh += py_speed;
glutPostRedisplay();
break;
case 'S':
pyqh -= py_speed;
glutPostRedisplay();
break;
case 'A':
pyzy -= py_speed;
glutPostRedisplay();
break;
case 'D':
pyzy += py_speed;
glutPostRedisplay();
break;
case 'Q':
pysx -= py_speed;
glutPostRedisplay();
break;
case 'E':
pysx += py_speed;
glutPostRedisplay();
break;
case 'R':
pysx = pyzy = pyqh = anglezy = anglesx = 0.0;
times = 1.0;
glutPostRedisplay();
break;
case 'z':
draw_move();
glutPostRedisplay();
break;
}
}
void SpecialKey(GLint key, GLint x, GLint y) {
if (key == GLUT_KEY_UP) {
yOffset += 0.2;
draw_move();
glutPostRedisplay();
}
if (key == GLUT_KEY_LEFT) {
xOffset -= 0.2;
draw_move();
glutPostRedisplay();
}
if (key == GLUT_KEY_DOWN) {
yOffset -= 0.2;
draw_move();
glutPostRedisplay();
}
if (key == GLUT_KEY_RIGHT) {
xOffset += 0.2;
draw_move();
glutPostRedisplay();
}
glutPostRedisplay();
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RED | GLUT_RGBA);
glutInitWindowSize(600, 600);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutSpecialFunc(SpecialKey);
glutMainLoop();
return 0;
}
读取off文件并呈现
// lab2_sam.cpp :
//
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <assert.h>
#include <time.h>
#include<string>
#include<vector>
#include<iostream>
using namespace std;
// Windows include files
#ifdef _WIN32
#include <windows.h>
#endif
// OpenGL include files
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
float pyzy = 0, pyqh = 0, pysx = 0;
float times = 1;
float anglezy = 0, anglesx = 0;
float py_speed = 0.3;
typedef struct Vertex
{
float x,y,z;
}Vertex;
typedef struct Facep
{
int num;
int order[3];
}Facep;
//static char *filename="boxcube.off";
static char *filename = "bird.off";
Vertex ver[10000];
Facep fap[20000];
int i,j,k,n_node,n_face,n_edge;
float scale=1,spin=0;
static int window_height = 800;
static int window_width = 800;
int readoff(const char* filename){
FILE *fp;
if(!(fp=fopen(filename,"r"))){
fprintf(stderr,"Open fail");
return 0;
}
char buffer[1024];
if(fgets(buffer,1023,fp)){
if(!strstr(buffer,"OFF")){
printf("It's not a OFF FILE");
return 0;
}
if(fgets(buffer,1023,fp)){
sscanf(buffer,"%d %d %d",&n_node,&n_face,&n_edge);
for(i=0;i<n_node;i++){
fgets(buffer,1023,fp);
sscanf(buffer,"%f %f %f",&ver[i].x,&ver[i].y,&ver[i].z);
}
for(i=0;i<n_face;i++){
fgets(buffer,1023,fp);
sscanf(buffer,"%d %d %d %d",&fap[i].num,&fap[i].order[0],&fap[i].order[1],&fap[i].order[2]);
}
}
}
}
void redraw(void){
glClearColor(0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glScalef(scale,scale,scale);
glTranslatef(pyzy, pyqh, pysx);
glRotatef(spin, 0.0, 0.0, 1.0);
glRotatef(anglezy, 0.0, 0.0, 1.0);
glRotatef(anglesx, 1.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
glBegin(GL_TRIANGLES);
for(i=0;i<n_face;i++){
int count=fap[i].order[0];
glVertex3f(ver[count].x,ver[count].y,ver[count].z);
count=fap[i].order[1];
glVertex3f(ver[count].x,ver[count].y,ver[count].z);
count=fap[i].order[2];
glVertex3f(ver[count].x,ver[count].y,ver[count].z);
}
glEnd();
glFlush();
glutSwapBuffers();
}
void keyboard(unsigned char key, int x, int y){
switch(key){
case 'p':glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);glutPostRedisplay();break;
case 'l':glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);glutPostRedisplay();break;
case 'f':glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);glutPostRedisplay();break;
case 'q':exit(1); break;
case 'z':
spin+=10;
glutPostRedisplay();
break;
case 'x':
spin-=10;
glutPostRedisplay();
break;
case 'c':
scale+=0.1;
glutPostRedisplay();
break;
case 'v':
scale-=0.1;
glutPostRedisplay();
break;
case '+':
times += 0.02f;
glutPostRedisplay();
break;
case '-':
times -= 0.02f;
glutPostRedisplay();
break;
case 'W':
pyqh += py_speed;
glutPostRedisplay();
break;
case 'S':
pyqh -= py_speed;
glutPostRedisplay();
break;
case 'A':
pyzy -= py_speed;
glutPostRedisplay();
break;
case 'D':
pyzy += py_speed;
glutPostRedisplay();
break;
case 'Q':
pysx -= py_speed;
glutPostRedisplay();
break;
case 'E':
pysx += py_speed;
glutPostRedisplay();
break;
case 'R':
pysx = pyzy = pyqh = anglezy = anglesx = 0.0;
times = 1.0;
glutPostRedisplay();
break;
}
}
void mouse(int button,int state,int x,int y){
if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN){
scale*=1.1;
glutPostRedisplay();
}
if(button==GLUT_RIGHT_BUTTON && state==GLUT_DOWN){
for(i=0;i<10;i++){
spin=spin+1;
glutPostRedisplay();
glFlush();
}
}
}
void SpecialKey(GLint key, GLint x, GLint y) {
if (key == GLUT_KEY_UP) {
anglesx += 10.0;
glutPostRedisplay();
}
if (key == GLUT_KEY_LEFT) {
anglezy += 10.0;
glutPostRedisplay();
}
if (key == GLUT_KEY_DOWN) {
anglesx -= 10.0;
glutPostRedisplay();
}
if (key == GLUT_KEY_RIGHT) {
anglezy -= 10.0;
glutPostRedisplay();
}
glutPostRedisplay();
}
void init(int *argc, char **argv){
// Open window
glutInit(argc, argv);
glutInitWindowPosition(100, 100);
glutInitWindowSize(window_width, window_height);
glutCreateWindow("OFF MADE BY SAM JJX");
// Initialize GLUT callback functions
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
//glutReshapeFunc(GLUTResize);
glutDisplayFunc(redraw);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutSpecialFunc(SpecialKey);
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
//glutMotionFunc(motion);
glutIdleFunc(0);
}
int main(int argc, char** argv)
{
init(&argc,argv);
readoff(filename);
glutMainLoop();
return 0;
}