OpenGL【1】视图类与鼠标坐标操作

来源:互联网 发布:西门子300plc编程实例 编辑:程序博客网 时间:2024/06/03 22:52
定义视窗大小的函数
glViewport (0, 0,  w,  h);(<—这玩意儿一定要记得后面两个参数是长和高,不是x,y坐标)
在自定义的mydisplay函数里面任意时刻开始编写。定义窗口位置数据从左下角开始(0,0),右上角结束
(参考链接glviewport)
从下图可以知道,无论如何扩大窗口,glviewport后的绘图代码,只在定义的左下角400x400区域绘制

OpenGL【1】视图类与鼠标坐标操作

这里可以设置矩阵模式:
glMatrixMode (GL_PROJECTION);

创建完视觉范围glviewport以后,在创建gluOrtho2D正交投影或者透视投影坐标之前,必须先装载单位矩阵,不然每次都会依照上一次运算完的矩阵叠加装载,在gl循环里面会不断更改视角,结果回悲剧。
glLoadIdentity ();

然后就是创建投影坐标:
gluOrtho2D (0, w, 0, h);


强制刷新命令
(参考链接:glFlush和glFinish以及SwapBuffer的用法)

   OpenGL 绘图的机制是: 先用 OpenGL的绘图上下文 Rendering Context (简称为 RC )把图画好,再把所绘结果通过 SwapBuffer() 函数传给Window 的 绘图上下文 Device Context (简记为 DC).要注意的是,程序运行过程中,可以有多个DC,但只能有一个 RC。因此当一个 DC 画完图后,要立即释放 RC,以便其它的 DC 也使用。

 

glFlush:GL命令队列中的命令发送给显卡并清空命令队列,发送完立即返回;

glFinish:GL命令队列中的命令发送给显卡并清空命令队列,显卡完成这些命令(也就是画完了)后返回。

 

   因此,在绘图命令比较冗长的情况下,可以分段调用glFlush以清空命令队列并让显卡开始先执行这些命令,最后调用glFinish来同步。举个例子:我的渲染器一共有9shader,渲染时从shader0一直渲染到shader8,以前是在所有shader渲染完成后才调用glFinish(注意:这里如果把glFinish换成glFlush,那么调用wglSwapBuffer的时候在不同的平台上会产生不同的结果,具体结果我也不清楚,个人感觉好像没什么问题,但是游戏的时钟系统会被扰乱——最明显的就是帧速算错),那么CPU就要等GPU绘图,浪费了大把大把的时间;现在改成每个shader完成后调用一次glFlush,强制GPU开始执行命令队列中的GL命令,最后调用glFinish等待GPU完成当前帧渲染,然后调用wglSwapBuffer调换前后缓存。

 

这里就会发现这样一件事情:无论如何,都要等glFinish返回了,如果GPU绘制需要比较多的时间,那么CPU在这里等待的时间就比较可观了,如何提高CPU效率呢?个人认为有两个办法:

1、使用多线程。将更新和渲染作为线程A,辅助性计算如AI策略、**图生成作为线程B。那么当线程A因为glFinish阻塞时,线程B便可以利用CPU进行计算。

2、使用CPU时间预算方法。即先给出一帧所需要的时间预算,在调用glFinish之前判断是否还有多的时间预算,若有多,则先作辅助计算,完成或超过预算时间后才调用glFinish(若此时GPU已经完成命令,就不需要等待了)

 

   对于SwapBuffers,SwapBuffer命令只是把前台和后台的缓冲区指针交换一下而已也就是把前台的内容变成后台缓冲的内容,把后台的缓冲内容换到了前台这个函数它本身并不对换过来的成为了后台的buffer做清理工作,所以每帧都glClear一次,然后再绘制,而后再SwapBuffers。


重绘制窗口大小声明函数

void reshape (int w, int h){}

重绘制窗口大小注册函数

glutReshapeFunc(reshape);

有关该函数无作为的问题,在main函数里面的注册顺序一定不能乱

如果先reshape再createwindow,reshape函数永远也执行不了!

glutReshapeFunc(&reshape);

glutCreateWindow("My firstOpenGL program");
glutDisplayFunc(&myDisplay);

必须这样才可以:

glutCreateWindow("My first OpenGL program");
glutReshapeFunc(&reshape);
glutDisplayFunc(&myDisplay);

___________________________________________________________________________
保持显示图像比例的代码:

 

#include<GL/freeglut.h>
const double w0=8.0;
const double h0=6.0;

void myDisplay(void){
   glClear(GL_COLOR_BUFFER_BIT);
   glColor3f(1.0f,1.0f,1.0f);
   glRectf(1.0f, 1.0f, 3.0f, 3.0f);
   glColor3f(1.0f,0.0f,0.0f);
   glRectf(0.0f, 0.0f, 2.0f, 2.0f);
   glColor3f(0.0f,1.0f,0.0f);
   glRectf(2.0f, 2.0f, 4.0f, 4.0f);
   glColor3f(1.0f,0.0f,1.0f);
   glRectf(3.0f, 3.0f, 5.0f, 5.0f);
   glColor3f(1.0f,1.0f,0.0f);
   glRectf(4.0f, 4.0f, 6.0f, 6.0f);
   glColor3f(0.0f,0.0f,1.0f);
   glRectf(5.0f, 3.0f, 7.0f, 5.0f);
   glColor3f(0.0f,1.0f,1.0f);
   glRectf(6.0f, 2.0f, 8.0f, 4.0f);
   glColor3f(0.0f,1.0f,1.0f);
   glRectf(-1.0f, 1.0f, 0.5f, 3.0f);
  
   glFlush();
}

void reshape(int w, inth) {
   if(w==0)
       w=1;
   if(h==0)
       h=1;
    doublerate=(double)w/(double)h;
    if( w0 / h0) {
       glViewport((GLsizei)(((double)w)-((double)h)*w0/h0)/2,0,(GLsizei)(((double)h)*w0/h0), (GLsizei) h);
    }else{
       glViewport(0,(GLsizei)((double)h-((double)w)*h0/w0)/2,(GLsizei)w,(GLsizei)(((double)w)*h0/w0));
    }
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluOrtho2D(0, w0, 0, h0);
   glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char *argv[]){
   glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
   glutInitWindowPosition(0, 0);
   glutInitWindowSize(640, 360);
      
   glutCreateWindow("Size rate stable");
   glutReshapeFunc(reshape);
   glutDisplayFunc(&myDisplay);
  
   glutMainLoop();
    return0;
}


效果图如下:
OpenGL【1】视图类与鼠标坐标操作

无论如何变化窗口,始终都能显示正确的比例




0 0
原创粉丝点击