OpenGL Render Sphere without Glut:这个实现有啥问题?

Posted

技术标签:

【中文标题】OpenGL Render Sphere without Glut:这个实现有啥问题?【英文标题】:OpenGL Render Sphere Without Glut: What is wrong with this implementation?OpenGL Render Sphere without Glut:这个实现有什么问题? 【发布时间】:2012-08-15 05:03:17 【问题描述】:

在我的渲染循环中,我有以下逻辑。我有其他东西渲染到屏幕上,它们渲染,(我删除了该代码以直截了当)。这段代码不渲染球体,我不知道为什么不。我在数学中遗漏了什么吗?我已经使用了调试器,并且这些值似乎是正确的。注意 mBubbleDiameter 在此对象的构造函数中设置为 20。

static GLfloat staticDegreesToRadians(GLfloat tmpDegrees) 
    return tmpDegrees * ((std::atan(1.0f)*4)/180.0f);


void LedPannelWidget::updateGL() 
    glMatrixMode(GL_PROJECTION);
        glLoadIdentity();

        glViewport(0, 0, mWidth, mHeight);
        glOrtho(0, mWidth, 0, mHeight, -mBubbleDiameter, mBubbleDiameter);

    glMatrixMode(GL_MODELVIEW);
        glScissor(0, 0, mWidth, mHeight);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glClearColor(0.92f, 0.92f, 0.92f, 1.0);

        glLoadIdentity();
    const GLfloat tmpRadius = mDiameter/2.0f;
    const GLfloat tmpDelta = 5.00f;
    const GLfloat tmpDeltaRadians = staticDegreesToRadians(tmpDelta);

    for (int32_t tmpTheta = 180; tmpTheta > 0; tmpTheta -= tmpDelta) 
        for (int32_t tmpPhi = 0; tmpPhi < 360; tmpPhi += tmpDelta) 
            GLfloat tmpThetaRadians = staticDegreesToRadians(tmpTheta);
            GLfloat tmpPhiRadians = staticDegreesToRadians(tmpTheta);

            GLfloat tmpX1 = tmpRadius *
                std::sin(tmpThetaRadians) * 
                std::cos(tmpPhiRadians); 
            GLfloat tmpY1 = tmpRadius *
                std::sin(tmpThetaRadians) *
                std::cos(tmpPhiRadians);
            GLfloat tmpZ1 = tmpRadius *
                std::cos(tmpThetaRadians);

            GLfloat tmpX2 = tmpRadius *
                std::sin(tmpThetaRadians - tmpDeltaRadians) * 
                std::cos(tmpPhiRadians);
            GLfloat tmpY2 = tmpRadius *
                std::sin(tmpThetaRadians - tmpDeltaRadians) *
                std::cos(tmpPhiRadians); 
            GLfloat tmpZ2 = tmpRadius *
                std::cos(tmpThetaRadians - tmpDeltaRadians);

            GLfloat tmpX3 = tmpRadius * 
                std::sin(tmpThetaRadians - tmpDeltaRadians) *
                std::cos(tmpPhiRadians + tmpDeltaRadians);
            GLfloat tmpY3 = tmpRadius *
                std::sin(tmpThetaRadians - tmpDeltaRadians) *
                std::cos(tmpPhiRadians + tmpDeltaRadians);
            GLfloat tmpZ3 = tmpRadius *
                std::cos(tmpThetaRadians - tmpDeltaRadians);

            GLfloat tmpX4 = tmpRadius *  
                std::sin(tmpThetaRadians) *
                std::cos(tmpPhiRadians + tmpDeltaRadians);

            GLfloat tmpY4 = tmpRadius *
                std::sin(tmpThetaRadians) *
                std::cos(tmpPhiRadians + tmpDeltaRadians);

            GLfloat tmpZ4 = tmpRadius *
                std::cos(tmpThetaRadians);

            glBegin(GL_QUADS);
                glVertex3f(tmpX1, tmpY1, tmpZ1);
                glVertex3f(tmpX2, tmpY2, tmpZ2);
                glVertex3f(tmpX3, tmpY3, tmpZ3);
                glVertex3f(tmpX4, tmpY4, tmpZ4);
            glEnd();

            if (tmpGLError != GL_NO_ERROR) 
                QApplication::exit(0);
            
        
    
    swapBuffers();


工作 GL 算法:

const GLfloat r = mDiameter/2.0f;
const GLfloat phid = 20.00f;
const GLfloat thetad = 20.00f;
const GLfloat x = mCenterXCoord;
const GLfloat y = mCenterYCoord;

using namespace std;
for (int32_t phi = 180; phi > 0; phi -= phid) 
    int32_t theta = 0;
    GLfloat rphi = staticDegreesToRadians(phi);
    GLfloat rtheta = staticDegreesToRadians(theta);
    glBegin(GL_QUAD_STRIP);
    glColor3f(mCurrentColor.red()/255.0, mCurrentColor.green()/255.0,
        mCurrentColor.blue()/255.0);
    glVertex3f(
        (x + (r * sin(rphi) * cos(rtheta))),
        (y + (r * cos(rphi))),
        (0 + (r * sin(rphi) * cos(rtheta))));
    glVertex3f(
        (x + (r * sin(rphi + phid) * cos(rtheta))),
        (y + (r * cos(rphi + phid))),
        (0 + (r * sin(rphi + phid) * cos(rtheta))));

    for (; theta < 360; theta += thetad) 
        rtheta = staticDegreesToRadians(theta);
        glVertex3f(
            (x + (r * sin(rphi + phid) * cos(rtheta + thetad))),
            (y + (r * cos(rphi + phid))),
            (0 + (r * sin(rphi + phid) * cos(rtheta + thetad))));
        glVertex3f(
            (x + (r * sin(rphi) * cos(rtheta + thetad))),
            (y + (r * cos(rphi))),
            (0 + (r * sin(rphi) * cos(rtheta + thetad))));
    
    glEnd();

【问题讨论】:

您正在使用已弃用的方法,并且您正在使用 OpenGL 3.1 和更高版本中不可用的功能,这是一个类似的场景 gamedev.stackexchange.com/a/34109/18802 给您一个想法。 我写这篇文章的项目不允许 VBO、着色器或任何扩展。我正在将其写入基于 opengl 2.0 的环境。不过,您的评论表示赞赏。而且我无法使用 glut,也不允许我使用它。 你可以使用三角条来改进它(顶部和底部都有一个风扇)。 是的,我可以,但我想先让它工作。当我使用我的代码时,屏幕上什么也没有出现。但我认为数学没有任何问题。我已经手动完成了这一切,并交叉检查了我的计算。 【参考方案1】:

在这些行中检查您的代码

       GLfloat tmpThetaRadians = staticDegreesToRadians(tmpTheta);
        GLfloat tmpPhiRadians = staticDegreesToRadians(tmpTheta);

        GLfloat tmpX1 = tmpRadius *
            std::sin(tmpThetaRadians) * 
            std::cos(tmpPhiRadians); 
        GLfloat tmpY1 = tmpRadius *
            std::sin(tmpThetaRadians) *
            std::cos(tmpPhiRadians);
        GLfloat tmpZ1 = tmpRadius *
            std::cos(tmpThetaRadians);

你需要改变见下文

       GLfloat tmpThetaRadians = staticDegreesToRadians(tmpTheta);
       GLfloat tmpPhiRadians = staticDegreesToRadians(tmpPhi);
       GLfloat tmpX1 = tmpRadius *
            std::sin(tmpThetaRadians) * 
            std::sin(tmpPhiRadians); 
        GLfloat tmpY1 = tmpRadius *
            std::sin(tmpThetaRadians) *
            std::cos(tmpPhiRadians);
        GLfloat tmpZ1 = tmpRadius *
            std::cos(tmpThetaRadians);

【讨论】:

根据我的数学书,公式是:x=r \, \sin\theta \, \cos\varphi \quad y=r \, \sin\theta \, \sin \varphi \quad z=r \, \cos\theta \quad 你说的是 y=r \, \sin\theta \, \sin\varphi \quad 但在你的上方使用 y=r \, \sin\theta \, \cos\varphi \quad代码。我也像你正在做的那样渲染球体,你可以在这里看到codeincodeblock.blogspot.com/2011/06/…它工作正常。这个程序是在 c++ 和 OpenGL(GLUT) 中的 我们正在以非常相似的方式解决问题,但是即使在进行了您建议的更改之后,它也是不行的。如果我重新发布我的代码,你能再看一下吗? @MatthewHoggan 分享你的完整代码我会下载并尝试解决问题 看上面的代码,我最大的错误是忘记了z轴是指向屏幕外的,而y轴是向上的。

以上是关于OpenGL Render Sphere without Glut:这个实现有啥问题?的主要内容,如果未能解决你的问题,请参考以下文章

jpa 2.1 spring boot with web sphere 8.5.5.8(完整版) jdk 7

将地球纹理贴图应用到 Sphere

使用 openGL ES 2.0 结合其他线条绘制功能的字体渲染(Freetype)不起作用

Qt 使用openGL 渲染NV12格式的视频

✠OpenGL-6-3D模型

OpenGL ES - 如何在 Blender Cycles Render 中实现光泽着色器?