OpenGL程序-输出-学号、姓名、照片等信息。直线、线型、字体程序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
作业1
一:作业目的及要求:
采用OpenGL程序,输出学号、姓名、照片等信息。
直线、线型、字体程序。
二:理论基础:
1.使用GLUT进行窗口管理:
(1)与大小有关的
glutInitWindowSize(800,600); //用来定义显示窗口的初始化宽度和高度的像素数glutInitWindowPosition(200,200); //显示窗口左上角应该在屏幕左边界向右50个像素、屏幕上边界100像素的位置上。
gluOrth02D(0.0,200.0,0.0,150.0); //这表示使用正投影将世界坐标系二维矩形区域的内容映射到屏幕上。
以上三个概念需要弄清,其中gluOrtho2D是指屏幕区域对应的模型坐标范围,比如横向范围是0到200米,纵向是0到150米,而后面的glutInitWindowSize是指glut的窗口弹出来后相对于你电脑屏幕的位置和大小,单位是像素。
(2)窗口颜色设置
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); //指出显示窗口使用单个缓存且使用RGB (红绿蓝)颜色模型来设置颜色值
glClearColor(1.0,1.0,1.0,0.0) //设置窗口背景颜色为白色,前三个变量为红绿蓝分量,最后一个为调和参数,相当于透明度。
glClear(GL_COLOR_BUFFER_BIT); //让赋予窗口的颜色在屏幕上显示。
Glcolor3f(1.0,0.0,0.0); //显示场景中各种对象的颜色,左边的简单的设置为红色(3)其他
glutInit(&argc, argv); //GLUT初始化函数
glutCreateWindow(" "); //显示窗口创建定一个标题
glutDisplayFunc(Display); //将创建的图形的定义传递给GLUT函数
glutMainLoop(); //创建的窗口及其中的图形内容激活
2.输出图元
(1)OpenGL画点函数
OpenGL中定义的点放在函数glBegin()和glEnd()之间,有函数glBegin()的参数指定绘制图元的类型。
在OpenGL中绘制一个点时,点大小的默认值是一个像素。
可以用函数glPointSize(GLfloat size)修改这个值。
这个函数采用一个参数来指定画点时以像素为单位的近似直径。
但是不是任意大小点都支持,通常使用下面的代码来获取点大小的范围和他们的之间最小的中间值:GLfloat sizes[2];//保存绘制点的尺寸范围
GLfloat step;//保存绘制点尺寸的步长
glGetFloatv(GL_POINT_SIZE_RANGE,sizes);
glGetFloatv(GL_POINT_SIZE_RANULARITY,&step);
在OpenGL程序中,我们常可以利用离散的点来拟合一些常见的曲线,如圆,螺旋线等。
(2)OpenGL的画线函数
使用模式GL_LINES可以在两点之间画线;
有时我们需要在一系列的顶点之间绘制连续直线,此时需要用到GL_LINE_STRIP或GL_LINE_LOOP模式。
GL_LINE_STRIP模式可以根据指定的一系列顶点,从一个顶点到另一个顶点用连续的线段画线。
特别的,当沿着某条曲线指定一系列靠的很近的点,使用GL_LINE_STRIP模式可以绘制一条曲线。
GL_LINE_LOOP模式与GL_LINE_STRIP模式类似,只是会在指定的最后一个顶点与第一个顶点之间画最后一条线。
直线的属性包括线宽和线型。
在OpenGL中可用void glLineWidth(GLfloat width)指定线宽。
可以用下面的代码来获取线宽范围和他们的之间的最小间隔:
GLfloat sizes[2]; //保存线宽的尺寸范围
GLfloat step; //保存线宽尺寸的最小间隔
glGetFloarv(GL_LINE_WIDTH_RANGE,sizes);
glGetFloarv(GL_LINE_WIDTH_GRANULARITY,&step);
数组sizes中保存了glLineWidth的最小有效值和最大有效值,而变量step将保存线宽之间允许的最小增量。
Microsoft的OpenGL实现允许线宽从0.5到10.0,最小增量为0.125.
(3)OpenGL的字符生成函数
字符指数字、字母、汉字等符号。
计算机中字符由一个数字编码唯一标识。
“美国信息交换用标准代码集”简称ASCII码。
它是用7位二进制数进行编码表示128个字符汉字编码的国家标准字符集。
每个符号由一个区码和一个位码(2字节)共同标识。
区分ASCII码与汉字编码,采用字节的最高位来标识
GlutBitmapCharacter(front,charater) //c是字符的ASCII码,该函数显示位图字符glutStrokeCharacter(front,charater) //函数显示轮廓字符。
三:算法及设计分析
算法1:输出学号及名字
(1)设计分析
输出汉字和英文字符,显示中文和显示英文并无不同,同样是把要显示的字符做成显示列表,然后进行调用。
但是有一个问题,英文字母很少,最多只有几百个,为每个字母创建一个显示列表,没有问题。
但是汉字有非常多个,如果每个汉字都产生一个显示列表,这是不切实际的。
这里还经常涉及到中文乱码的问题,也就是说中文占两个字符,英文占一个字符,当然把两个字符的东西放到一个字符的空间里面会产生截断,自然不能正常显示。
在教材当中没有中文字符的输出,只有基本的英文字符输出,因此在网上版本,找到使用了MultiByteToWideChar这个函数的,基本上都没有出现乱码,所以用这个函数。
wglUseFontBitmapsW函数是wglUseFontBitmaps函数的宽字符版本,它认为字符都占两个字节。
(2)函数分析
(3)运行结果
算法2:直线线型函数
(1)设计分析
Opengl中使用图元常量可以得到多种画线的方法,在画线的同时可以对线进行不同的属性设置,线宽属性,线型属性,通过对点的设置,对线性的设置可以得到不同的线段。
(2)算法中主要函数分析
(3)运行结果
附录:
程序源代码如下:
算法1:输出学号及名字
#include <windows.h>
#include "glut.h"
void drawCNString(const char* str) {
int len, i;
wchar_t* wstring;
HDC hDC = wglGetCurrentDC();
GLuint list = glGenLists(1);
// 计算字符的个数
// 如果是双字节字符的(比如中文字符),两个字节才算一个字符// 否则一个字节算一个字符
len = 0;
for(i=0; str[i]!='\0'; ++i)
{
if( IsDBCSLeadByte(str[i]) )
++i;
++len;
}
// 将混合字符转化为宽字符
wstring = (wchar_t*)malloc((len+1) * sizeof(wchar_t));
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, wstring, len);
wstring[len] = L'\0';
// 逐个输出字符
for(i=0; i<len; ++i)
{
wglUseFontBitmapsW(hDC, wstring[i], 1, list);
glCallList(list);
}
// 回收所有临时资源
free(wstring);
glDeleteLists(list, 1);
}
void selectFont(int size, int charset, const char * face)
{
HFONT hFont = CreateFontA(size, 0, 0, 0, FW_MEDIUM, 0, 0, 0,
charset, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, face);
HFONT hOldFont = (HFONT)SelectObject(wglGetCurrentDC(), hFont);
DeleteObject(hOldFont);
}
void Display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
selectFont(48, DEFAULT_CHARSET, "宋体");
glColor3f(1.0f, 0.0f, 0.0f);
glRasterPos2f(-0.8f, 0.6f);
drawCNString("姓名:");
selectFont(64, DEFAULT_CHARSET, "宋体");
glColor3f(1.0f, 1.0f, 0.0f);
glRasterPos2f(-0.8f, 0.1f);
drawCNString("学号:");
glutS();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(800,600);
glutInitWindowPosition(200,200);
glutCreateWindow("输出学号姓名");
glutDisplayFunc(Display);
glutMainLoop();
return 0;
}
算法2:直线线型函数
#include "glut.h"
void RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0f,0.0f,0.0f);
GLfloat sizes[2];//保存绘制点的尺寸范围
GLfloat step;//保存绘制点尺寸的步长
GLfloat curSize;//当前绘制的点的大小
glGetFloatv(GL_POINT_SIZE_RANGE,sizes);//获得点的尺寸范围
glGetFloatv(GL_POINT_SIZE_GRANULARITY,&step);//获得点尺寸的步长
//绘制不同大小的点
curSize = sizes[0];
for (int i=0; i < 25; i++)
{
glPointSize(curSize);//设置点的大小
glBegin(GL_POINTS);
glVertex3f(25.0+i*8,200.0f,0.0f);
glEnd();
curSize += step * 2;
}
//绘制一条宽度为5的直线
glLineWidth(5);//设置线宽
glBegin(GL_LINES);
glVertex3f(20.0f,150.0f,0.0f);
glVertex3f(220.0f,150.0f,0.0f);
glVertex3f(200.0f,160.0f,0.0f);
glVertex3f(200.0f,160.0f,0.0f);
glEnd();
//在xy平面内绘制了两条直线(0,0,0)到(10,0,0)和(0,10,0)到(20,5,0). glBegin(GL_LINE_STRIP);
glVertex3f(0.0f,0.0f,0.0f);
glVertex3f(10.0f,10.0f,0.0f);
glVertex3f(20.0f,5.0f,0.0f);
glEnd();
//画了一个三角形
glBegin(GL_LINE_LOOP);
glVertex3f(100.0f,100.0f,0.0f);
glVertex3f(150.0f,150.0f,0.0f);
glVertex3f(200.0f,50.0f,0.0f);
glEnd();
//绘制一条虚线
glEnable(GL_LINE_STIPPLE);
glLineStipple(1,0x00ff);//设置点划线模式
glBegin(GL_LINES);
glVertex3f(20.0f,120.0f,0.0f);
glVertex3f(220.0f,120.0f,0.0f);
glEnd();
//绘制一条宽度为3的点划线
glLineWidth(3);
glLineStipple(1,0xff0c);
glBegin(GL_LINES);
glVertex3f(20.0f,80.0f,0.0f);
glVertex3f(220.0f,80.0f,0.0f);
//增加重复因子绘制的点划线
glLineStipple(4,0xFF0C);
glBegin(GL_LINES);
glVertex3f(20.0f,40.0f,0.0f);
glVertex3f(220.0f,40.0f,0.0f);
glEnd();
glDisable(GL_LINE_STIPPLE);
glFlush();
}
void ChangeSize(GLsizei w,GLsizei h)
{
if(h == 0)
{
h = 1;
}
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
{
glOrtho(0.0f,250.0f,0.0f,250.0f*h/w,1.0f,-1.0f);
}
else
{
glOrtho(0.0f,250.0f*w/h,0.0f,250.0f,1.0f,-1.0f);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void SetupRC()
{
glClearColor(1.0f,1.0f,1.0f,1.0f);
}
void main()
{
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutCreateWindow("点与线");
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
glutMainLoop(); }。