利用openGL纯手工打造一个金字塔
Posted airduce
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了利用openGL纯手工打造一个金字塔相关的知识,希望对你有一定的参考价值。
环境:linux(ubuntu16.4)、gcc
第一步:先出一个三角形线框
效果:
实现代码:
Makefile
BDIR = -L/usr/X11R6/lib CC = gcc CFLAGS = $(COMPILERFLAGS) LIBRARIES = -lX11 -lXi -lglut -lGL -lGLU -lm pyramid : pyramid.o $(CC) $(CFLAGS) -o $@ $(LIBDIR) $? $(LIBRARIES) clean: rm -f *.o
pyramid.c
#include <GL/gl.h> #include <GL/glu.h> #include <GL/glut.h> #include <GL/glext.h> #include <sys/time.h> #include <math.h> #define GL_PI 3.1415f void RenderScene(void){ //用线框绘制 glPolygonMode(GL_FRONT,GL_LINE); //用当前颜色清除屏幕(也就是SetupRC中的 glClearColor 指定的颜色) glClear(GL_COLOR_BUFFER_BIT); //此三角形位于x、y轴的平面上 glBegin(GL_TRIANGLES); glVertex3f(50.0f,0.0f,0.0f);//右顶点 glVertex3f(0.0f,50.0f,0.0f);//上顶点 glVertex3f(-50.0f,0.0f,0.0f);//左顶点 glEnd(); glutSwapBuffers(); } void SetupRC() { glClearColor(0.0f, 0.0f, 0.0f, 1.0f ); // 设置绘制颜色为绿色 glColor3f(0.0f, 1.0f, 0.0f); } void ChangeSize(int w, int h) { GLfloat nRange = 100.0f; // 防止清零 if(h == 0) h = 1; // 设置视口大小为当前窗口 glViewport(0, 0, w, h); //重置操作矩阵栈 glMatrixMode(GL_PROJECTION); glLoadIdentity(); // 这是透视投影裁截体 (left, right, bottom, top, near, far) if (w <= h) glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange); else glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange); //重置模型视图矩阵 glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutCreateWindow("Pyramid Example"); glutReshapeFunc(ChangeSize); glutDisplayFunc(RenderScene); SetupRC(); glutMainLoop(); return 0; }
第二步:实现旋转
效果(当按上下左右箭头时实现旋转):
实现代码:
#include <GL/gl.h> #include <GL/glu.h> #include <GL/glut.h> #include <GL/glext.h> #include <sys/time.h> #include <math.h> #define GL_PI 3.1415f static GLfloat xRot = 0.0f; static GLfloat yRot = 0.0f; void RenderScene(void){ //用线框绘制 glPolygonMode(GL_FRONT,GL_LINE); glPolygonMode(GL_BACK,GL_LINE); //用当前颜色清除屏幕(也就是SetupRC中的 glClearColor 指定的颜色) glClear(GL_COLOR_BUFFER_BIT); //保存当前操作矩阵 glPushMatrix(); //绕x轴旋转 glRotatef(xRot, 1.0f, 0.0f, 0.0f); //绕y轴旋转 glRotatef(yRot, 0.0f, 1.0f, 0.0f); //此三角形位于x、y轴的平面上 glBegin(GL_TRIANGLES); glVertex3f(50.0f,0.0f,0.0f);//右顶点 glVertex3f(0.0f,50.0f,0.0f);//上顶点 glVertex3f(-50.0f,0.0f,0.0f);//左顶点 glEnd(); //恢复当前操作矩阵 glPopMatrix(); glutSwapBuffers(); } void SetupRC() { glClearColor(0.0f, 0.0f, 0.0f, 1.0f ); // 设置绘制颜色为绿色 glColor3f(0.0f, 1.0f, 0.0f); } void ChangeSize(int w, int h) { GLfloat nRange = 100.0f; // 防止清零 if(h == 0) h = 1; // 设置视口大小为当前窗口 glViewport(0, 0, w, h); //重置操作矩阵栈 glMatrixMode(GL_PROJECTION); glLoadIdentity(); // 这是透视投影裁截体 (left, right, bottom, top, near, far) if (w <= h) glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange); else glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange); //重置模型视图矩阵 glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } //控制键 void ControlKeys(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; if(key > 356.0f) xRot = 0.0f; if(key < -1.0f) xRot = 355.0f; if(key > 356.0f) yRot = 0.0f; if(key < -1.0f) yRot = 355.0f; // Refresh the Window glutPostRedisplay(); } int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutCreateWindow("Pyramid Example"); glutReshapeFunc(ChangeSize); glutSpecialFunc(ControlKeys); glutDisplayFunc(RenderScene); SetupRC(); glutMainLoop(); return 0; }
第三步:线框金字塔
效果:红x轴,绿y轴,蓝z轴
实现代码:
#include <GL/gl.h> #include <GL/glu.h> #include <GL/glut.h> #include <GL/glext.h> #include <sys/time.h> #include <math.h> #define GL_PI 3.1415f static GLfloat xRot = 0.0f; static GLfloat yRot = 0.0f; void RenderScene(void){ //用线框绘制 glPolygonMode(GL_FRONT,GL_LINE); glPolygonMode(GL_BACK,GL_LINE); // glEnable(GL_DEPTH_TEST); //用当前颜色清除屏幕(也就是SetupRC中的 glClearColor 指定的颜色) glClear(GL_COLOR_BUFFER_BIT); //保存当前操作矩阵 glPushMatrix(); //绕x轴旋转 glRotatef(xRot, 1.0f, 0.0f, 0.0f); //绕y轴旋转 glRotatef(yRot, 0.0f, 1.0f, 0.0f); //加宽线条 glLineWidth(3.0f); //金字塔底边长 GLfloat len = 60.0f; //z轴点 GLfloat vz = 2*len*cos(GL_PI/180*30); //顶点的z轴点 GLfloat vhz = len*tan(GL_PI/180*30); //此三角形位于x、y轴的平面上 glBegin(GL_TRIANGLES); glVertex3f(len,0.0f,0.0f);//前右 glVertex3f(0.0f,len,-vhz);//顶点 glVertex3f(-len,0.0f,0.0f);//前左 glVertex3f(0.0f,0.0f,-vz);//后 glVertex3f(0.0f,len,-vhz);//顶点 glVertex3f(len,0.0f,0.0f);//前右 glVertex3f(-len,0.0f,0.0f);//前左 glVertex3f(0.0f,len,-vhz);//顶点 glVertex3f(0.0f,0.0f,-vz);//后 glEnd(); //绘制一个坐标系, GLint factor = 2; GLushort pattern = 0x5555; //启用点画 glEnable(GL_LINE_STIPPLE); //点画模式 glLineStipple(factor,pattern); glLineWidth(1.0f); glBegin(GL_LINES); //x轴 glColor3ub((GLubyte)255,(GLubyte)0,(GLubyte)0); glVertex3f(-100.0f,0.0f,0.0f); glVertex3f(100.0f,0.0f,0.0f); glColor3ub((GLubyte)0,(GLubyte)255,(GLubyte)0); //y轴 glVertex3f(0.0f,-100.0f,0.0f); glVertex3f(0.0f,100.0f,0.0f); //z轴 glColor3ub((GLubyte)0,(GLubyte)0,(GLubyte)255); glVertex3f(0.0f,0.0f,-100.0f); glVertex3f(0.0f,0.0f,100.0f); glEnd(); //关闭点画 glDisable(GL_LINE_STIPPLE); //恢复当前操作矩阵 glPopMatrix(); glutSwapBuffers(); } void SetupRC() { glClearColor(0.0f, 0.0f, 0.0f, 1.0f ); // 设置绘制颜色为绿色 glColor3f(0.0f, 1.0f, 0.0f); } void ChangeSize(int w, int h) { GLfloat nRange = 100.0f; // 防止清零 if(h == 0) h = 1; // 设置视口大小为当前窗口 glViewport(0, 0, w, h); //重置操作矩阵栈 glMatrixMode(GL_PROJECTION); glLoadIdentity(); // 这是透视投影裁截体 (left, right, bottom, top, near, far) if (w <= h) glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange); else glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange); //重置模型视图矩阵 glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } //控制键 void controlKeys(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; if(key > 356.0f) xRot = 0.0f; if(key < -1.0f) xRot = 355.0f; if(key > 356.0f) yRot = 0.0f; if(key < -1.0f) yRot = 355.0f; // Refresh the Window glutPostRedisplay(); } int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutCreateWindow("Pyramid Example"); glutReshapeFunc(ChangeSize); glutSpecialFunc(controlKeys); glutDisplayFunc(RenderScene); SetupRC(); glutMainLoop(); return 0; }
以上是关于利用openGL纯手工打造一个金字塔的主要内容,如果未能解决你的问题,请参考以下文章
纯手工打造CPU的那些牛人们,欣赏令人叹为观止的纯手工布线和高超技
纯手工打造CPU的那些牛人们,欣赏令人叹为观止的纯手工布线和高超技