(四)OpenGL窗口管理

  • 1.glutCreateWindow 创建顶层窗口
  • 2.glutCreateSubWindow 创建子窗口
  • 3.glutSetWindowTitle 设置当前顶层窗口的窗口标题
  • 4.glutPositionWindow 申请改变当前窗口的位置
  • 5.glutPostRedisplay 标记当前窗口需要重新绘制
  • 6.glutSwapbuffers 交换当前窗口的缓存

1.glutCreateWindow 创建顶层窗口

int glutCreateWindow(char * name)
参数说明: name 窗口标题
返回值:窗口的int型标识符,在调用之后的glutSetWindow时使用

2.glutCreateSubWindow 创建子窗口

int glutCreateSubWindow(int win, int x, int y, int width, int height)
参数说明:win 子窗口的父窗口的标识符
    x,y 子窗口相对于父窗口左上角的x,y坐标
返回值:窗口的int型标识符,与glutCreateWindow的返回值一个性质
代码举例(画一个绿色三角形):

#include 
#include 
#include 
#include 

//将背景初始化为白色
void init(){
    glClearColor(1,1,1,1);
}
//画一个绿色的三角形
void display(){
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(0,1,0);
    glBegin(GL_LINE_LOOP);
        glVertex2f(50,50);
        glVertex2f(100,50);
        glVertex2f(100,100);
    glEnd();
    glFlush();
}

void reshape(GLsizei w,GLsizei h){
    gluOrtho2D(0,w,0,h);//更改窗口坐标系,窗口的左上、左下、右下、右上的坐标分别为(0,h)(0,0)(w,0)(w,h)
}

int main(int argc,char* * argv){
    glutInit(&argc,argv);
	
	//创建窗口
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(600,400);
    glutInitWindowPosition(150,150);
    int x1=glutCreateWindow("ortho1 ");//创建窗口的同时得到标识符
    init();
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);

	//创建子窗口
    glutCreateSubWindow(x1,50,50,200,200);//子窗口左上角相对父窗口左上角的位置为(50,50),大小为200*200
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);


    glutMainLoop();
    return 0;
}

运行结果:
(四)OpenGL窗口管理_第1张图片

3.glutSetWindowTitle 设置当前顶层窗口的窗口标题

void glutSetWindowTitle(char * name)
参数说明: name 与glutCreateWindow中的name相同,都是顶层窗口的名称
创建窗口时使用glutCreateWindow确定名称,窗口创建完成后,使用glutSetWindowTitle改变窗口名称.

4.glutPositionWindow 申请改变当前窗口的位置

void glutPositionWindow(int x, int y)
参数说明: x,y 当前窗口新位置的左上角x,y坐标
与3类似,创建窗口时使用glutInitWindowPosition确定窗口位置,窗口创建完成后,使用glutPositionWindow 改变当前窗口的位置.

5.glutPostRedisplay 标记当前窗口需要重新绘制

void glutPostRedisplay(void)
  标记当前窗口的图像层需要重新绘制。由于在glutMainLoop函数调用后,会循环处理,因此在下一个循环中会处理重绘请求。但是main函数中的一个重绘请求只能使用一次,因此需要在其它函数中调用以达到不停重绘从而形成动画的效果。示例代码如5所示。

6.glutSwapbuffers 交换当前窗口的缓存

void glutSwapbuffers(void)
  将后台缓存中的内容交换到前台缓存中。如果使用的不是GLUT_DOUBLE结构,该函数不起任何作用。
画一个不断移动的绿色正方形:

#include 
#include 
#include 
#include 

GLfloat x = 10.0f;//矩形左上角的x坐标
GLfloat y = 20.0f;//矩形左上角的y坐标
GLfloat xsize = 10.0f;//矩形每次横向平移长度
GLfloat ysize = 10.0f;//矩形每次纵向平移长度
GLfloat length = 50.0f;//这里直接设置为正方形,因此表示正方形的边长
GLfloat width = 0.0f;//窗口宽度
GLfloat height = 0.0f;//窗口长度

//画一个绿色矩形
void diplay(){
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(0,1,0);

    //当矩形遇到边界时反弹
    if(x+length > width   ||   x+xsize < 0) xsize = (-1)*xsize;
    if(y+length > width   ||   y+ysize < 0) ysize = (-1)*ysize;
    if(x+length > width) x = width-length+xsize;
    if(y+length > width) y = width-length+ysize;
    
    //画一个矩形,四个参数分别是矩形左上角的x、y坐标,矩形右下角的x、y坐标
    glRectf(x,y,x+50,y+50);
    glutSwapBuffers();
}

void reshape(GLsizei w,GLsizei h){
    width = w;
    height = h;
    gluOrtho2D(0,w,0,h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
}

//每隔200ms重画一次
void animate(){
    Sleep(200);
    x += xsize;
    y += ysize;

    glutPostRedisplay();
}

//响应键盘按钮,如果按下q,则终止程序并退出;如果按下u,矩形上移;如果按下d,矩形下移
void key(unsigned char inp, int xi, int yi){
    printf("%c",inp);
    switch(inp){
        case 'q':
            printf("get it");
            exit(0);
        case 'u':
            x+=20;
            y+=20;
            break;
        case 'd':
            x-=20;
            y-=10;
            printf("down \n");
            break;
        default:
            break;
    }
    glutPostRedisplay();
}

int main(int argc, char *argv[]){
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
    glutInitWindowPosition(150,150);
    glutInitWindowSize(400,400);

    glutCreateWindow("moving");
    glutDisplayFunc(diplay);
    //glutKeyboardFunc(key);//响应键盘,暂时不考虑,有兴趣的可以解注释试试
    glutReshapeFunc(reshape);
    glutIdleFunc(animate);

    glutMainLoop();
    return 0;

}

你可能感兴趣的:(做小游戏用到的OpenGL知识)