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