例程1 可以当做练习,这是学长给的补充代码。可以根据提示写上去。
//This is example1.
// This assignment may cost you some efferts, so I give you some important HINTS, hope that may help you.
// Enjoy the coding and thinking, do pay more attention to the library functions used in OPENGL, such as how they are used?
//what are the parameters used? and why?
// 实验报告里面多写点感想,即对函数的理解,以及调用的顺序,步骤等。思考为什么是这样子调用的,为什么参数是这样子设置的?。。。等等你觉得值得研究的问题。
#include <stdlib.h>
#include <GL/glut.h>
#include <stdbool.h>
float fTranslate;
float fRotate;
float fScale = 1.0f; // set inital scale value to 1.0f
bool bPersp = false;
bool bAnim = false;
bool bWire = false;
int wHeight = 0;
int wWidth = 0;
//todo
//hint: some additional parameters may needed here when you operate the teapot
void Draw_Leg()
{
glScalef(1, 1, 3);
glutSolidCube(1.0);
}
void Draw_Scene()
{
glPushMatrix();
glTranslatef(0, 0, 4+1);
glRotatef(90, 1, 0, 0); //notice the rotation here, you may have a TRY removing this line to see what it looks like.
//todo; hint: when operate the teapot, you may need to change some parameters
glutSolidTeapot(1);
glPopMatrix();
//draw complete table.
glPushMatrix();
glTranslatef(0, 0, 3.5);
glScalef(5, 4, 1);
glutSolidCube(1.0);
glPopMatrix();
glPushMatrix();
glTranslatef(1.5, 1, 1.5);
Draw_Leg();
glPopMatrix();
glPushMatrix();
glTranslatef(-1.5, 1, 1.5);
Draw_Leg();
glPopMatrix();
glPushMatrix();
glTranslatef(1.5, -1, 1.5);
Draw_Leg();
glPopMatrix();
glPushMatrix();
glTranslatef(-1.5, -1, 1.5);
Draw_Leg();
glPopMatrix();
//completed
}
void updateView(int width, int height)
{
glViewport(0,0,width,height); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
float whRatio = (GLfloat)width/(GLfloat)height; //reset the ratio of width and height
if (bPersp){ //bPersp is a parameter when it equals 1 then select perspective else ortho
gluPerspective(65.0, whRatio, 1.0,100.0); // temporarily answer
//todo when 'p' operation, hint: use FUNCTION gluPerspective
}
else
glOrtho(-3 ,3, -3, 3,-100,100);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
}
void reshape(int width, int height)
{
if (height==0) // Prevent A Divide By Zero By
{
height=1; // Making Height Equal One
}
wHeight = height;
wWidth = width;
updateView(wHeight, wWidth);
}
/*
void reshape (int width ,int height )
{
if (height == 0)
height = 1;
glViewport(0.0, 0.0, width, height); //default
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (bPersp){
gluPerspective(65.0, (GLfloat)width/(GLfloat)height; , 1.0,100.0);
}
else
glOrtho(-3 ,3, -3, 3,-100,100);
glMatrixMode(GL_MODELVIEW); //default
glLoadIdentity(); //default
}
*/
void idle()
{
glutPostRedisplay(); //
}
float eye[] = {0, 0, 8};
float center[] = {0, 0, 0};
//todo; hint: you may need another ARRAY when you operate the teapot
void key(unsigned char k, int x, int y)
{
switch(k)
{
case 27:
case 'q': {exit(0); break; }
case 'p': {bPersp = !bPersp; updateView(wHeight, wWidth);break; }
case ' ': {bAnim = !bAnim; break;}
case 'o': {bWire = !bWire; break;}
case 'a': {//todo, hint: eye[] and center[] are the keys to solve the problems
break;
}
case 'd': {//todo
break;
}
case 'w': {//todo
break;
}
case 's': {//todo
break;
}
case 'z': {//todo
break;
}
case 'c': {//todo
break;
}
//茶壶相关操作
case 'l': {//todo, hint:use the ARRAY that you defined, and notice the teapot can NOT be moved out the range of the table.
break;
}
case 'j': {//todo
break;
}
case 'i': {//todo
break;
}
case 'k': {//todo
break;
}
case 'e': {//todo
break;
}
}
}
void redraw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity(); // Reset The Current Modelview Matrix
gluLookAt(eye[0], eye[1], eye[2],
center[0], center[1], center[2],
0, 1, 0); // 场景(0,0,0)的视点中心 (0,5,50),Y轴向上
if (bWire) {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
else {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_pos[] = {5,5,5,1};
glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
glLightfv(GL_LIGHT0, GL_AMBIENT, white);
glEnable(GL_LIGHT0);
// glTranslatef(0.0f, 0.0f,-6.0f); // Place the triangle at Center
glRotatef(fRotate, 0, 1.0f, 0); // Rotate around Y axis
glRotatef(-90, 1, 0, 0);
glScalef(0.2, 0.2, 0.2);
Draw_Scene(); // Draw Scene
if (bAnim) fRotate += 0.5f;
//todo; hint: when you want to rotate the teapot, you may like to add another line here =)
glutSwapBuffers();
}
int main (int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(480,480);
glutWindowPosition(100,100);
glutCreateWindow("Simple GLUT App");
glutDisplayFunc(redraw);
glutReshapeFunc(reshape);
glutKeyboardFunc(key);
glutIdleFunc(idle);
glutMainLoop();
return 0;
}
//This is my program!
#include <stdlib.h> #include <GL/glut.h> #include <stdbool.h> float fTranslate; float fRotate; float fScale = 1.0f; // set inital scale value to 1.0f bool bPersp = false; bool bAnim = false; bool bWire = false; int wHeight = 0; int wWidth = 0; float fMovex = 0.0; float fMovez = 0.0; float fRotatet; bool bTea = false; void Draw_Leg() { glScalef(1, 1, 3); glutSolidCube(1.0); } void Draw_Scene() { glPushMatrix(); //glTranslatef(0, 0, 5.0); glRotatef(90, 1, 0, 0); //notice the rotation here, you may have a TRY removing this line to see what it looks like. glTranslatef(0+fMovex,5.0,0+fMovez); glRotatef(fRotatet, 0, 1.0f, 0); //todo; hint: when operate the teapot, you may need to change some parameters glutSolidTeapot(1); glPopMatrix(); //draw complete table. glPushMatrix(); glTranslatef(0, 0, 3.5); glScalef(5, 4, 1); glutSolidCube(1.0); glPopMatrix(); glPushMatrix(); glTranslatef(1.5, 1, 1.5); Draw_Leg(); glPopMatrix(); glPushMatrix(); glTranslatef(-1.5, 1, 1.5); Draw_Leg(); glPopMatrix(); glPushMatrix(); glTranslatef(1.5, -1, 1.5); Draw_Leg(); glPopMatrix(); glPushMatrix(); glTranslatef(-1.5, -1, 1.5); Draw_Leg(); glPopMatrix(); //completed } void updateView(int width, int height) { glViewport(0,0,width,height); // Reset The Current Viewport glMatrixMode(GL_PROJECTION); // Select The Projection Matrix glLoadIdentity(); // Reset The Projection Matrix float whRatio = (GLfloat)width/(GLfloat)height; //reset the ratio of width and height if (bPersp){ //bPersp is a parameter when it equals 1 then select perspective else ortho gluPerspective(25.0, whRatio, 1.0,200.0); // temporarily answer //todo when 'p' operation, hint: use FUNCTION gluPerspective } else glOrtho(-3 ,3, -3, 3,-100,100); glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix } void reshape(int width, int height) { if (height==0) // Prevent A Divide By Zero By { height=1; // Making Height Equal One } wHeight = height; wWidth = width; updateView(wHeight, wWidth); } /* void reshape (int width ,int height ) { if (height == 0) height = 1; glViewport(0.0, 0.0, width, height); //default glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (bPersp){ gluPerspective(65.0, (GLfloat)width/(GLfloat)height; , 1.0,100.0); } else glOrtho(-3 ,3, -3, 3,-100,100); glMatrixMode(GL_MODELVIEW); //default glLoadIdentity(); //default } */ void idle() { glutPostRedisplay(); //glutPostRedisplay marks the current window as needing to be redisplayed. } float eye[] = {0, 0, 8}; float center[] = {0, 0, 0}; /*float array[16][20]={0}; for(int i=0;i<=16;i++) for(int j=0;j<=40;j+=2){ array[i][j]=-2.5+0.25*(j/2); array[i][++j]=2-0.25*i; }*/ void keyboard(unsigned char k, int x, int y) { switch(k) { case 27: case 'q': {exit(0); break; } case 'p': {bPersp = !bPersp; updateView(wHeight, wWidth);break; } case ' ': {bAnim = !bAnim; break;} case 'o': {bWire = !bWire; break;} case 'a': {eye[0]=eye[0]+0.2;center[0]=center[0]+0.2;break; } case 'd': {eye[0]=eye[0]-0.2;center[0]=center[0]-0.2;break; } case 'w': {eye[1]=eye[1]-0.2;center[1]=center[1]-0.2;break; } case 's': {eye[1]=eye[1]+0.2;center[1]=center[1]+0.2;break; } case 'z': {eye[2]=eye[2]-0.2;break; } case 'c': {eye[2]=eye[2]+0.2;break; } //茶壶相关操作 case 'l': { if(fMovex!=2.0) fMovex+=0.25; break; } case 'j': { if(fMovex!=-2.0) fMovex-=0.25; break; } case 'i': { if(fMovez!=-2.0) fMovez-=0.25; break; } case 'k': { if(fMovez!=2.0) fMovez+=0.25; break; } case 'e': {bTea=!bTea;//todo break; } } } void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); // Reset The Current Modelview Matrix gluLookAt(eye[0], eye[1], eye[2], center[0], center[1], center[2], 0, 1, 0); // 场景(0,0,0)的视点中心 (0,5,50),Y轴向上 eye [] ={0, 0, 8} if (bWire) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } else { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } glEnable(GL_DEPTH_TEST); // light glEnable(GL_LIGHTING); GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_pos[] = {5,5,5,1}; glLightfv(GL_LIGHT0, GL_POSITION, light_pos); glLightfv(GL_LIGHT0, GL_AMBIENT, white); glEnable(GL_LIGHT0); // glTranslatef(0.0f, 0.0f,-6.0f); // Place the triangle at Center glRotatef(fRotate, 0, 1.0f, 0); // Rotate around Y axis glRotatef(-90, 1, 0, 0); glScalef(0.2, 0.2, 0.2); Draw_Scene(); // Draw Scene if (bAnim) fRotate += 0.5f; if(bTea) fRotatet += 0.5f; glutSwapBuffers(); } int main (int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE); glutInitWindowSize(480,480); glutInitWindowPosition(100,100); glutCreateWindow("Simple GLUT App"); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutIdleFunc(idle); //not be familiar to the function glutMainLoop(); return 0; }
// my classmate's
#include <stdlib.h> #include <stdio.h> #include "glut.h" float fTranslate_x; float fTranslate_y; float fRotate; float fRotate_tea; float xCoordinate_tea = 0; float zCoordinate_tea = 5; float fScale = 1.0f; // set inital scale value to 1.0f bool bPersp = false; bool bAnim = false; bool bWire = false; int wHeight = 0; int wWidth = 0; //todo //hint: some additional parameters may needed here when you operate the teapot void Draw_Leg() { glScalef(1, 1, 3); glutSolidCube(1.0); } void Draw_Scene() { glPushMatrix(); glTranslatef(xCoordinate_tea,0, zCoordinate_tea); glRotatef(fRotate_tea, 0, 0, 1.0f); // Rotate around Y axis glRotatef(90, 1, 0, 0); //notice the rotation here, you may have a TRY removing this line to see what it looks like. //todo; hint: when operate the teapot, you may need to change some parameters glutSolidTeapot(1); glPopMatrix(); glPushMatrix(); glTranslatef(0, 0, 3.5); glScalef(5, 4, 1); glutSolidCube(1.0); glPopMatrix(); glPushMatrix(); glTranslatef(1.5, 1, 1.5); Draw_Leg(); glPopMatrix(); glPushMatrix(); glTranslatef(-1.5, 1, 1.5); Draw_Leg(); glPopMatrix(); glPushMatrix(); glTranslatef(1.5, -1, 1.5); Draw_Leg(); glPopMatrix(); glPushMatrix(); glTranslatef(-1.5, -1, 1.5); Draw_Leg(); glPopMatrix(); } void updateView(int width, int height) { glViewport(0,0,width,height); // Reset The Current Viewport glMatrixMode(GL_PROJECTION); // Select The Projection Matrix glLoadIdentity(); // Reset The Projection Matrix float whRatio = (GLfloat)width/(GLfloat)height; if (bPersp){ //todo when 'p' operation, hint: use FUNCTION gluPerspective gluPerspective(45.0f,(GLfloat)(width+5)/(GLfloat)height,0.1f,100.0f); printf("sds\n"); } else glOrtho(-3 ,3, -3, 3,-100,100); glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix } void reshape(int width, int height) { if (height==0) // Prevent A Divide By Zero By { height=1; // Making Height Equal One } wHeight = height; wWidth = width; updateView(wHeight, wWidth); } void idle() { glutPostRedisplay(); } float eye[] = {0,0, 8}; float center[] = {0, 0, 0}; //todo; hint: you may need another ARRAY when you operate the teapot void key(unsigned char k, int x, int y) { switch(k) { case 27: case 'q': {exit(0); break; } case 'p': {bPersp = !bPersp; updateView(wHeight, wWidth);break; } case ' ': {bAnim = !bAnim; break;} case 'o': {bWire = !bWire; break;} case 'a': {//todo, hint: eye[] and center[] are the keys to solve the problems fTranslate_x -= 0.1f; break; } case 'd': {//todo fTranslate_x += 0.1f; break; } case 'w': {//todo fTranslate_y += 0.1f; break; } case 's': {//todo fTranslate_y -= 0.1f; break; } case 'z': {//todo eye[0] +=1; break; } case 'x': {//todo eye[1] +=1; break; } case 'c': {//todo eye[2] +=1; break; } case 'v': {//todo eye[0] -=1; break; } case 'b': {//todo eye[1] -=1; break; } case 'n': {//todo eye[2] -=1; break; } //茶壶相关操作 case 'l': {//todo, hint:use the ARRAY that you defined, and notice the teapot can NOT be moved out the range of the table. if(xCoordinate_tea<=2.0f) xCoordinate_tea += 0.1f; break; } case 'j': {//todo if(xCoordinate_tea>=-2.0f) xCoordinate_tea -= 0.1f; break; } case 'i': {//todo zCoordinate_tea += 0.1f; break; } case 'k': {//todo if(zCoordinate_tea>=5) zCoordinate_tea -= 0.1f; break; } case 'e': {//todo fRotate_tea += 3.0f; break; } } } void redraw() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); // Reset The Current Modelview Matrix gluLookAt(eye[0], eye[1], eye[2], center[0], center[1], center[2], 0, 1, 0); // 场景(0,0,0)的视点中心 (0,5,50),Y轴向上 if (bWire) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } else { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_pos[] = {5,5,5,1}; glLightfv(GL_LIGHT0, GL_POSITION, light_pos); glLightfv(GL_LIGHT0, GL_AMBIENT, white); glEnable(GL_LIGHT0); glTranslatef(fTranslate_x, fTranslate_y,0); // Place the triangle at Center glRotatef(fRotate, 0, 1.0f, 0); // Rotate around Y axis glRotatef(-90, 1, 0, 0); glScalef(0.2, 0.2, 0.2); Draw_Scene(); // Draw Scene if (bAnim) fRotate += 0.5f; //todo; hint: when you want to rotate the teapot, you may like to add another line here =) glutSwapBuffers(); } int main (int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE); glutInitWindowSize(480,480); int windowHandle = glutCreateWindow("Simple GLUT App"); glutDisplayFunc(redraw); glutReshapeFunc(reshape); glutKeyboardFunc(key); glutIdleFunc(idle); glutMainLoop(); return 0; }
1)我有点看不太懂程序,所以我把该程序分解开来。在前面的draw_scene中,teapot的画法为什么先平移到了Z轴,然后一个旋转90度绕X轴,画了一个teapot(1.0)。
通过对teapot的绘制函数进行变化,
1. glPushMatrix();
2. glTranslatef(0, 0, 4+1);
3. glRotatef(90, 1, 0, 0); //notice the rotation here, you may have a TRY removing this line to see what it looks like.
4. //todo; hint: when operate the teapot, you may need to change some parameters
5. glutSolidTeapot(1);
6. glPopMatrix();
a.当我将2、3行注释掉的时候,那么也就是说,teapot的绘制将在默认的坐标系中,但是出现了下图:
b.在上面的注释情况下,我把glTranslatef(5.0,0.0,0.0),如下图:
C 那么在这个时候,考虑到了y的坐标系,为了证明想法,还是实践了一下:于是我将上述的参数改为. glTranslatef(0.0,50.0,0.0)。由于正交投影没有显示出变化,但在透视投影下我看到了:
D 那么之后的参数验证也可想而知了。但是为什么teapot的默认坐标系不是右手坐标系呢?teapot的默认坐标系:x指向了右方,y指向了屏幕里面,z指向了上方。
找了一个关于teapot的OpenGL例程。
1. #include <GL/glut.h>
2. void init();
3. void display();
4. int main(int argc, char* argv[])
5. {
6. glutInit(&argc, argv);
7. glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
8. glutInitWindowPosition(0, 0);
9. glutInitWindowSize(300, 300);
10. glutCreateWindow("OpenGL 3D View");
11. init();
12. glutDisplayFunc(display);
13. glutMainLoop();
14. return 0;
15. }
16.
17. void init()
18. {
19. glClearColor(0.0, 0.0, 0.0, 0.0);
20. glMatrixMode(GL_PROJECTION);
21. glOrtho(-5, 5, -5, 5, 5, 15);
22. glMatrixMode(GL_MODELVIEW);
23. gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0);
24. }
25.
26. void display()
27. {
28. glClear(GL_COLOR_BUFFER_BIT);
29. glColor3f(1.0, 0, 0);
30. glutWireTeapot(3);
31. glFlush();
32.
33. }
但是这个显示的teapot是正常的默认的坐标系,一个可漂亮的茶壶了。
最后的最后我找到了问题的根源了:是在display里面有个无端的旋转函数。。真是晕倒!!!
2)reshape 回调函数分为了俩个部分。是为了之后的调用。但是这样我觉得还不如写成后一种。这样在需要的时候直接调用reshape函数。显得比较简洁。
1. void updateView(int width, int height)
2. {
3. glViewport(0,0,width,height); // Reset The Current Viewport
4.
5. glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
6. glLoadIdentity(); // Reset The Projection Matrix
7.
8. float whRatio = (GLfloat)width/(GLfloat)height;
9.
10. if (bPersp){
11. //todo when 'p' operation, hint: use FUNCTION gluPerspective
12. }
13. else
14. glOrtho(-3 ,3, -3, 3,-100,100);
15.
16. glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
17. }
18.
19. void reshape(int width, int height)
20. {
21. if (height==0) // Prevent A Divide By Zero By
22. {
23. height=1; // Making Height Equal One
24. }
25.
26. wHeight = height;
27. wWidth = width;
28.
29. updateView(wHeight, wWidth);
30. }
这儿懒的再写一次了,不能上传Word文档。。。喵喵