OpenGL实验(一)彩色五角星绘制
2017-03-27 16:48
781 查看
Open Graphics Library (OpenGL) is a cross-language, cross-platform application programming interface (API) for rendering 2D and 3D vector graphics. The API is typically used to interact with a graphics processing unit (GPU), to achieve hardware-accelerated rendering. (wikipedia)
六角星……
其中两个为(0.1,0.3)(0.25,0)其余由对称可得。
对颜色进行分析。中点(0,0)为白色,周围一圈边界为一段纯色一段渐变。(这里mark一下 矩形的内部填充不知道是怎么实现的。三角形的填充可以认为,比如投影到R坐标系中的三个点,那中间任意一个点的R是可以用线性进行确定的)
http://www.cppblog.com/doing5552/archive/2009/01/08/71532.html
头文件
主函数
简单的绘制
glBegin — delimit the vertices of a primitive or a group of like primitives
与glEnd对应 为一次绘制
glBegin说明
https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glBegin.xml
GL_TRIANGLE_FAN:Draws a connected group of triangles. One triangle is defined for each vertex presented after the first two vertices.
以中心为第一个绘制的点。
函数如下
要是没有最后for循环外的两行代码图是这样的
完成图
= =!我看到了纸飞机
并没有(你期待中的)总结
这里暂时涉及到的是世界坐标系和当前绘图坐标系。
在绘制前对当前绘图坐标系进行旋转和移动,就可以实现实际绘制图形在世界坐标系的改变。
好的有点丑……
然后一涉及PI……我的CPU就转不过来了……
于是我想……能不能不通过计算具体的位置画出图来
基本思路就是 画一个点 转30度……很完美啊(躺
于是有了以下代码(突然发现颜色可以少存一半
然而没啥用(摊手
在绘制两个点的中间不管加旋转还是移动它都不理我
加了个glMatrixMode(GL_MODELVIEW);
还是不理我 我也很绝望啊
再留个坑吧
反正就是不好看QwQ
直接找个博客对着改……
http://blog.csdn.net/haohan_meng/article/details/23154511
然后一直是一个白的框
在我几次以为是背景把图盖住了(??)换了个背景色之后发现中间有一个隐隐约约的点
我画了颗星星怎么变成一个点了?
大概是隔了几亿光年吧……
综上(??),有几个参数稍微有点不一样(试一试也试出来了)(所以我大概其实没看懂这一段)
要求
以上 FROM ZJUCG
六角星……
思路
根据尺寸要求首先对12个点中6个未标示的点的坐标进行计算。其中两个为(0.1,0.3)(0.25,0)其余由对称可得。
对颜色进行分析。中点(0,0)为白色,周围一圈边界为一段纯色一段渐变。(这里mark一下 矩形的内部填充不知道是怎么实现的。三角形的填充可以认为,比如投影到R坐标系中的三个点,那中间任意一个点的R是可以用线性进行确定的)
OrenGL相关
具体可以参考http://www.cppblog.com/doing5552/archive/2009/01/08/71532.html
头文件
#include <GL/glut.h>
主函数
int main(int argc, char *argv[]) { glutInit(&argc, argv); //对GLUT进行初始化 glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); //设置显示方式,RGB 单缓存&多缓存 glutInitWindowPosition(100, 100); //窗口在屏幕中的位置 glutInitWindowSize(400, 400);//窗口的大小 glutCreateWindow("Birdy's OpenGL");//创建窗口 glutDisplayFunc(&myDisplay); glutMainLoop();//循环 return 0; }
简单的绘制
glBegin — delimit the vertices of a primitive or a group of like primitives
与glEnd对应 为一次绘制
glBegin说明
https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glBegin.xml
glColor3f(1, 0, 0); //选择红色 glBegin(GL_QUADS);//开始绘制 矩形 { glVertex2f(-0.9, 0.6); glVertex2f(0.9, 0.6); glVertex2f(0.9, -0.6); glVertex2f(-0.9, -0.6); } glEnd();//结束
实现
对glBegin的模式进行分析后认为GL_TRIANGLE_FAN比较符合预期。GL_TRIANGLE_FAN:Draws a connected group of triangles. One triangle is defined for each vertex presented after the first two vertices.
以中心为第一个绘制的点。
函数如下
/*@author Birdy@C*/ //确定每个点的坐标 const GLfloat point[2][12] = { { 0, 0.1, 0.4, 0.25, 0.4, 0.1, 0,-0.1, -0.4, -0.25, -0.4, -0.1 }, { 0.5, 0.3, 0.3, 0, -0.3, -0.3, -0.5, -0.3, -0.3, 0, 0.3, 0.3 } }; //确定每个点的颜色 GLfloat Color[3][12] = { 0 }; for (int i = 0; i < 12; i++) { if (i <= 3 || i >= 10) Color[0][i] = 1; // 0 1 2 3 10 11 if (i >= 2 && i <= 7) Color[1][i] = 1; // 2 3 4 5 6 7 if (i >= 6 && i <= 11) Color[2][i] = 1; // 6 7 8 9 10 11 } //六角星绘制 glBegin(GL_TRIANGLE_FAN); //开始绘制 { glColor3f(1, 1, 1); glVertex2f(0, 0); //中心点 for (int i = 0; i < 12; i++) { glColor3f(Color[0][i], Color[1][i], Color[2][i]);//选择颜色 glVertex2f(point[0][i], point[1][i]);//顶点 } glColor3f(Color[0][0], Color[1][0], Color[2][0]); glVertex2f(point[0][0], point[1][0]);//最后一个点要重画 } glEnd();
要是没有最后for循环外的两行代码图是这样的
完成图
其他尝试
关于颜色
之前提到的对颜色的差值特别好奇。想知道如果没有中间一个点的白色,会生成什么样的图片/*@author Birdy@C*/ glBegin(GL_POLYGON); { // glColor3f(1, 1, 1); // glVertex2f(0, 0); for (int i = 0; i < 12; i++) { glColor3f(Color[0][i], Color[1][i], Color[2][i]); glVertex2f(point[0][i], point[1][i]); } //glColor3f(Color[0][0], Color[1][0], Color[2][0]); //glVertex2f(point[0][0], point[1][0]); } glEnd();
= =!我看到了纸飞机
并没有(你期待中的)总结
加入旋转和移动
OpenGL好像有很多的坐标系……这里暂时涉及到的是世界坐标系和当前绘图坐标系。
世界坐标系也称为全局坐标系。它是一个右手坐标系,可以认为该坐标系是固定不变的,在初始态下,其x轴为沿屏幕水平向右,y轴为沿屏幕垂直向上,z轴则为垂直屏幕面向外指向用户,长度单位这样来定:窗口范围按此单位恰好是(-1,-1)(左下角)到(1,1)(右上角)。当然,如果在程序中对视点进行了转换,就不能再认为是这样的了。我们用这个坐标系来描述物体及光源的位置。世界坐标系是始终固定不变的。 当前绘图坐标系是绘制物体时的坐标系,就是模型坐标系,也是右手坐标系。程序刚初始化时,世界坐标系和当前绘图坐标系是重合的。当用glTranslatef(),glScalef(), glRotatef()对当前绘图坐标系进行平移、伸缩、旋转变换之后, 世界坐标系和当前绘图坐标系不再重合。改变以后,再用glVertex3f()等绘图函数绘图时,都是在当前绘图坐标系进行绘图,所有的函数参数也都是相对当前绘图坐标系来讲的。
在绘制前对当前绘图坐标系进行旋转和移动,就可以实现实际绘制图形在世界坐标系的改变。
/* 输入:中心坐标(cx,cy),旋转角度 angle(顺时针) */ void drawstar(const GLfloat cx, const GLfloat cy, GLfloat angle) { glTranslatef(cx, cy, 0); glRotatef(angle, 0, 0, -1); //顺时针旋转 /* .....中间绘制代码如上..... */ glLoadIdentity();//重置当前的模型观察矩阵,该句执行完后,将焦点移动到了屏幕的中心 } void display() { glClearColor(1.0, 1.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); drawstar(0, 0, 0); drawstar(0.5, 0.5, 60); drawstar(-0.5, -0.5, 120); glFlush(); glutSwapBuffers(); //交换两个缓冲区指针 }
好的有点丑……
不成功的绘制
由于它有点丑……就想能不能画出一个标准的圆……然后一涉及PI……我的CPU就转不过来了……
于是我想……能不能不通过计算具体的位置画出图来
基本思路就是 画一个点 转30度……很完美啊(躺
于是有了以下代码(突然发现颜色可以少存一半
glTranslatef(cx, cy, 0); glRotatef(angle, 0, 0, -1); //顺时针旋转 const GLfloat length1 = 0.5, length2 = 0.3; GLfloat Color[3][6] = { 0 }; //RGB for (int i = 0; i < 6; i++) { if (i <= 1 || i >= 5) Color[0][i] = 1; // 0 1 5 if (i >= 1 && i <= 3) Color[1][i] = 1; // 1 2 3 if (i >= 3 && i <= 5) Color[2][i] = 1; //3 4 5 } glMatrixMode(GL_PROJECTION); glBegin(GL_TRIANGLE_FAN); { glColor3f(1, 1, 1); glVertex2f(0, 0); for (int i = 0; i < 6; i++) { glColor3f(Color[0][i], Color[1][i], Color[2][i]); glVertex2f(0, length1); glRotatef(30, 0, 0, -1); //顺时针旋转 glTranslatef(1, 1, 0); glVertex2f(0.5, length2); glRotatef(30, 0, 0, -1); //顺时针旋转 } glColor3f(Color[0][0], Color[1][0], Color[2][0]); glVertex2f(0, length1); } glEnd();
然而没啥用(摊手
在绘制两个点的中间不管加旋转还是移动它都不理我
加了个glMatrixMode(GL_MODELVIEW);
还是不理我 我也很绝望啊
再留个坑吧
窗口缩放
这里涉及的问题是一拉伸窗口……看图看图反正就是不好看QwQ
直接找个博客对着改……
http://blog.csdn.net/haohan_meng/article/details/23154511
然后一直是一个白的框
在我几次以为是背景把图盖住了(??)换了个背景色之后发现中间有一个隐隐约约的点
我画了颗星星怎么变成一个点了?
大概是隔了几亿光年吧……
综上(??),有几个参数稍微有点不一样(试一试也试出来了)(所以我大概其实没看懂这一段)
void ChangeSize(GLsizei w, GLsizei h) { GLfloat aspectRatio; // 防止被0所除 if (0 == h) { h = 1; } glViewport(0, 0, w, h);// 设置视口为窗口的大小 glMatrixMode(GL_PROJECTION);// 选择投影矩阵,并重置坐标系统 glLoadIdentity(); aspectRatio = (GLfloat)w / (GLfloat)h;// 计算窗口的纵横比(像素比) // 定义裁剪区域(根据窗口的纵横比,并使用正投影) if (w <= h) {// 宽 < 高 glOrtho(-1.0, 1.0, -1 / aspectRatio, 1 / aspectRatio, 1.0, -1.0); } else {// 宽 > 高 glOrtho(-1.0 * aspectRatio, 1.0 * aspectRatio, -1.0, 1.0, 1.0, -1.0); } glMatrixMode(GL_MODELVIEW);// 选择模型视图矩阵,并重置坐标系统 glLoadIdentity(); }
完整代码
// @author Birdy&C #include "gl/glut.h" /* 输入:中心坐标(cx,cy),旋转角度 angle(顺时针) */ void drawstar(const GLfloat cx, const GLfloat cy, GLfloat angle) { glTranslatef(cx, cy, 0); glRotatef(angle, 0, 0, -1); //顺时针旋转 //确定每个点的坐标 const GLfloat point[2][12] = { { 0, 0.1, 0.4, 0.25, 0.4, 0.1, 0,-0.1, -0.4, -0.25, -0.4, -0.1 }, { 0.5, 0.3, 0.3, 0, -0.3, -0.3, -0.5, -0.3, -0.3, 0, 0.3, 0.3 } }; //确定每个点的颜色 GLfloat Color[3][12] = { 0 }; for (int i = 0; i < 12; i++) { if (i <= 3 || i >= 10) Color[0][i] = 1; // 0 1 2 3 10 11 if (i >= 2 && i <= 7) Color[1][i] = 1; // 2 3 4 5 6 7 if (i >= 6 && i <= 11) Color[2][i] = 1; // 6 7 8 9 10 11 } //六角星绘制 glBegin(GL_TRIANGLE_FAN); //开始绘制 { glColor3f(1, 1, 1); glVertex2f(0, 0); //中心点 for (int i = 0; i < 12; i++) { glColor3f(Color[0][i], Color[1][i], Color[2][i]);//选择颜色 glVertex2f(point[0][i], point[1][i]);//顶点 } glColor3f(Color[0][0], Color[1][0], Color[2][0]); glVertex2f(point[0][0], point[1][0]); } glEnd(); glLoadIdentity();//重置当前的模型观察矩阵,该句执行完后,将焦点移动到了屏幕的中心 } void display() { glClearColor(1.0, 1.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); drawstar(0, 0, 0); drawstar(0.5, 0.5, 60); drawstar(-0.5, -0.5, 120); glFlush(); glutSwapBuffers(); //交换两个缓冲区指针 } void ChangeSize(GLsizei w, GLsizei h) { GLfloat aspectRatio; // 防止被0所除 if (0 == h) { h = 1; } glViewport(0, 0, w, h);// 设置视口为窗口的大小 glMatrixMode(GL_PROJECTION);// 选择投影矩阵,并重置坐标系统 glLoadIdentity(); aspectRatio = (GLfloat)w / (GLfloat)h;// 计算窗口的纵横比(像素比) // 定义裁剪区域(根据窗口的纵横比,并使用正投影) if (w <= h) {// 宽 < 高 glOrtho(-1.0, 1.0, -1 / aspectRatio, 1 / aspectRatio, 1.0, -1.0); } else {// 宽 > 高 glOrtho(-1.0 * aspectRatio, 1.0 *aspectRatio, -1.0, 1.0, 1.0, -1.0); } glMatrixMode(GL_MODELVIEW);// 选择模型视图矩阵,并重置坐标系统 glLoadIdentity(); } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); glutInitWindowPosition(10, 10); glutInitWindowSize(400, 400); glutCreateWindow("My Star _Birdy"); glutDisplayFunc(display); glutReshapeFunc(ChangeSize);// 设置当窗口的大小发生变化时的回调函数 glutMainLoop(); //注册绘制回调函数 return 0; }
感想
线代要好好学…… 不知道openGL的运行机制是怎么样的…… 那么多杂七杂八的坐标系…… 好想当一个能动不动carry全队的人w 啥时候画个好看的男孩子出来…… (无视以上)
相关文章推荐
- OpenGL实验:绘制彩色五角星
- OpenGL(一)绘制圆、五角星、正弦曲线
- 整理 qt opengl,自己的基础框架 —— 绘制一个彩色三角形
- OpenGL(一)绘制圆、五角星、正弦曲线
- 计算机图形学-OpenGL-绘制五角星
- VC6环境下OpenGL入门——绘制一个彩色三角型
- Opengl -- 五角星的绘制
- OpenGL入门示例7——黑色背景绘制彩色ZUFE字母
- 整理 qt opengl,自己的基础框架 —— 绘制一个彩色三角形
- OpenGL - 国旗绘制(五角星绘制)
- OpenGL入门示例6——黑色背景绘制彩色点画多边形
- opengl学习入门之模拟器利用element方法绘制五角星
- 使用opengl绘制五角星图形
- OpenGL入门示例5——黑色背景绘制彩色旋转立方体
- OpenGL入门示例4——黑色背景绘制彩色点画线
- 解析RTSP流后,使用opengl在MFC界面绘制1920*1080P的图像
- OpenGL实现Hermite算法绘制三次曲线
- OpenGL绘制长方体线框
- OpenGL3D图形绘制/纹理映射
- OpenGL 绘制国民党党徽 共青团团徽 花型(可变边的数目)