皮皮网

【线程池的源码】【nzcms源码】【databasenet源码】glViewport函数源码_glviewport的功能

来源:江苏离贵州源码 时间:2024-12-24 08:26:42

1.opengl 中reshape函数怎么用
2.《图形编程技术学习》(十三)OpenGLStarter程序问题解答(二)
3.glViewport参数
4.glViewport功能
5.如何在mfc中进行opengl编程初始化环境
6.OpenGL之Viewport

glViewport函数源码_glviewport的函数功能

opengl 中reshape函数怎么用

       你说的应该是改变窗口形状,所绘制的源码物体不变形,而只是函数大小发生变化是吧?\x0d\void reshape (int w, int h)\x0d\{ \x0d\ glViewport (0, 0, (GLsizei) w, (GLsizei) h);\x0d\ glMatrixMode (GL_PROJECTION);\x0d\ glLoadIdentity ();\x0d\ if (w <= h)\x0d\ gluOrtho2D (0.0, .0, 0.0, .0 * (GLfloat) h/(GLfloat) w);\x0d\ else\x0d\ gluOrtho2D (0.0, .0 * (GLfloat) w/(GLfloat) h, 0.0, .0);\x0d\ glMatrixMode(GL_MODELVIEW);\x0d\}\x0d\看这个reshape函数当窗口发生变化,窗口的源码w(宽度)和h(高度)参数传给reshape函数,\x0d\ glViewport (0,函数 0, (GLsizei) w, (GLsizei) h);\x0d\把视口设置为铺满整个窗口, if (w <= h)\x0d\ gluOrtho2D (0.0,源码线程池的源码 .0, 0.0, .0 * (GLfloat) h/(GLfloat) w);\x0d\ else\x0d\ gluOrtho2D (0.0, .0 * (GLfloat) w/(GLfloat) h, 0.0, .0);\x0d\把投影得到的视景体按照视口变化的比例变化视景体的比例;简单地说,本来视景体宽高比是函数1:1,视口宽高比也是源码1:1,这时绘制了一个物体。函数然后因为窗口发生变化,源码视口也变化,函数假如变成了2:1;这时如果用1:1的源码视景体放到2:1的视口上肯定会变形,所以要把视景体变成2:1,函数这样,源码虽然物体看起来变大(或变小)了,函数但长宽比例不变,也就看起来不变形了。注意这个参数(GLfloat) w/(GLfloat) h。

《图形编程技术学习》(十三)OpenGLStarter程序问题解答(二)

       一、nzcms源码OpenGLStarter程序相关问题解析

       1. 通过免费glut进行OpenGL编程时,重点在于理解消息驱动和回调函数的概念。这有助于程序在特定事件发生时执行特定代码。

       2. 函数display()和myReshape()的调用时机取决于OpenGL的窗口状态。display()在窗口更新时调用,而myReshape()在窗口大小发生变化时被调用。

       3. 程序通过设置键盘事件的回调函数来实现对物体的旋转和平移控制。当特定键被按下或释放时,回调函数会根据预设规则更新物体的位置。

       4. glutIdleFunc()函数用于指定一个函数,在OpenGL上下文空闲时调用。这为实现动画效果提供了一个基础。

       5. display()函数中调用glTranslatef(0.0,0.0,-G_fDistance)是为了平移三维空间中的视点,使得场景从不同距离观察。

       6. 从程序中可以找到图形绘制的整个流程,即OpenGL的图形流水线,包括CPU和GPU的分工。

       7. gluPerspective()函数用于设置透视投影,databasenet源码定义了视角的垂直视野角度、宽高比、近裁剪面和远裁剪面。

       8. glViewport()函数用于设置视口,即确定在屏幕上显示的区域大小。

       二、详细解答

       5. 在display()函数中调用glTranslatef是为了调整视点位置,实现不同深度的场景观察,提高3D图形的视觉效果。

       6. OpenGL的图形流水线可以形象理解为一条流水线,包括顶点着色、几何着色、片段着色、深度测试、模板测试和混合等步骤,最终生成屏幕上的图像。

       7. gluPerspective()的使用确保了3D场景中物体的正确透视效果,使得远处的muemu源码物体看起来更小,符合人类视觉经验。

       8. glViewport()的设定有助于优化GPU的渲染过程,使屏幕显示更高效、更清晰。

       扩展阅读:理解右手坐标系和左手坐标系的原理及其在OpenGL编程中的应用。

       在OpenGL编程中,右手坐标系和左手坐标系的概念对理解3D空间的旋转和方向至关重要。右手坐标系中,拇指、食指和中指分别代表X、Y、Z轴的正方向,旋转方向遵循右手定则。左手坐标系中,坐标轴的指向与右手坐标系相反。

       OpenGL作为一个状态机,控制着绘制操作的整个流程。glRotatef()函数计算旋转矩阵,talPHP源码实现物体的旋转。此外,了解编译与链接的概念、OpenGL的跨平台特性、回调函数和消息映射等知识对于深入理解OpenGLStarter程序至关重要。

glViewport参数

       在进行图形绘制时,`glViewport`函数成为了一个关键的组件。其函数原型为:

       glViewport(GLint x, GLint y, GLsizei width, GLsizei height)

       通过`glViewport`函数,我们可以灵活地控制渲染区域的位置和大小。具体来说:

       其中,参数`x`和`y`分别以像素为单位,表示视口的左下角位置坐标。想象一下,你正在绘制一个巨大的画布,`x`和`y`就是你想要从画布的哪个角落开始绘制。比如,如果你想从屏幕左上角开始绘制,`x`和`y`都设置为0;若想从屏幕右下角开始绘制,可以将`x`设置为屏幕宽度减去所需宽度,`y`同样设置为屏幕高度减去所需高度。

       参数`width`和`height`则用来定义视口矩形的宽度和高度,决定了实际的绘制区域大小。与`x`和`y`类似,这同样可以根据窗口的实际尺寸实时调整。举个例子,如果你的窗口大小动态变化,通过`glViewport`函数可以相应地调整绘制区域的大小,确保在任何窗口尺寸下都能精确地绘制出你想要的内容。

       综上所述,`glViewport`函数的巧妙使用,使得在OpenGL等图形处理库中,能够灵活地控制渲染区域的位置和大小,适应不同的显示需求,从而实现更丰富、更灵活的图形界面。

glViewport功能

       在计算机图形学领域,OpenGL是一个广泛使用的图形渲染引擎。它提供了一系列强大的工具和函数,帮助开发者实现复杂的图形渲染任务。其中,glViewport功能就显得尤为重要。

       glViewport是OpenGL中的一个关键函数,用于调整视口的大小和位置。在默认情况下,视口被设定为占据打开窗口的整个像素矩形。然而,为了适应不同的应用需求,开发者往往需要选择一个更小的绘图区域。这时,glViewport就扮演了关键角色。

       通过使用glViewport函数,开发者可以定义一个像素矩形,作为最终图像映射的目标区域。这一功能允许在同一个窗口中显示分割屏幕的效果,进而展示多个视图。例如,在游戏开发中,开发者可能需要在同一个屏幕上同时显示玩家视角和环境信息,此时,glViewport就成为实现这一目标的强大工具。

       使用glViewport函数的过程相对简单,开发者只需要提供四个参数:x、y、width、height。其中,x和y分别表示视口左下角在窗口中的坐标,width和height则表示视口的宽度和高度。通过调整这些参数,开发者可以精确控制视口的大小和位置,从而实现更加灵活和精细的图像渲染。

       在实际应用中,glViewport的灵活性和高效性为开发者提供了极大的便利。它不仅简化了图像渲染的复杂性,还极大地增强了OpenGL的可定制性。无论是游戏开发、图形设计还是其他需要复杂图形处理的应用场景,glViewport都是不可或缺的工具。

       总之,glViewport功能是OpenGL中一个强大且灵活的工具,它帮助开发者在屏幕上定义和调整绘图区域,实现多样化的图形渲染效果。通过合理使用glViewport,开发者可以创造出更加丰富和吸引人的视觉体验,满足不同应用场景的需求。

如何在mfc中进行opengl编程初始化环境

       æ‚¨å¥½ï¼Œå¾ˆé«˜å…´ä¸ºæ‚¨è§£ç­”。

       1:新建一个MFC的工程,单文档的工程。

       2:工程建好之后,可以先编译运行一下。下面就是要把View的窗口初始化为OpenGL的编程环境。当然以下所有的操作都是在View类中进行的。

       å…ˆåœ¨Project->Settings->Link中,加上opengl.lib

       glu.lib glut.lib glaux.lib,然后在View.h的类定义中加上如下引用。

       #include <gl\gl.h>

       #include <gl\glu.h>   

       #include <gl\glaux.h>

       3:首先要让窗口支持OpenGL,那就必须要对PIXELFORMATDESCRIPTOR这个结构有所了解,先在View类中新建一个函数SetupPixFormat(CDC

       *pDC),类型:看下面的函数就知道为BOOL,(方法:在classview中,找到**view类,鼠标右击,添加函数)公有私有无所谓,如下:

BOOL 

       CTestGLInitialView::SetupPixFormat(CDC *pDC) 

       //我建立的工程名叫TestGLInitial{ static PIXELFORMATDESCRIPTOR pfd = 

       //定义像素格式{    sizeof(PIXELFORMATDESCRIPTOR), // 

       ä¸Šè¿°æ ¼å¼æè¿°ç¬¦çš„大小   1,         // 

       ç‰ˆæœ¬å·   PFD_DRAW_TO_WINDOW |    // 

       æ ¼å¼æ”¯æŒçª—口   PFD_SUPPORT_OPENGL |    // 

       æ ¼å¼å¿…须支持OpenGL   PFD_DOUBLEBUFFER,     // 

       å¿…须支持双缓冲   PFD_TYPE_RGBA,      // ç”³è¯· RGBA 

       æ ¼å¼   ,         // 

       ä½è‰²å½©æ·±åº¦ï¼Œå³1.千万的真彩色   0, 0, 0, 0, 0, 0,     // 

       å¿½ç•¥çš„色彩位   0,         // 

       æ— Alpha缓存   0,         // 

       å¿½ç•¥Shift Bit   0,         

       // æ— ç´¯åŠ ç¼“å­˜   0, 0, 0, 0,       // 

       å¿½ç•¥èšé›†ä½   ,         // ä½ 

       Z-缓存 (深度缓存)   0,         

       // æ— è’™æ¿ç¼“å­˜   0,         // 

       æ— è¾…助缓存   PFD_MAIN_PLANE,      // 

       ä¸»ç»˜å›¾å±‚   0,         // 

       Reserved   0, 0, 0        // 

       å¿½ç•¥å±‚遮罩};

       int nIndex = ChoosePixelFormat(pDC->GetSafeHdc(), &pfd); 

       //选择刚刚定义的像素格式if( nIndex == 0 ) return FALSE;return 

       SetPixelFormat(pDC->GetSafeHdc(), nIndex, &pfd);   

       //设置像素格式}

       è¿™ä¸ªå‡½æ•°çš„主要目的就是设置窗口的像素格式,使之支持OpenGL,明白这点就行了。在创建窗口的时候,调用这个函数。

       5:刚刚那个函数是用来在创建窗口是调用的,在创建窗口时,还需要对OpenGL的环境做一些初始化,再定义一个函数InitialGL(),(方法:在classview中,找到**view类,鼠标右击,添加函数)公有私有也无所谓,反正是自己调用的,如下:

BOOL 

       CTestGLInitialView::InitialGL()

       {

       glShadeModel(GL_SMOOTH);           

       // å¯ç”¨é˜´å½±å¹³æ»‘

       glClearColor(0.0f, 0.0f, 0.0f, 

       0.0f);       // 

       é»‘色背景

       glClearDepth(1.0f);                            

       // 

       è®¾ç½®æ·±åº¦ç¼“å­˜

       glEnable(GL_DEPTH_TEST);             

       // 

       å¯ç”¨æ·±åº¦æµ‹è¯•

       glDepthFunc(GL_LEQUAL);              

       // æ‰€ä½œæ·±åº¦æµ‹è¯•çš„类型

       glHint(GL_PERSPECTIVE_CORRECTION_HINT, 

       GL_NICEST);    // å‘Šè¯‰ç³»ç»Ÿå¯¹é€è§†è¿›è¡Œä¿®æ­£

       return 

       TRUE;                                      

       // åˆå§‹åŒ– OK

       }

       è¿™é‡Œçš„代码我都是抄的NeHe教程上面的代码。

       6:现在可以捕获WM_CREATE消息了(方法:view-->classvizard -->messages

       maps:classname

       é€‰**view,找到WM_CREATE,添加函数,编辑代码)。但是,还要先定义一个CClientDC*的成员,(方法:在classview中,找到**view类,鼠标右击,添加函数成员变量。类型:CClientDC*,名字:m_pDC)这个成员指向View窗口自己,是用来传递给SetupPixFormat(CDC

       *pDC)函数的,没别的意思。

       çŽ°åœ¨ï¼Œæ¥æ•èŽ·WM_CREATE消息(),写上如下代码:

int 

       CTestGLInitialView::OnCreate(LPCREATESTRUCT lpCreateStruct)

       {

       if 

       (CView::OnCreate(lpCreateStruct) == -1)

          return -1;

       // 

       TODO: Add your specialized creation code here

       m_pDC = new 

       CClientDC(this);

       SetupPixFormat(m_pDC);

       HGLRC hrc = 

       wglCreateContext(m_pDC->GetSafeHdc());

       wglMakeCurrent(m_pDC->GetSafeHdc(), 

       hrc);

       InitialGL();

       return 

       0;

       }

       å½“然,当窗口关闭的时候,还应该要释放一些资源。捕获WM_DESTROY消息,(方法:view-->classvizard

       -->messages maps:classname 选**view,找到WM_DESTROY,添加函数,编辑代码)写下如下代码:

void 

       CTestGLInitialView::OnDestroy()

       {

       CView::OnDestroy();

       // TODO: Add 

       your message handler code here

       HGLRC hrc = 

       wglGetCurrentContext();

       wglMakeCurrent(NULL, 

       0);

       wglDeleteContext(hrc);

       delete 

       m_pDC;

       }

       çŽ°åœ¨å¯ä»¥ç¼–译一下了,没有错误。

       7:现在,OpenGL的环境已经初始化差不多了。可以开始做图了,先定义一个作图的函数DrawScene(),写上如下的代码:

BOOL 

       CTestGLInitialView::DrawScene()

       {

       glClear(GL_COLOR_BUFFER_BIT | 

       GL_DEPTH_BUFFER_BIT);    // 

       æ¸…除屏幕和深度缓存

       glLoadIdentity();            

       // 

       é‡ç½®å½“前的模型观察矩阵

       SwapBuffers(m_pDC->GetSafeHdc());        

       // äº¤æ¢ç¼“冲区

       return TRUE;

       }

       ç„¶åŽï¼Œè¦åœ¨OnDraw中,调用这个函数:

void 

       CTestGLInitialView::OnDraw(CDC* pDC)

       {

       CTestGLInitialDoc* pDoc = 

       GetDocument();

       ASSERT_VALID(pDoc);

       // TODO: add draw code for native data 

       here

       DrawScene();

       }

       8:运行一下,黑色的背景出来了。

       9:这时,可以修改DrawScene()这个作图函数,作图。画出NeHe第3课的那个三角形和正方形来。写代码如下:

BOOL 

       CTestGLInitialView::DrawScene(){ glClear(GL_COLOR_BUFFER_BIT | 

       GL_DEPTH_BUFFER_BIT);    // 

       æ¸…除屏幕和深度缓存glLoadIdentity();            

       // é‡ç½®å½“前的模型观察矩阵

       glTranslatef(-1.5f,0.0f,-6.0f);       // å·¦ç§» 

       1.5 å•ä½ï¼Œå¹¶ç§»å…¥å±å¹• 

       6.0glBegin(GL_TRIANGLES);         // 

       ç»˜åˆ¶ä¸‰è§’å½¢glColor3f(1.0f, 0.0f, 0.0f);glVertex3f( 0.0f, 1.0f, 

       0.0f);       // ä¸Šé¡¶ç‚¹glColor3f(0.0f, 1.0f, 

       0.0f);glVertex3f(-1.0f,-1.0f, 0.0f);       // 

       å·¦ä¸‹glColor3f(0.0f, 0.0f, 1.0f);glVertex3f( 1.0f,-1.0f, 

       0.0f);       // 

       å³ä¸‹glEnd();            

       // 

       ä¸‰è§’形绘制结束glTranslatef(3.0f,0.0f,0.0f);       

       // å³ç§»3单位glColor3f(0.0f, 0.0f, 

       1.0f);glBegin(GL_QUADS);          

       // ç»˜åˆ¶æ­£æ–¹å½¢glVertex3f(-1.0f, 1.0f, 0.0f);       

       // å·¦ä¸ŠglVertex3f( 1.0f, 1.0f, 0.0f);       // 

       å³ä¸ŠglVertex3f( 1.0f,-1.0f, 0.0f);       // 

       å·¦ä¸‹glVertex3f(-1.0f,-1.0f, 0.0f);       // 

       å³ä¸‹   

       glEnd();SwapBuffers(m_pDC->GetSafeHdc());        

       // äº¤æ¢ç¼“冲区return TRUE;}

          

       è¿è¡Œä¸€ä¸‹ï¼Œå‘现图形没有出现,这个怎么回事呢。原来是因为还没有定义投影方式和视口。即用正交投影还是透视投影。定义投影,还要捕获WM_SIZE消息。写如下代码:

void 

       CTestGLInitialView::OnSize(UINT nType, int cx, int 

       cy)

       {

       CView::OnSize(nType, cx, cy);

       // TODO: Add your message 

       handler code here

       if (0 == 

       cy)         // 

       é˜²æ­¢è¢«é›¶é™¤

       {

          cy = 

       1;          // 

       å°†Height设为1

       }

       glViewport(0, 0, cx, cy);      

       // é‡ç½®å½“前的视口

       glMatrixMode(GL_PROJECTION);     // 

       é€‰æ‹©æŠ•å½±çŸ©é˜µ

       glLoadIdentity();        // 

       é‡ç½®æŠ•å½±çŸ©é˜µ

       // 

       è®¾ç½®è§†å£çš„大小

       gluPerspective(.0f,(GLfloat)cx/(GLfloat)cy,0.1f,.0f);

       glMatrixMode(GL_MODELVIEW);      

       // é€‰æ‹©æ¨¡åž‹è§‚察矩阵

          

       glLoadIdentity();        // 

       é‡ç½®æ¨¡åž‹è§‚察矩阵

       }

          

       å†è¿è¡Œä¸€ä¸‹ï¼Œå›¾å½¢å·²ç»å‡ºæ¥äº†ã€‚以后,就可以在DrawScene()写任何画图的代码了,当窗口重绘的时候,都可以自动适应。如果要做一段可以运动的3D图画,可以再捕获WM_TIMER消息,通过在OnCreate的时候定义一个时钟,再配合一些变量,就可以做简单的动画了

       å¦‚若满意,请点击右侧【采纳答案】,如若还有问题,请点击【追问】

       å¸Œæœ›æˆ‘的回答对您有所帮助,望采纳!

                                                                                                                                    ~ O(∩_∩)O~

OpenGL之Viewport

        1.1 窗口(Screen)

        窗口其实就是屏幕,如下图1中红色圈中黑色背景的部分。所有的场景最终都是要被光栅化乘显示器上的图像,屏幕是所有场景(2D、3D等)的最终输出目的地。一个screen可以显示多个视口中的内容;

        1.2 视口(Viewport)

        视口就是窗口中用来显示图形的一块矩形区域,它可以和窗口等大,也可以比窗口大或者小,如图1中蓝色标示的绿色背景的区域。它具有两个意义:

          • 定义了视镜体中的景物要被绘制到一张什么尺寸的画布之上;

          • 定义了画布在屏幕的什么区域;

        显然,如果 视景体的投影平面 定义的宽高比和 视口 所定义的宽高比 不相同 的话,那么将视景体中的物体绘制到画布上的时候会进行 拉伸或者压缩 ;而当视景体投影平面的宽高比和视口所定义的宽高比一致的时候,图像将会不进行任何缩放绘制到视口所定义的画布之上。

        在实际应用中,一个窗口中会绘制多个3D场景,这个通过定义多个视口,绘制多个图像,然后贴在屏幕的不同区域即可。比如图中黄色笔圈中的区域,在画布中定于两个不同的viewport1 (0,0;w/2,y)和 viewport2 (0,w/2;w/2,y);

        1.4 视镜体(View Frustum)

        视景体(View Volume)定义了我们能够通过虚拟的3D摄像机所能看到的场景。在一个3D场景中站立中,需要摄像机的摆放位置和视野来定义我们所能够看到的东西,而这个视野就是通过视景体来定义的。在3D中,一般可以通过以下两种方式来定义视景体:

        通过前面的介绍,我们大致的了解了这三个不同东西的概念。从中我们可以知道,通过定义投影矩阵,我们实际上是在虚拟的3D空间中,创建了一个视野,也就是视景体。在接着,我们通过定义视口,来描述视景体中的内容如何映射到一个虚拟的画布之上,并且这个画布最终将显示在屏幕上的什么位置。当所有的这些都设置完毕,我们绘制完毕场景之后,就能够通过硬件在我们的显示器屏幕上看到最终的画面。更理论的表述就是,通过定义投影矩阵,将3D场景投影到一个投影平面之上。通过定义视口,我们将投影平面上的内容映射到这个视口中去,并且填满它,同时根据定义视口是给定的屏幕坐标的位置,将这个视口中的图像映射到窗口的指定位置之上,最终我们就看到了图像。

        glViewport是OpenGL中的一个函数。计算机图形学中,在屏幕上打开窗口的任务是由窗口系统,而不是OpenGL负责的。glViewport在默认情况下,视口被设置为占据打开窗口的整个像素矩形,如图1,窗口大小和设置视口大小相同,所以为了选择一个更小的绘图区域,就可以用glViewport函数来实现这一变换,在窗口中定义一个像素矩形,最终将图像映射到这个矩形中。例如可以对窗口区域进行划分,在同一个窗口中显示分割屏幕的效果,以显示多个视图。

OpenGL中的reshape函数如何处理窗口形状改变事件?

       在OpenGL和GLUT的世界中,你是否对reshape函数有所困惑?当窗口尺寸发生变化时,GLUT中的glutReshapeFunc(reshape)正是那个关键的幕后英雄,它负责响应窗口形状调整的事件,引导我们调整图形的显示。

       “reshape”这个词,其实是在说窗口调整时的图形处理策略。它给予开发者灵活的空间,可以根据实际需求定制反应。例如,你可能选择图形的长宽比例跟随窗口尺寸动态变化,实现精细的缩放效果。

       比如,你可以编写这样的函数来实现这一目标:

void reshape(int cur_w, int cur_h) {

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        if (cur_h <= 0) {

        cur_h = ; // 防止窗口过小时的处理

        }

        glViewport(0, 0, cur_w, cur_h);

        float xfactor = (float) glutGet(GLUT_WINDOW_WIDTH) / (float) img_width; // 按窗口宽度缩放

        float yfactor = (float) glutGet(GLUT_WINDOW_HEIGHT) / (float) img_height; // 按窗口高度缩放

        glutPostRedisplay(); // 通知系统进行图形的更新

}

       通过这样的reshape函数,你可以确保图形始终适应窗口变化,保持视觉一致性。希望这个简要的解释能帮助你理解并应用到实际项目中。

       至此,关于reshape函数的分享就到这里,期待它能为你的OpenGL编程旅程增添一抹亮色。

glViewPort

       glViewPort中字母P要小写 -- glViewport(...)

       å‡½æ•°åŽŸåž‹æ˜¯

       void glViewport(GLint x,

        GLint y,

        GLsizei width,

        GLsizei height)

       å®ƒæ˜¯OpenGL库里的东西,别忘了 #include 有关的OpenGL的头文件.