Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt 为什么用Opengl绘制球体并进行透视投影时球体会变形?_Qt_Opengl - Fatal编程技术网

Qt 为什么用Opengl绘制球体并进行透视投影时球体会变形?

Qt 为什么用Opengl绘制球体并进行透视投影时球体会变形?,qt,opengl,Qt,Opengl,当其他对象没有扭曲或拉伸时,在透视投影后,我的球体会扭曲 使用正交投影可以,但使用QMatrix4x4::perspective投影时会拉伸。我希望它能起作用,但这里很棘手。 绘制球体的代码如下所示: #include "ballshader.h" #include <iostream> void BallShader::initialize(float r) { m_program.addCacheableShaderFromSourceFile

当其他对象没有扭曲或拉伸时,在透视投影后,我的球体会扭曲

使用正交投影可以,但使用QMatrix4x4::perspective投影时会拉伸。我希望它能起作用,但这里很棘手。 绘制球体的代码如下所示:

    #include "ballshader.h"

#include <iostream>

void BallShader::initialize(float r)
{
  m_program.addCacheableShaderFromSourceFile(QOpenGLShader::Vertex, "vsrc.vsh");
   m_program.addCacheableShaderFromSourceFile(QOpenGLShader::Fragment, "fsrc.fsh");
if (m_program.link())
{
    std::cout << "link ok"<<std::endl;
}
//else
{
    std::cout << "link nok" << std::endl;
    
}

m_r = r;

/// p3    p2
///
/// p0    p1
///
int angleSpan = 10; //radian = angle * PI / 180
for (int vAngle = -90; vAngle <90; vAngle = vAngle + angleSpan) { //Generate spherical vertices
    for (int hAngle = 0; hAngle <= 360; hAngle = hAngle + angleSpan) {
        float x0 = r * ::cosf(vAngle * PI / 180.0) * ::cosf(hAngle * PI / 180.0);
        float y0 = r * ::cosf(vAngle * PI / 180.0) * ::sinf(hAngle * PI / 180.0);
        float z0 = r * ::sinf(vAngle * PI / 180.0);

        float x1 = r * ::cosf(vAngle * PI / 180.0) * ::cosf((hAngle + angleSpan) * PI / 180.0);
        float y1 = r * ::cosf(vAngle * PI / 180.0) * ::sinf((hAngle + angleSpan) * PI / 180.0);
        float z1 = r * ::sinf(vAngle * PI / 180.0);

        float x2 = r * ::cosf((vAngle + angleSpan) * PI / 180.0) * ::cosf((hAngle + angleSpan) * PI / 180.0);
        float y2 = r * ::cosf((vAngle + angleSpan) * PI / 180.0) * ::sinf((hAngle + angleSpan) * PI / 180.0);
        float z2 = r * ::sinf((vAngle + angleSpan) * PI / 180.0);

        float x3 = r * ::cosf((vAngle + angleSpan) * PI / 180.0) * ::cosf(hAngle * PI / 180.0);
        float y3 = r * ::cosf((vAngle + angleSpan) * PI / 180.0) * ::sinf(hAngle * PI / 180.0);
        float z3 = r * ::sinf((vAngle + angleSpan) * PI / 180.0);

        // p1 -> p3 -> p0
        // p1 -> p2 -> p3

        m_points
            << x1 << y1 << z1
            << x3 << y3 << z3
            << x0 << y0 << z0
            << x1 << y1 << z1
            << x2 << y2 << z2
            << x3 << y3 << z3;

            /*//normals
            << x1 / r << y1 / r << z1 / r
            << x3 / r << y3 / r << z3 / r
            << x0 / r << y0 / r << z0 / r
            << x1 / r << y1 / r << z1 / r
            << x2 / r << y2 / r << z2 / r
            << x3 / r << y3 / r << z3 / r;*/

    }
}
m_vbo.create();
m_vbo.bind();
m_vbo.allocate(m_points.constData(), m_points.count() * sizeof GLfloat);
m_vbo.release();
}

void BallShader::render(QOpenGLFunctions *f, QMatrix4x4 & projM, QMatrix4x4 & camera, QMatrix4x4 & model, const QVector3D &eye)
{

f->glClearColor(0.0, 0.0, 0.0, 1.0f);
f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
f->glEnable(GL_DEPTH_TEST);
f->glEnable(GL_CULL_FACE);
m_program.bind();
m_vbo.bind();
m_program.setUniformValue("uPMatrix", projM);
m_program.setUniformValue("camMatrix", camera);
m_program.setUniformValue("uMMatrix", model);
m_program.setUniformValue("uR", m_r);
m_program.setUniformValue("objectColor", 1, 0.3f, 0.3f);
m_program.setUniformValue("lightColor", 1, 1, 1);
m_program.setUniformValue("viewPos", eye);
m_program.setUniformValue("lightPos", eye);

m_program.enableAttributeArray(0);
m_program.setAttributeBuffer(0, GL_FLOAT, 0, 3, 3 * sizeof(GL_FLOAT));

f->glDrawArrays(GL_TRIANGLES, 0, m_points.count() / 3);

m_program.disableAttributeArray(0);
m_vbo.release();
m_program.release();
f->glDisable(GL_DEPTH_TEST);
f->glDisable(GL_CULL_FACE);
}
#包括“ballshader.h”
#包括
void BallShader::初始化(浮点r)
{
m_program.addCacheableShaderFromSourceFile(QOpenGLShader::Vertex,“vsrc.vsh”);
m_program.addCacheableShaderFromSourceFile(QOpenGLShader::Fragment,“fsrc.fsh”);
if(m_program.link())
{

这是透视失真。失真在视图的边缘处增加。在视图的中心绘制球体,并看到差异。是的。在中心绘制球体时看起来不错。但我想在边缘处循环球体。问题是什么?屏幕截图中没有任何错误。使用较小的字段f视角,增加相机和物体之间的距离,使效果不那么明显。如果你不希望任何透视失真,请使用正交投影。你实际上看到的是通过a看到的东西。我可以重复最后一句话:使用较小的视角,增加凸轮之间的距离“但是近平面的高度似乎比我预期的要大,这与几何结构是矛盾的,不是吗?”问题中给出的信息不足以得出任何结论。但是屏幕截图看起来比我从45度视场期望的角度要宽一些,我的第一个预感是你使用45度作为弧度。