您的位置:首页 > 编程语言 > C语言/C++

C++(11):OpenGL坐标系及绘制多个矩形

2017-10-16 17:20 2166 查看
(1)我的开发环境是VS2015,在运用OpenGL进行图形绘制之前,首先需要先下载glut库(下载链接:http://download.csdn.net/download/qq_27170195/10024519)。

解压得到5个文件:glut.h,glut.dll,glut32.dll,glut.lib,glut32.lib。

(2)安装glut库。

在VS2015的安装路径下的/VC/include/下新建一个文件夹GL,然后复制glut.h到这个文件夹下,然后复制glut.lib和glut32.lib到MY_VS_ROOT/VC/lib/下,最后复制glut.dll和glut32.dll到系统的dll目录下:C:\Windows\system32文件夹内(32位系统)或和C:\Windows\SysWOW64(64位系统)。

(3)OpenGL坐标系讲解:

openGL中,其坐标系如图所示:



而想要在此坐标系下绘制矩形时,便需要结合坐标给出正方形对角线的左下和右上的两个坐标(x1,y1,x2,y2)即可,比如要绘制下图的矩形,便需要给出的坐标为(-1,0.8,-0.8,1)。



由于我们本文要处理的数据数量为50个,所以人为将窗口分成了一个5行10列的划分,在编程时我们的处理方式为对窗口进行一行一行的分别绘制矩形,因此关键便在于每一行的第一个初始的坐标的确定,当每行的第一个矩形确定后,由于处于同一行的矩形的两个y轴坐标都是相同的,因此只需要从左到右依次对每个矩形的两个x轴坐标进行进行逐加即可。

所以在实际编程中,绘制时有以下几个步骤:(数组下标为i(i<50))

(1) 得出屏幕上5行的每一行的初始正方形坐标(正方形大小为0.2*0.2)

(2)对当前矩形位于第几行L进行判断:

由于是一个包含50个元素的一位数组,因此利用下标i除以10,便可知道行数,因此有:L
= i/10

(3)绘制当前行的第k个坐标:

由于行数L的范围为0至4,因此,假设计算第一行的初始矩形坐标为(x1,y1,x2,y2),要计算第一行的第k个正方形的坐标,便有:

(x1 +
(i-n)*0.2 ,  y1 , x2 +(i-n)*0.2
, y2) (n=0,10,20,30,40)
n为相应的行数乘以10得到的值,因此只要得知每一行的初始矩形坐标,便可计算每一行的其余正方形坐标了。



(4)打开VS2015建立一个Win32控制台程序->选择空项目->完成。

编写代码如下:

#include <GL/glut.h>
#include <iostream>
using namespace std;

void myDisplay(void)
{

float x1, y1, x2, y2,tag=0.2;		//xy为坐标,tag为绘制矩形时需要用到的数据

//根据元素255,0绘制黑框和白框的矩形
int displayData[] = { 255,255,255,255,0,0,0,255,0,
0,0,0,255,255,0,0,0,0,0,255,255,255,255,
255,255,255,255,0,0,0,0,255,255,0,0,0,0,
0,255,255,255,255,255,0,0,0,255,0,0,0 };
int disLength = 50;		//共50个元素,5行10列,
int res = 0;			//用于判断矩形在第几行
glClear(GL_COLOR_BUFFER_BIT);		//清除。GL_COLOR_BUFFER_BIT表示清除颜色,glClear函数还可以清除其它的东西,

//glRectf(x1, y1, x2, y2);//画一个矩形。四个参数分别表示了位于对角线上的左下和右上两个点的横、纵坐标。

//第1行左起第一个点(-1,0.8,-0.8,1),为坐标初始点赋值
x1 = -1; y1 = 0.8, x2 = -0.8, y2 = 1;

for (int i = 0; i < 50; i++)
{
if (displayData[i] > 0)
{
glColor3f(0.0f, 0.0f, 0.0f);//黑色
res = i / 10;
switch (res)
{
case 0://第1列左起第一个点(-1,0.8,-0.8,1)
x1 = -1; y1 = 0.8, x2 = -0.8, y2 = 1;
glRectf(x1 + (i*tag) + 0.05, y1, x2 + (i*tag), y2);
break;
///*
case 1://第2列左起第一个点(-1,0.4,-0.8,0.6)
x1 = -1; y1 = 0.4, x2 = -0.8, y2 = 0.6;
glRectf(x1 + ((i - 10)*tag + 0.05), y1, x2 + ((i - 10)*tag), y2);
break;

case 2://第2列左起第一个点(-1,0,-0.8,0.2)
x1 = -1; y1 = 0, x2 = -0.8, y2 = 0.2;
glRectf(x1 + ((i - 20)*tag + 0.05), y1, x2 + ((i - 20)*tag), y2);
break;

case 3://第2列左起第一个点(-1,-0.4,-0.8,-0.2)
x1 = -1; y1 = -0.4, x2 = -0.8, y2 = -0.2;
glRectf(x1 + ((i - 30)*tag + 0.05), y1, x2 + ((i - 30)*tag), y2);
break;

case 4://第2列左起第一个点(-1,-0.8,-0.8,-0.6)
x1 = -1; y1 = -0.8, x2 = -0.8, y2 = -0.6;
glRectf(x1 + ((i - 40)*tag + 0.05), y1, x2 + ((i - 40)*tag), y2);
break;
//*/
default:
break;
}
}
else
{
glColor3f(1.0f, 1.0f, 1.0f);//白色
res = i / 10;
switch (res)
{

case 0://第1列左起第一个点(-1,0.8,-0.8,1)
x1 = -1; y1 = 0.8, x2 = -0.8, y2 = 1;
glRectf(x1 + (i*tag) + 0.05, y1, x2 + (i*tag), y2);//0.05是间隙
break;
///*
case 1://第2列左起第一个点(-1,0.4,-0.8,0.6)
x1 = -1; y1 = 0.4, x2 = -0.8, y2 = 0.6;
glRectf(x1 + ((i - 10)*tag + 0.05), y1, x2 + ((i - 10)*tag), y2);
break;

case 2://第2列左起第一个点(-1,0,-0.8,0.2)
x1 = -1; y1 = 0, x2 = -0.8, y2 = 0.2;
glRectf(x1 + ((i - 20)*tag + 0.05), y1, x2 + ((i - 20)*tag), y2);
break;

case 3://第2列左起第一个点(-1,-0.4,-0.8,-0.2)
x1 = -1; y1 = -0.4, x2 = -0.8, y2 = -0.2;
glRectf(x1 + ((i - 30)*tag + 0.05), y1, x2 + ((i - 30)*tag), y2);
break;

case 4://第2列左起第一个点(-1,-0.8,-0.8,-0.6)
x1 = -1; y1 = -0.8, x2 = -0.8, y2 = -0.6;
glRectf(x1 + ((i - 40)*tag + 0.05), y1, x2 + ((i - 40)*tag), y2);
break;
//*/
default:
break;
}
}
}

glFlush();//保证前面的OpenGL命令立即执行(而不是让它们在缓冲区中等待)
}
int main()
{
//glutInit(&argc, argv);
//int data[] = { 255,255,255,255,0,0,0,255,0,0,0,0,255,255,0,0,0,0,0,255,255,255,255,255,255,255,255,0,0,0,0,255,255,0,0,0,0,0,255,255,255,255,255,0,0,0,255,0,0,0 };

glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);//设置显示方式,其中GLUT_RGB表示使用RGB颜色,与之对应的还有GLUT_INDEX(表示使用索引颜色)
glutInitWindowPosition(100, 100);//设置窗口在屏幕中的位置。
glutInitWindowSize(600, 600);//设置窗口大小
glutCreateWindow("OpenGL多矩形框绘制");//窗口标题
glutDisplayFunc(&myDisplay);//设置一个函数,当需要进行画图时,这个函数就会被调用
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);	//设置背景为灰色
glutMainLoop();//进行一个消息循环

return 0;
}
(5)生成窗口:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: