【OpenGL】画立方体
编写一个程序,该程序运行时可以用鼠标的一个按键调整立方体的方向,用另一个按键平移立方体,用第三个按键缩放立方体。
这是题目,我的程序不一定完全按照这个来。初学OpenGL,对那一堆坐标系表示十分混乱,慢慢看吧,有点头绪了。
(一)
#include <gl/glut.h>
#include <math.h>
#define GL_PI 3.1415f GLfloat xRot = -35.0f;
GLfloat yRot = 15.0f;
GLfloat xMov = 0.0f;
GLfloat winW = 0.0f;
GLfloat winH = 0.0f;
GLfloat zoom = 1.0f; void RenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT); glPushMatrix();
glLoadIdentity();
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f); // 底面
glBegin(GL_LINE_LOOP);
glVertex3f(0.0f+xMov, 0.0f, 0.0f);
glVertex3f(1.0f+xMov, 0.0f, 0.0f);
glVertex3f(1.0f+xMov, 0.0f, 1.0f);
glVertex3f(0.0f+xMov, 0.0f, 1.0f);
glEnd(); // 顶面
glBegin(GL_LINE_LOOP);
glVertex3f(0.0f+xMov, 1.0f, 1.0f);
glVertex3f(0.0f+xMov, 1.0f, 0.0f);
glVertex3f(1.0f+xMov, 1.0f, 0.0f);
glVertex3f(1.0f+xMov, 1.0f, 1.0f);
glEnd(); // 背面
glBegin(GL_LINE_LOOP);
glVertex3f(0.0f+xMov, 0.0f, 0.0f);
glVertex3f(1.0f+xMov, 0.0f, 0.0f);
glVertex3f(1.0f+xMov, 1.0f, 0.0f);
glVertex3f(0.0f+xMov, 1.0f, 0.0f);
glEnd(); // 前面
glBegin(GL_LINE_LOOP);
glVertex3f(1.0f+xMov, 0.0f, 1.0f);
glVertex3f(0.0f+xMov, 0.0f, 1.0f);
glVertex3f(0.0f+xMov, 1.0f, 1.0f);
glVertex3f(1.0f+xMov, 1.0f, 1.0f);
glEnd(); // 右面
glBegin(GL_LINE_LOOP);
glVertex3f(1.0f+xMov, 0.0f, 0.0f);
glVertex3f(1.0f+xMov, 0.0f, 1.0f);
glVertex3f(1.0f+xMov, 1.0f, 1.0f);
glVertex3f(1.0f+xMov, 1.0f, 0.0f);
glEnd(); // 左面
glBegin(GL_LINE_LOOP);
glVertex3f(0.0f+xMov, 0.0f, 0.0f);
glVertex3f(0.0f+xMov, 0.0f, 1.0f);
glVertex3f(0.0f+xMov, 1.0f, 1.0f);
glVertex3f(0.0f+xMov, 1.0f, 0.0f);
glEnd(); glPopMatrix();
glFlush();
}
void OnReshape(int w, int h)
{
GLfloat aspectRatio = (GLfloat)w/(GLfloat)h;
winW = w;
winH = h; glViewport(,,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
{
glOrtho(-3.0f*zoom, 3.0f*zoom, -3.0f*zoom/aspectRatio, 3.0f*zoom/aspectRatio, -10.0f*zoom, 10.0f*zoom);
}
else{
glOrtho(-3.0f*zoom*aspectRatio, 3.0f*zoom*aspectRatio, -3.0f*zoom, 3.0f*zoom, -10.0f*zoom, 10.0f*zoom);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void OnMouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
xRot += ;
yRot += ;
glutPostRedisplay();
}
else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
{
xMov -= 0.1;
glutPostRedisplay();
}
else if (button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN)
{
zoom += 0.1;
OnReshape(winW,winH);
glutPostRedisplay();
}
}
void OnKeyUpDown(int key, int x, int y)
{
if (key == GLUT_KEY_UP){
zoom -= 0.1;
}
else if (key == GLUT_KEY_DOWN){
zoom += 0.1;
}
OnReshape(winW,winH);
glutPostRedisplay();
} void SetupRC()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f);
} void main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutCreateWindow("Cube");
glutDisplayFunc(RenderScene);
glutReshapeFunc(OnReshape);
glutMouseFunc(OnMouse);
glutSpecialFunc(OnKeyUpDown); SetupRC(); glutMainLoop();
}
这个程序略长,显得有点笨。手工实现了平移和放大缩小的功能,值得记录一下。
(二)
#include <windows.h>
#include<gl/glut.h>
#include <math.h>
#include<stdio.h> GLfloat angle=0.0f;
GLfloat translate_x=0.0f;
GLfloat zoom=1.0f; void myDisplay()
{
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0f, 1.0f, 1.0f);
glPushMatrix();
{
glMatrixMode(GL_MODELVIEW); //切换到模型视图矩阵
glLoadIdentity();
glRotatef(angle,1.0f,0.0f,0.0f);
glRotatef(angle, 0.0f, 1.0f, 0.0f);
glTranslatef(translate_x,0.0f,0.0f);
glScalef (zoom, zoom, zoom);
glutWireCube(1.5); //画立方体
}
glPopMatrix();
glFlush();
} void reshape(int w,int h)
{
glViewport (, , (GLsizei) w, (GLsizei) h); //调整视口位置和大小
glMatrixMode (GL_PROJECTION);//切换到投影矩阵
glLoadIdentity();//加载单位阵至投影矩阵
if (w <= h){
glOrtho(-3.0f, 3.0f, -3.0f/(w/h), 3.0f/(w/h), -3.0f, 3.0f);
}
else{
glOrtho(-3.0f*w/h, 3.0f*w/h, -3.0f, 3.0f, -3.0f, 3.0f);
} glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
} void OnMouse(int button, int state, int x, int y)
{
//鼠标左键
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
angle += 10.0f;
glutPostRedisplay();
}
//鼠标右键
else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
{
translate_x+=0.1f;
glutPostRedisplay();
}
//鼠标滚轮
else if (state == GLUT_UP && button == GLUT_WHEEL_DOWN)
{
if(zoom>)
zoom-=0.1f;
glutPostRedisplay();
}
else if(state == GLUT_UP && button == GLUT_WHEEL_UP)
{
zoom+=0.1f;
glutPostRedisplay();
}
} int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowPosition(,);
glutInitWindowSize(,);
glutCreateWindow("cube"); glutDisplayFunc(myDisplay);
glutReshapeFunc(reshape);
glutMouseFunc( OnMouse );
glutMainLoop();
return ;
}
采用了OpenGL的一些库函数实现,投影还是采用平行投影,表示对透视投影函数gluPerspective以及视点变化函数gluLookAt不是很清楚。
(三)
#include <windows.h>
#include<gl/glut.h>
#include <math.h>
#include<stdio.h> GLfloat angle=0.0f;
GLfloat translate_x=0.0f;
GLfloat zoom=1.0f; void myDisplay()
{
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0f, 1.0f, 1.0f);
glPushMatrix(); glMatrixMode(GL_MODELVIEW); //切换到模型视图矩阵
glLoadIdentity();
gluLookAt (0.0f, 0.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); //设置相机参数
glRotatef(angle, 0.0f, 1.0f, 0.0f);
glTranslatef(translate_x,0.0f,0.0f);
glScalef (zoom, zoom, zoom);
glutWireCube(0.5); //画立方体 glPopMatrix();
glFlush();
} void reshape(int w,int h)
{
glViewport (, , (GLsizei) w, (GLsizei) h); //调整视口位置和大小
glMatrixMode (GL_PROJECTION);//切换到投影矩阵
glLoadIdentity();//加载单位阵至投影矩阵
gluPerspective(,w/h,,);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
} void OnMouse(int button, int state, int x, int y)
{
//鼠标左键
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
angle += 10.0f;
glutPostRedisplay();
}
//鼠标右键
else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
{
//xMov -= 0.1;
translate_x+=0.1f;
glutPostRedisplay();
}
//鼠标滚轮
else if (state == GLUT_UP && button == GLUT_WHEEL_DOWN)
{
if(zoom>)
zoom-=0.1f;
glutPostRedisplay();
}
else if(state == GLUT_UP && button == GLUT_WHEEL_UP)
{
zoom+=0.1f;
glutPostRedisplay();
}
} int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowPosition(,);
glutInitWindowSize(,);
glutCreateWindow("cube"); glutDisplayFunc(myDisplay);
glutReshapeFunc(reshape);
glutMouseFunc( OnMouse );
glutMainLoop();
return ;
}
用的是透视投影。我的理解是gluPerspective()和gluLookAt()要配合使用,二者中的相机位置要一致。
【OpenGL】画立方体的更多相关文章
- OpenGL 画出雷达动态扫描效果(二) 非底图
OpenGL 画出雷达动态扫描效果(一)中给出了已一张图片作为底图的雷达扫面程序 如果有漂亮的雷达底图的话,效果应该非常不错的,另外也可以直接手绘雷达框架 效果如下 雷达主体代码 glLineWidt ...
- 46.Qt 使用OpenGL绘制立方体
main.cpp #include <QApplication> #include <iostream> #include "vowelcube.h" in ...
- opengl画不出直线 线段 坐标轴 却能画出其他图形的坑
原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/12054507.html 好多次都是画坐标轴的三条直线画不出来,虽然最后都解决了 但是还是耽误 ...
- opengl画圆
通过这个例子可以更加深刻的了解割圆术的原理,明白如何的化曲为直,且看代码: #include <windows.h> //#include <GLUT/glut.h> #inc ...
- 用OpenGL进行立方体表面纹理贴图
一.目的 掌握OpenGL中纹理对象的创建.绑定与使用方法. 二.简单介绍 1,连接静态库 #pragma comment(lib, "glut32.lib") #pragma c ...
- OpenGL 画出雷达动态扫描效果(一)
最终效果如下所示 Demo下载 http://files.cnblogs.com/xd-jinjian/Debug.zip 源代码下载 http://download.csdn.net/detail ...
- 【转】【OPenGL】OPenGL 画图板-- 中点算法画圆
为了能以任意点为圆心画圆,我们可以把圆心先设为视点(相当于于将其平移到坐标原点),然后通过中点法扫描转换后,再恢复原来的视点(相当于将圆心平移回原来的位置). 圆心位于原点的圆有四条对称轴x=0,y= ...
- 用OpenGL画线
. 两点之间的连线称之为线段,在屏幕上显示线段放在现在已经不是稀奇的事情,大多数高级图形API都可以轻松实现,我尝试用OpenGL画线,在这里记录一下收获. . OpenGL这个级别的图形API,通常 ...
- OpenGL 画高斯随机函数
高斯函数代码 const float CFFTOceanShader::_getGaussianRandomFloat() const { float u1 = rand() / (float)RAN ...
随机推荐
- 软件调试之INT 3讲解
第4章断点和单步执行 断点和单步执行是两个经常使用的调试功能,也是调试器的核心功能.本章我们将介绍IA-32 CPU是如何支持断点和单步执行功能的.前两节将分别介绍软件断点和硬件断点,第4.3节介绍用 ...
- EhCache 分布式缓存/缓存集群(转)
开发环境: System:Windows JavaEE Server:tomcat5.0.2.8.tomcat6 JavaSDK: jdk6+ IDE:eclipse.MyEclipse 6.6 开发 ...
- uva 567
Floyd 算法 就输入麻烦点 #include <iostream> #include <cstring> #include <cstdlib> #inclu ...
- Scrum中的User Story
我们通常用User Story来描述Backlog里的各个Backlog项,User Story是从用户的角度对系统的某个功能模块所作的简短描述.一个User Story描述了项目中的一个小功能,以及 ...
- Unity寻路的功能总结
源地址:http://blog.csdn.net/sgnyyy/article/details/21878163 1. 利用Unity本身自带的NavMesh 这篇文章已经比较详细,可能对于很多需要a ...
- CodeForces 300A Array
http://codeforces.com/problemset/problem/300/A 题意 :给你n个数字,让你分成3组,第一组各个数之积要小于0,第二组要大于0,第三组要等于0,符合要求的答 ...
- linux bash_profile和.bashrc区别
经常在一些技术类的文章中提到修改bash_profile和.bashrc这两个文件,也算是使用频率比较高的两个文件吧,但实现同样一个功能,有的教程里说修改bash_profile这个文件,有的教程里却 ...
- CentOS7.1配置远程桌面
网上看了很多资料,完全是乱的. 我使用的是CentOS7.1的系统.我的要求是windows的客户机可以远程访问CentOS系统. 1,首先需要检查一下服务器是否已经安装了VNC服务,检查服务器的是否 ...
- Android:Toast简单消息提示框
Toast是简单的消息提示框,一定时间后自动消失,没有焦点. 1.简单文本提示的方法: Toast.makeText(this, "默认的toast", Toast.LENGTH_ ...
- 关于hadoop的环境变量
export PATH export JAVA_HOME=/opt/jdk1.7 export PATH=$PATH:$JAVA_HOME/bin 为什么/etc/profile 添加了环境变量had ...