OpenGL 实验一 绘制简单图形
OpenGL实验一
OpenGL简介:
(英语:Open Graphics Library,译名:开放图形库或者“开放式图形库”)是用于渲染2D、3D矢量图形的跨语言、跨平台的应用程序编程接口(API)。这个接口由近350个不同的函数调用组成,用来绘制从简单的图形比特到复杂的三维景象。而另一种程序接口系统是仅用于Microsoft Windows上的Direct3D。OpenGL常用于CAD、虚拟现实、科学可视化程序和电子游戏开发。
开发环境:win10 ,VS-2015
一、预先准备
1.1 安装VS2015
1.2 创建工程目录并复制GLIB至工程目录下
GLIB内文件如下:
二、创建工程
2.1 创建命令行程序
打开vs,点击:文件->新建->项目
打开对话框选择:模板->VC+±>Win32->Win32控制台应用程序
点击确定,进入命令行程序向导
2.2 Win32应用程序向导
点击下一步,打开应用程序设置
应用程序类型:选择“控制台应用程序”
附加选项:全部不选
点击“完成”,生成项目
2.3 指定OpenGL头文件路径
2.4 加入OpenGL静态库、动态库
2.5 包含头文件:在main.cpp中,添加并改写main函数:
2.6 点击:VS->生成->重新生成解决方案,若编译成功,说明编译连接配置是正确的
2.7 调试运行 点击F5运行程序调试成功
三、绘制二维图形
3.1 改写main.cpp
// exp_1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<windows.h>
#define GLUT_DISABLE_ATEXIT_HACK
#include "GL/glut.h"
void myDisplay();
void myInit();
int main(int argc,char **argv)
{glutInit(&argc, argv); //Initialize GLUT function callings//Set window size (width,height)in number of pixelsglutInitWindowSize(400, 400);//Set window position,form the left and top of the screenglutInitWindowPosition(200, 100);//in numbers of pixels//Specify a window creation eventglutCreateWindow("Green Triangle");//Specify the drawing function that is called when the window is created or re-drewglutDisplayFunc(myDisplay); myInit(); //Invoke this function for initializationglutMainLoop(); //Enter the event processing loopreturn 0; //Indicate normal termination
}
void myDisplay() {glClear(GL_COLOR_BUFFER_BIT); //Clear the frame bufferglColor3f(0.0, 1.0, 0.0); //Set current color to greenglBegin(GL_POLYGON); //Draw the triangleglVertex2f(-0.7, -0.7);glVertex2f(0.7, -0.7);glVertex2f(0, 0.7);glEnd();glFlush(); //Force to display the new drawings immediately
}
void myInit() {glClearColor(0.0, 0.0, 0.0, 0.0); //Set the clear color to black//Specify the boundaries of the view windowglMatrixMode(GL_PROJECTION);glLoadIdentity();//恢复初始坐标gluOrtho2D(-1.0, 1.0, -1.0, 1.0); //指定世界窗口glMatrixMode(GL_MODELVIEW);
}
3.2 编译运行
四、绘制3D图形
4.1 改写main.cpp
#include "stdafx.h"
#include <windows.h> //Header File For Windows
#include <GL\GL.h> //Header File For The OpenGL32 Library
#include <GL\GLU.h> //Header File For The GLu32 Library
#include <GL\GLAUX.H> //Header File For the Glaux Library
#define GLUT_DISABLE_ATEXIT_HACK
#include "GL\GLUT.H"
GLfloat rtri; //Angle For The Triangle (NEW)
GLfloat rquad; //Angle for the Quad (NEW)
void InitGL(int width, int height);
GLvoid DrawGLScene(GLvoid);
void myReshape(int w, int h);
void myKeyboard(int key, int x, int y);
void myMovedMouse(int x, int y);
int main(int argc, char **argv) {glutInit(&argc, argv); //Intialize GLUT function callingsglutInitWindowSize(800, 600); //Set widow size (width,height)in number of pixels//Set window positio, from the left and top of the screen,glutInitWindowPosition(200, 100); //in numbers of pixels//Specify a window creation eventglutCreateWindow("3D Graph");//Specify the drawing function that is called when the windowglutDisplayFunc(DrawGLScene);glutReshapeFunc(myReshape);glutMotionFunc(myMovedMouse);glutSpecialFunc(myKeyboard); //新增键盘响应InitGL(800, 600); //Invoke this function for initializationglutMainLoop(); // Enter the event processing loopreturn 0; //Indicate normal termination
}
void InitGL(int width, int height) {myReshape(width, height);glShadeModel(GL_SMOOTH); //Enable Smooth ShadingglClearColor(0.0f, 0.0f, 0.0f, 0.5f); //BlackBackgroundglClearDepth(1.0f);//Depth Buffer SetupglEnable(GL_DEPTH_TEST); //Enables Depth TestingglDepthFunc(GL_LEQUAL); //The Type of Depth Testing To DoglHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //Really Nice Perspective Calculations
}
void myReshape(int width, int height) {if (height == 0)//Prevent A Divide By Zero By{height = 1;//Making Height Equal One}glViewport(0, 0, width, height); //Reset the Cuurent ViewportglMatrixMode(GL_PROJECTION); //Select the Projection MatrixglLoadIdentity(); //Resetthe Projection Matrix//Calculate the Aspect Ratio of the windowgluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);glMatrixMode(GL_MODELVIEW); //Select The Modelview MatrixglLoadIdentity(); //Reset the Modelview Matrix
}
GLvoid DrawGLScene(GLvoid)
//Here's where we do all the drawing
{glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //Clear Screen And Depth BufferglLoadIdentity(); //Reset The cuurent Modelview MatrixglTranslatef(-1.5f, 0.0f, -6.0f); //Move Left 1.5 Units And Into The Screen 6.0glRotatef(rtri, 0.0f, 1.0f, 0.0f); //Rotate The Triangle On the Y axis(NEW)glBegin(GL_TRIANGLES); //Start Drawing A TriangleglColor3f(1.0f, 0.0f, 0.0f); //RedglVertex3f(0.0f, 1.0f, 0.0f); //Top of Triangle (Front)glColor3f(0.0f, 1.0, 0.0f); //GreenglVertex3f(-1.0f, -1.0f, 1.0f); //Left of Triangle (Front)glColor3f(0.0f, 0.0f, 1.0f); //BlueglVertex3f(1.0f, -1.0f, 1.0f); //Right of Triangle (Front)glColor3f(1.0f, 0.0f, 0.0f); //RedglVertex3f(0.0f, 1.0f,0.0f); //Top of Triangle (Right)glColor3f(0.0f, 0.0f, 1.0f); //BlueglVertex3f(1.0f, -1.0f, 1.0f); //Left of Triangle (Right)glColor3f(0.0f, 1.0f, 0.0f); //GreenglVertex3f(1.0f, -1.0f, -1.0f); //Right of Triangle (Right)glColor3f(1.0f, 0.0f, 0.0f); //RedglVertex3f(0.0f, 1.0f, 0.0f); //Top of Triangle (Back)glColor3f(0.0f, 1.0f, 0.0f); //GreenglVertex3f(1.0f, -1.0f, -1.0f);//Left of Triangle(Back)glColor3f(0.0f, 0.0f, 1.0f); //BlueglVertex3f(-1.0f, -1.0f, -1.0f); //Left of Triangle (Back)glColor3f(1.0f, 0.0f, 0.0f); //RedglVertex3f(0.0f, 1.0f, 0.0f); //Top of Triangle (Left)glColor3f(0.0f, 0.0f, 1.0f); //BlueglVertex3f(-1.0f, -1.0f, -1.0f);//Left of Triangle (Left)glColor3f(0.0f, 1.0f, 0.0f); //GreenglVertex3f(-1.0f, -1.0f, 1.0f); //Right of Triangle(Left)glEnd();//Done Drawing the PyramidglLoadIdentity(); //Reset the Current Modelview MatrixglTranslatef(1.5f, 0.0f, -7.0f); //Move Right 1.5 Units And Intothe screen 7.0glRotatef(rquad, 1.0f, 1.0f, 1.0f); //Rotate The Quad On the X axis(NEW)glBegin(GL_QUADS);//Draw A QuadglColor3f(0.0f, 1.0f, 0.0f); // Set The Color to GreenglVertex3f(1.0f, 1.0f, -1.0f); //Top Right of The Quad (Top)glVertex3f(-1.0f, 1.0f, -1.0f);//Top Left of The Quad (Top)glVertex3f(-1.0f, 1.0f, 1.0f); //Bottom Left of the Quad(Top)glVertex3f(1.0f, 1.0f, 1.0f); //Bottom Right of the Quad(Top)glColor3f(1.0f, 0.5f, 0.0f); //Set The Color to OrangeglVertex3f(1.0f, -1.0f, 1.0f); //Top Right of the Quad(Bottom)glVertex3f(-1.0f, -1.0f, 1.0f);//Top Left of the Quad (Bottom)glVertex3f(-1.0f, -1.0f, -1.0f);//Bottom Left of the Quad(Bottom)glVertex3f(1.0f, -1.0f, -1.0f);//Bottom Right of the QuadglColor3f(1.0f, 0.0f, 0.0f); //Set the Color to RedglVertex3f(1.0f, 1.0f, 1.0f); //Top Right of the Quad (Front)glVertex3f(-1.0f, 1.0f, 1.0f); //Top Left of the Quad (Front)glVertex3f(-1.0f, -1.0f, 1.0f);//Bottom Left of the Quad(Front)glVertex3f(1.0f, -1.0f, 1.0f); //Bottom Right of the Quad(Front)glColor3f(1.0f, 1.0f, 0.0f); //Set the Color to Yellow glVertex3f(1.0f, -1.0f, -1.0f);//Top Right of the Quad(back)glVertex3f(-1.0f, -1.0f, -1.0f);//Top Left of the Quad(back)glVertex3f(-1.0f, 1.0f, -1.0f);//Bottom Left of the Quad (back)glVertex3f(1.0f, 1.0f, -1.0f); //Bottom Right of the Quad (back)glColor3f(0.0f, 0.0f, 1.0f);//Set the Color to BlueglVertex3f(-1.0f, 1.0f, 1.0f);//Top Right of the Quad(Left)glVertex3f(-1.0f, 1.0f, -1.0f);//Top Left of the Quad(Left)glVertex3f(-1.0f, -1.0f, -1.0f);//Bottom Left of the Quad (Left)glVertex3f(-1.0f, -1.0f, 1.0f);//Bottom Right of the Quad (Left)glColor3f(1.0f, 0.0f, 1.0f); //Set the Color to VioletglVertex3f(1.0f, 1.0f, -1.0f); //Top right of the Quad(Right)glVertex3f(1.0f, 1.0f, 1.0f); //Top Left of the Quad(Right)glVertex3f(1.0f, -1.0f, 1.0f); //Bottom Left of the Quad(Right)glVertex3f(1.0f, -1.0f, -1.0f); //Bottom Right of the Quad(Right)glEnd();//Done Drawing the quadglFlush(); //Force to display the new drawings immediately
}
void myKeyboard(int key, int x, int y) {switch (key) {case GLUT_KEY_LEFT:case GLUT_KEY_UP:rtri -= 0.5f; //Decrese the Roatation Variable For The Triangle (New)rquad += 0.5f; //Increse The Rotation Variable For The QuadDrawGLScene();break;case GLUT_KEY_RIGHT:case GLUT_KEY_DOWN:rtri += 0.5f; //Increse the Roatation Variable For The Triangle (New)rquad -= 0.85f; //Decrese The Rotation Variable For The QuadDrawGLScene();break;}
}
void myMovedMouse(int x, int y) {
}
4.2 运行成功的截图
4.3 控制3D物体旋转平移
上述代码中的myKeyboard便实现了通过键盘而操纵图像旋转,注意在主函数中,用glutSpecialFunc()才能调用。
void myKeyboard(int key, int x, int y) {switch (key) {case GLUT_KEY_LEFT:case GLUT_KEY_UP:rtri -= 0.5f; //Decrese the Roatation Variable For The Triangle (New)rquad += 0.5f; //Increse The Rotation Variable For The QuadDrawGLScene();break;case GLUT_KEY_RIGHT:case GLUT_KEY_DOWN:rtri += 0.5f; //Increse the Roatation Variable For The Triangle (New)rquad -= 0.85f; //Decrese The Rotation Variable For The QuadDrawGLScene();break;}
}
五、心得体会
本次实验中需要在写代码时仔细比对各个参数,不可粗心大意,比如针对颜色,glColor3f函数中的3个参数取不同的值就会导致不同的效果。头文件的导入也需要注意,再比如"stdafx.h"文件必须放在其他库文件之前。
观察代码结构可以发现,绘制图形的思路大致如下:
- 绘制窗口
- 初始化GL函数
- 编写重新载入图像的函数
- 绘制图形的函数
- 键盘or鼠标操纵图形的函数
相关函数列举:
- 上述源程序中的主函数:
glutInit() 初始化函数
glutInitWindowSize() 设置窗口大小
glutInitWindowPosition() 设置窗口位置
glutCreateWindow() 创建窗口
glutDisplayFunc(DrawGLScene) 指定显示函数
glutReshapeFunc(myReshape) 改变显示区域
glutMotionFunc(myMovedMouse) 这个函数是处理当鼠标键摁下时,鼠标拖动的事件。当鼠标拖动时,将每一帧都调用一次这个函数。
glutSpecialFunc(myKeyboard) 这个函数是用来处理一些特殊键(如:F1,F2,etc)摁下的事件。本实验中主要是方向键。
glutMainLoop() 进行过程循环 - myReshape函数
glViewport(width,height) 表示这个视口矩形的宽度和高度,根据窗口的实时变化重绘窗口。
glMatrixMode() 选择投影矩阵 这个函数其实就是对接下来要做什么进行一下声明,也就是在要做下一步之前告诉计算机我要对“什么”进行操作了,这个“什么”在glMatrixMode的“()”里的选项(参数)有3种模式: GL_PROJECTION 投影, GL_MODELVIEW 模型视图, GL_TEXTURE 纹理。
如果参数是GL_PROJECTION,这个是投影的意思,就是要对投影相关进行操作,也就是把物体投影到一个平面上,就像我们照相一样,把3维物体投到2维的平面上。这样,接下来的语句可以是跟透视相关的函数,比如glFrustum()或gluPerspective();
在操作投影矩阵以前,需要调用函数:glMatrixMode(GL_PROJECTION); //将当前矩阵指定为投影矩阵
然后把矩阵设为单位矩阵:glLoadIdentity();再度调用glFrustum()或gluPerspective(),它们生成的矩阵会与当前的矩阵相乘,生成透视的效果;
参考资料:https://blog.csdn.net/jiangdf/article/details/8460012
glLoadIdentity() 恢复初始坐标系
该命令是一个无参的无值函数,其功能是用一个4×4的单位矩阵来替换当前矩阵,实际上就是对当前矩阵进行初始化。也就是说,无论以前进行了多少次矩阵变换,在该命令执行后,当前矩阵均恢复成一个单位矩阵,即相当于没有进行任何矩阵变换状态。
注意:由于某些原因可能使得当前矩阵中的元素有一些不确定的值,这将导致程序对图形对象进行几何变形时得到一个非预期的结果。因此有必要将当前矩阵初始成 一个单位矩阵,即对图形对象不做任何变换。这就是为什么在调用过glMatrixMode()命令后,总是要调用该命令的原因。由于glMatrixMode()命令本身也是一种矩阵变换,它将当前矩阵变成命令参数所规定的形式,若不用单位矩阵来替换它,在此矩阵下绘制出的图形将是难以预计的。
关于这个函数的详细解释请看以下博文:
https://blog.csdn.net/shuaihj/article/details/7228265
(个人感觉这一篇讲得很清楚~)
glViewport() 在默认情况下,视口被设置为占据窗口的整个像素矩形,窗口大小和视口大小相同。如果选择一个更小的绘图区域,可以用glviewport函数实现这一变换,在窗口中定义一个像素矩形,将图像映射到这个矩形中。
gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear,GLdouble zFar)
fovy,这个最难理解,我的理解是,眼睛睁开的角度,即,视角的大小,如果设置为0,相当你闭上眼睛了,所以什么也看不到,如果为180,那么可以认为你的视界很广阔
aspect,这个好理解,就是实际窗口的纵横比,即x/y
zNear,这个呢,表示你近处,的裁面,
zFar表示远处的裁面
参考资料:https://blog.csdn.net/dcrmg/article/details/53106457 - InitGL中的函数
glShadeModel() 设置着色模式,即控制绘制自定两点间其他点颜色的过渡模式,参数一般为GL_SMOOTH(默认)如果两点颜色不同,GL_SMOOTH会出现过渡效果。采用恒定着色时(即GL_FLAT),使用图元中某个顶点的颜色来渲染整个图元。
在使用光滑着色时(即GL_SMOOTH),独立的处理图元中各个顶点的颜色。对于线段图元,线段上各点的颜色将根据两个顶点的颜色通过差值得到。对于多边形图元,多边形内部区域的颜色将根据所有顶点的颜色差值得到。
参考原文链接:https://blog.csdn.net/deniece1/article/details/102133394
glClearColor() 搭配glClearDepth使用
参数:GL_COLOR_BUFFER_BIT,颜色缓冲
GL_DEPTH_BUFFER_BIT,深度缓冲
GL_STENCIL_BUFFER_BIT,模板缓冲
值的预制主要通过glclearcolor,glcleardepth,glclearstencil来完成,它提前设置好值,OpenGL是一个状态机,它就相当于设置好了context的一个状态值。
参考:https://blog.csdn.net/qq_36383623/article/details/85115585
因此我运行的程序窗口的背景是黑色的~
glEnable() 用于启用各种功能。功能由参数决定。
程序中的参数GL_DEPTH_TEST 启用深度测试,根据坐标的远近自动隐藏被遮住的图形(材料)
glDepthFunc() 指定目标像素与当前像素在z方向上值大小比较的函数。
GL_LEQUAL,如果输入的深度值小于或等于参考值,则通过
glHint() 应用:glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 如果OpenGL不能有效的支持透视修正参数差值,那么GL_DONT_CARE 和 GL_FASTEST可以执行颜色、纹理坐标的简单线性差值计算。
GL_PERSPECTIVE_CORRECTION_HINT:指定颜色和纹理坐标的差值质量。如果OpenGL不能有效的支持透视修正参数差值,那么GL_DONT_CARE 和 GL_FASTEST可以执行颜色、纹理坐标的简单线性差值计算。
GL_NICEST在光栅化期间可以生成更多的像素段。选择最高质量选项。
参考资料:https://blog.csdn.net/blues1021/article/details/48769797 - DrawGLScene()
glTranslatef() 沿X轴正方向平移x个单位(x是有符号数) 沿Y轴正方向平移y个单位(y是有符号数)沿Z轴正方向平移z个单位(z是有符号数)
glRotatef() 先解释一下旋转方向,做(0,0,0)到(x,y,z)的向量,用右手握住这条向量,大拇指指向向量的正方向,四指环绕的方向就是旋转的方向;
函数功能:以点(0,0,0)到点(x,y,z)为轴,旋转angle角度;
glBegin() mode:创建元素的类型.
glBegin和glEnd函数限定了一组或多组图元的定点定义。
GL_TRIANGLES 把每个顶点作为一个独立的三角形,顶点3n-2,3n-1和3n定义了第n个三角形,绘制了N/3个三角形。
glColor3f() 需要注意的是,如果在glBegin()与glEnd()函数之间多次连续调用颜色函数,那么,只会显示出最后一次的颜色。它的参数应该有三个,类型是float型的。另外一点是它的参数值的范围是[0.0,1.0]"background-color: rgb(255, 255, 255); 。
本次实验圆满结束O(∩_∩)O哈哈~,欢迎分享交流。
OpenGL 实验一 绘制简单图形相关推荐
- Android openGl开发详解(一)——绘制简单图形
1. What? openGl是什么?openGl ES又是什么? 2. How? Android中的openGL 如何使用? 3. GlSurfaceView是什么? GLSurfaceView的作 ...
- SurfaceView简单理解,Android混淆,Android openGl开发详解简单图形的绘制,
SurfaceView允许你在非ui线程中去绘制. SurfaceView的帧率可以操作60FPS 在要求实时性比较高的游戏开发中,显然,view的ondraw是满足不了你的,这时候只能是用Surfa ...
- OpenGL实验:绘制彩色五角星
OpenGL实验:绘制彩色五角星 第二次编程作业内容 用配置好的OpenGL环境实现彩色五角星效果,以及把五角星作为3D对象绘制出来,通过按键能够调整角度(用J.K.L三个键分别控制三个互相正交方向上 ...
- [Qt教程] 第11篇 2D绘图(一)绘制简单图形
[Qt教程] 第11篇 2D绘图(一)绘制简单图形 楼主 发表于 2013-4-23 12:52:35 | 查看: 1398| 回复: 5 绘制简单图形 版权声明 该文章原创于Qter开源社区,作者 ...
- java 绘制长方形_Java入门:绘制简单图形
在上一节,我们学习了如何使用swing和awt工具创建一个空的窗口,本节学习如何绘制简单图形. 基本绘图介绍 Java中绘制基本图形,可以使用Java类库中的Graphics类,此类位于java.aw ...
- python opencv 绘制简单图形
09-python opencv 绘制简单图形 09-python opencv 绘制简单图形 概述 实现过程 引用与创建空图 绘制直线 绘制矩形 绘制圆 绘制椭圆 添加文字 显示图像 源代码 运行结 ...
- Python之Turtle库绘制简单图形
Python之Turtle库绘制简单图形 来绘制正方形.三角形.五边形.五角形 import turtle #引入turtle库pen=turtle.Turtle() #创建turtle类型的画笔 # ...
- plotly绘制简单图形4--饼形图
plotly绘制简单图形<1>--散点图折线图 plotly绘制简单图形<2>--条形图 plotly绘制简单图形<3>--设置按钮 本次说一下饼形图: 目录 1. ...
- plotly绘制简单图形5--饼形图附加
plotly绘制简单图形<4>--饼形图里说了饼形图的基本设置, 这里补充一个怎样设置两个饼图的方法(数据是爬取京东手机和电脑价格数据分析结果) import plotly.plotly ...
最新文章
- C语言中常用的数学公式
- BZOJ 1176([Balkan2007]Mokia-CDQ分治-分治询问)
- 超级计算机 26010,全球最强超级计算机搭载的SW26010处理器解析
- 超好看的科学科普书,孩子大人都可以看!
- CMU本科计算机科学,CMU计算机科学学院本科难录吗?
- opencv_python使用cv2.imread()读取中文路径报错问题(转)
- Canny边缘检测算法原理及其VC实现详解(一)
- SpringMVC工作原理的介绍
- Unity项目中的资源管理
- 2020 CUMCM全国大学生数学建模竞赛 B题 Notes
- [Telink][TLSR8251] [泰凌微]入门上手教程(IDE+SDK+烧录)
- Excel堆积柱形图制作过程
- 四六级得分技巧备考和心态
- Python+Vue计算机毕业设计教师教学质量评价管理2lbw7(程序+LW+源码+部署)
- 基于Echarts实现可视化数据大屏大数据平台车辆监控系统HTML模板
- “ORA-28007: the password cannot be reused”解决
- MATLAB 输入和输出参数
- 票据识别android代码,Android 百度AI开放平台-文字识别-财务票据文字识别
- LABVIEW以及各种驱动(VDM/VAS等)的安装教程
- 【python操作word和pdf】
热门文章
- 面试又被问高并发,哑口无言?一份高并发核心文档助你吊打面试官
- 骨传导耳机会伤害耳朵吗?骨传导耳机优点是什么
- 面向对象概念及对象、抽象、类的解释
- S型加减速程序,C++,PLC,AGV
- java从数据库读取zip文件的字节数组byte[]直接解压
- 网上经常听到的“终端”指的什么?
- C语言基础---3.格式化输出总结---%d ,%s,%f %.3f,%m.ns 以及sprintf函数
- mp3音频转换,合并方法?-QVE音频剪辑
- 泛知识+社交搜索,快手平台内容生态知识普惠价值凸显
- Android Studio入学1-3:通过okhttp连接服务器