首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OpenGL在画三角形之前我要做什么?

OpenGL在画三角形之前我要做什么?
EN

Stack Overflow用户
提问于 2012-08-05 06:58:45
回答 2查看 2K关注 0票数 0

我发现的大多数教程、指南和书籍都与OpenGL相关,解释了如何绘制三角形和初始化OpenGL。这很好。但是当他们试图解释的时候,他们只是列出了一些函数和参数,比如:

代码语言:javascript
复制
glClear()
glClearColor()
glBegin()
glEnd()
...

因为我不是很擅长记忆学东西,所以我总是需要一个答案:“我们为什么要这样做?”所以我会写一些函数,因为我记得我必须在做其他事情之前设置一个特定的东西,而不是因为教程告诉我的。

请有人向我解释一下,在开始用OpenGL和glEnd()绘制一些东西之前,我必须向OpenGL定义什么(只有纯OpenGL,我使用SFML作为后台库,但这并不重要)。

样本答案:

您必须首先告诉OpenGL它需要用什么颜色来清除屏幕。因为在我们开始绘制当前的帧之前,每个帧都需要被清除.

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-08-05 09:24:55

首先,您应该知道,OpenGL是一个状态机。这意味着,除了创建OpenGL上下文(这是由SFML完成的)之外,不存在初始化之类的事情!

因为我不是很擅长记忆学东西,

这是很好的…

我总是需要一个答案,“我们为什么要这么做?”

这太棒了!

请有人向我解释一下,在开始用OpenGL ()和glEnd()绘制一些东西之前,我必须向OpenGL(只有纯OpenGL,我正在使用SFML作为后台库,但这并不重要)定义什么?

正如我已经告诉过的: OpenGL是一个状态机。这基本上意味着,您可以执行两种类型的调用:设置状态和执行操作。

例如,glClearColor设置一个状态变量,即clear颜色的状态变量,该值用于在设置了GL_COLOR_BUFFER_BIT标志的对glClear的调用时将活动的框架缓冲区颜色清除到。深度值存在类似的函数glClearDepth (GL_DEPTH_BUFFER_BIT标志为glClear)。

glBeginglEnd属于OpenGL的即时模式,已被废弃。所以没有什么理由去学习它们。您应该使用顶点数组,最好是通过顶点缓冲区对象。

但是这里是这样的:glBegin将OpenGL设置为它现在应该绘制的几何图形的状态,这是作为参数选择给glBegin的原语的类型。例如,GL_TRIANGLES意味着,OpenGL现在将每3个对glVertex的调用解释为形成一个三角形。glEnd告诉OpenGL,您已经完成了这批三角形。在glBegin…中不允许glEnd阻止某些状态更改。在这些与几何变换和生成图片有关的东西中,包括矩阵、着色器、纹理等等。

一个常见的误解是,OpenGL是初始化的。这是由于编写不当的教程,其中有一个initGL函数或类似的。当开始呈现场景时,从零开始设置所有状态是一种很好的做法。但是,由于单个帧可能包含几个场景(比如HUD或拆分屏幕游戏),所以一个场景会发生几次。

更新:

那你怎么画三角呢?嗯,这很简单。首先,你需要几何数据。例如:

代码语言:javascript
复制
GLfloat triangle[] = {
    -1, 0, 0,
    +1, 0, 0,
     0, 1, 0
};

在呈现函数中,我们告诉OpenGL,下一个对glDrawArrays或glDrawElements的调用将从那里获取数据(为了简单起见,这里我将使用OpenGL-2函数):

代码语言:javascript
复制
glVertexPointer(3, /* there are three scalars per vertex element */
                GL_FLOAT, /* element scalars are float */
                0, /* elements are tightly packed (could as well be sizeof(GLfloat)*3 */
                trignale /* and there you find the data */ );
/* Note that glVertexPointer does not make a copy of the data! 
   If using a VBO the data is copied when calling glBufferData. */

/* this switches OpenGL into a state that it will
   actually access data at the place we pointed it
   to with glVertexPointer */
glEnableClientState(GL_VERTEX_ARRAY);

/* glDrawArrays takes data from the supplied arrays and draws them
   as if they were submitted sequentially in a for loop to immediate
   mode functions. Has some valid applications. Better use index
   based drawing for models with a lot of shared vertices. */
glDrawArrays(Gl_TRIANGLE, /* draw triangles */
             0, /* start at index 0 */
             3, /* process 3 elements (of 3 scalars each) */ );

我还没有包括的是设置转换和视口映射。

视图定义了如何将容易投影和标准化的几何图形放置在窗口中。此状态是使用glViewport(pos_left, pos_bottom, width, height)设置的。

今天的转换发生在顶点着色器中,本质上,顶点着色器是用一种特殊语言(GLSL)编写的一个小程序,它接受顶点属性并计算结果顶点的剪辑空间位置。通常的方法是模拟固定功能流水线,这是一个两阶段的过程:首先将几何转换成视图空间(一些计算,比如在这个空间中的光照比较容易),然后将其投影到剪辑空间,这是渲染器的镜头。在固定函数管道中有两个转换矩阵:模型视图和投影。您可以将它们设置为期望结果所需的任何东西。在三角形的情况下,我们保留模型视图的恒等式,并在任一维中使用从-1到1的正交投影。

代码语言:javascript
复制
glMatrixMode(GL_PROJECTION);
/* the following function multiplies onto what's already on the stack,
   so reset it to identity */
glLoadIdentity(); 

/* our clip volume is defined by 6 orthogonal planes with normals X,Y,Z
   and ditance 1 from origin into each direction */
glOrtho(-1, 1, -1, 1, -1, 1); 

glMatrixMode(GL_MODELVIEW);
/* now a identity matrix is loaded onto the modelview */
glLoadIdentity();

在设置了转换之后,我们现在可以画出如上所述的三角形:

代码语言:javascript
复制
draw_triangle();

最后,我们需要告诉OpenGL,我们已经完成了发送命令,它应该完成它的渲染。

代码语言:javascript
复制
if(singlebuffered)
    glFinish();

然而,大多数情况下,您的窗口是双缓冲的,所以您需要交换它,以使事情变得生动。由于交换没有完成就没有意义,所以交换意味着完成。

代码语言:javascript
复制
else
    SwapBuffers();
票数 9
EN

Stack Overflow用户

发布于 2015-07-03 00:58:35

您正在使用API设置和更改OpenGL状态机。

实际上,您并不是直接对GPU进行编程,而是在应用程序和GPU之间使用一种媒介来做任何您想做的事情。

它之所以是这样的,不像CPU和内存那样工作,是因为openGL的目的是在操作系统/系统无关的硬件上运行,这样您的代码就可以在任何操作系统上运行,在任何硬件上运行,而不仅仅是在编程的硬件上运行。

因此,因此,您需要学习使用他们的预置代码,以确保您要做的任何操作都能够在合理的范围内在所有系统/OS/硬件上运行。

例如,如果您要使用特定的图形卡(比如amd)在windows 8.1上创建应用程序,那么您仍然希望您的应用程序能够在Andoird/iOS/Linux/其他Windows系统/其他硬件(Gpus)(如Nvidia )上运行。

因此,为什么Khronos在创建API时,将其作为独立于系统/硬件的API,这样它就可以在任何东西上运行,并成为每个人的标准。

这是我们必须付出的代价,我们必须学习他们的API,而不是学习如何直接写入gpu内存和直接利用GPU处理信息/数据。

尽管随着Vulkan的引入,当它发布时(也来自khronos),事情可能会有所不同,我们将了解它将如何工作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11814547

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档