为啥 GLfloat 需要全局范围?

Posted

技术标签:

【中文标题】为啥 GLfloat 需要全局范围?【英文标题】:Why does GLfloat require global scope?为什么 GLfloat 需要全局范围? 【发布时间】:2011-03-10 07:31:01 【问题描述】:

当声明为局部变量时,不会发生旋转 GLfloat 对象。当它被声明为全局时,它会相应地旋转,它需要全局的原因是什么? OpenGL程序的display()函数是否调用了别的东西?

【问题讨论】:

A GLfloat 是一个数字。 “旋转”它是什么意思?从 9 变为 6 ;-)? 【参考方案1】:

我在想的是,您可能正在尝试做这样的事情(函数中的 rot 不是全局的):

GLfloat rot = 0.1;
glRotatef(rot, 0.0f, 1.0f, 0.0f);

它不会旋转之后绘制的对象。

这是因为glRotatef 使用绝对旋转。您将 0.1 的恒定旋转应用于您绘制的每个图像,因此它们不会移动。

您不必全局存储rot,您可以将其与您旋转的对象的模型一起存储并像这样:

glRotatef(myObj->rotation, 0.0f, 1.0f, 0.0f);
... draw myObj->triangles ...
myObj->rotation += speed;   // speed can be e.g. 0.1

请注意:请记住,如果您在渲染功能中执行myObj->rotation += speed;,您的旋转速度将与您的渲染速度成正比(在更快的计算机上更快),这通常是不希望的。为避免这种情况,您可以检查经过的时间,并且仅在该时间超过 50 毫秒时才对其进行评估。

【讨论】:

这是一个很好的答案,但是如何创建对象的模型?我只是使用 glVertex3f() 和 glVertex2f() 之类的简单函数。 谢谢。必须发布代码才能回答这个问题,所以我会创建一个新的Answer 可能是一个带有顶点数组、比例、旋转等的结构体? @nkint 完全正确。我在更长的第二个答案中写了这个。【参考方案2】:

回应您的评论

但是如何创建对象的模型?我只是使用 glVertex3f() 之类的简单函数

您可以通过多种方式将模型与渲染(调用 glVertex、glColor...)分开,而不是对 glVertex、glColor... 进行硬编码。先说通俗易懂(但效率低下)的版本:三角形链表:

#define triangleList struct _triangleList
struct _triangleList 
    float ax, ay, az, bx, by, bz, cx, cy, cz;
    triangleList* next; // this has to be a null-pointer if this is the last link

以及使用它们的模型结构:

#define model struct _model
struct _model 
    float rotationX;
    triangleList* firstTriangle;

然后你可以制作一个通用的 renderFunction:

void myRenderFunc(model* aModel) 
    triangleList* current = aModel->firstTriangle;
    glBegin(GL_TRIANGLES);
    glRotate(aModel->rotationX,1.0,0.0,0.0);
    while(current!=0) 
        glVertex3f(current->ax,current->ay,current->az);
        ...
        current = current -> next;
    
    glEnd();

现在您有了一个通用(但速度较慢)的渲染函数:要渲染新模型,您不必编写 glBegins/glVertex/glColor...,只需创建一个新模型并将其提供给 renderFunc(您必须将其扩展为支持颜色...)。现在快速提及如何更快地做到这一点(如果需要的话):而不是调用 glVertex... 阅读有关顶点数组甚至顶点缓冲区对象的信息。但是,将模型与渲染功能分开的一般想法也适用于这些。

【讨论】:

一个链表?!非常非常奇怪的想法......但是,它确实有效。 @malfy:1)您通常不仅仅将rotationX存储在“模型”类中,而是存储完整的变换矩阵或[位置+旋转],具体取决于您的应用程序。 2) 在 glEnd() 之后调用 glLoadIdentity() 或 glRotate 将被考虑两次 用于下一个模型。 3) 当你对这些东西感到更舒服时,考虑使用 VBO。 @Calvin:OP 对这个东西很陌生,链表这样他就不必处理更快但更难理解的东西(交错......),1)是的,我希望他将他的模型扩展为最终包含位置和旋转(当然作为 trafo 矩阵)2)我通常在我的渲染函数之前调用 push+loadIdentity 3)是的,也提到了 VBO,但中间的步骤是 v-arrays。谢谢您的意见。

以上是关于为啥 GLfloat 需要全局范围?的主要内容,如果未能解决你的问题,请参考以下文章

Opengl - GLfloat未被识别

如何将 glm::vec4<float> 转换为 GLfloat*?

为啥我必须除以 Z?

有人能解释一下这段代码中的法线是如何计算的吗?

OpenGL第十三节:矩阵变换

使用 glDrawArrays 绘制多个模型