Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.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
C++ OpenGL奇异立方体旋转_C++_Opengl_3d_Rendering - Fatal编程技术网

C++ OpenGL奇异立方体旋转

C++ OpenGL奇异立方体旋转,c++,opengl,3d,rendering,C++,Opengl,3d,Rendering,我正在自学现代OpenGL。我目前在渲染3D立方体时遇到了一个问题 首先,我创建了一个精灵,它是我的类,包含单个矩形精灵的位置、宽度、高度和纹理。然后,我将其传递给渲染器类,以创建一个立方体,该立方体的每一面墙都由相同的精灵组成 void Renderer::constructWall(maths::vec3 bottomLeft, maths::vec3 topLeft, maths::vec3 topRight, maths::vec3 bottomRight, maths:

我正在自学现代OpenGL。我目前在渲染3D立方体时遇到了一个问题

首先,我创建了一个精灵,它是我的类,包含单个矩形精灵的位置、宽度、高度和纹理。然后,我将其传递给渲染器类,以创建一个立方体,该立方体的每一面墙都由相同的精灵组成

        void Renderer::constructWall(maths::vec3 bottomLeft, maths::vec3 topLeft, maths::vec3 topRight, maths::vec3 bottomRight, maths::vec4 color){
        m_Buffer->position = bottomLeft;
        m_Buffer->color = maths::vec4(color.x, color.y, color.z, 1.0f);
        m_Buffer->tex = maths::vec2(0.0f, 0.0f);
        m_Buffer++;

        m_Buffer->position = topLeft;
        m_Buffer->color = maths::vec4(color.x, color.y, color.z, 1.0f);
        m_Buffer->tex = maths::vec2(0.0f, 1.0f);
        m_Buffer++;

        m_Buffer->position = topRight;
        m_Buffer->color = maths::vec4(color.x, color.y, color.z, 1.0f);
        m_Buffer->tex = maths::vec2(1.0f, 1.0f);
        m_Buffer++;

        m_Buffer->position = bottomRight;
        m_Buffer->color = maths::vec4(color.x, color.y, color.z, 1.0f);
        m_Buffer->tex = maths::vec2(1.0f, 0.0f);
        m_Buffer++;

        m_IndexCount += 6;
    }
m_Buffer是VertexData类型的指针,它是一个结构:

        struct VertexData{
        maths::vec3 position;
        maths::vec4 color;
        maths::vec2 tex;
    };
m_IndexCount是一个简单的计数器,用于指示在渲染器类中提交刷新时需要渲染多少索引。 我通过对立方体的顶点建模来创建立方体,并通过以下方式使用constructWall函数:

        maths::vec3 A(vertex.x, vertex.y, -depth/2);
        maths::vec3 B(vertex.x, vertex.y + size.y, -depth / 2);
        maths::vec3 C(vertex.x + size.x, vertex.y + size.y, -depth / 2);
        maths::vec3 D(vertex.x + size.x, vertex.y, -depth / 2);
        maths::vec3 E(vertex.x, vertex.y, depth/2);
        maths::vec3 F(vertex.x, vertex.y + size.y, depth/2);
        maths::vec3 G(vertex.x + size.x, vertex.y + size.y, depth/2);
        maths::vec3 H(vertex.x + size.x, vertex.y, depth/2);
        constructWall(A, B, C, D, color1);
        constructWall(E, F, G, H, color1);
        constructWall(A, B,F,E, color1);
        constructWall(D, C, G, H, color1);
        constructWall(A, E, H, D, color1);
        constructWall(B, F, G, C, color1);
当我创建一个立方体时,它可以完美地工作,在一个轴上旋转它也可以工作,但是当我尝试在多个轴上旋转它时,我的立方体有时表现得很奇怪:

资料来源:

还有我的矩阵代码:

        mat4::mat4()
    {
        for (int i = 0; i < 4 * 4; i++)
            elements[i] = 0.0f;
    }

    mat4::mat4(float diagonal)
    {
        for (int i = 0; i < 4 * 4; i++)
            elements[i] = 0.0f;

        elements[0 + 0 * 4] = diagonal;
        elements[1 + 1 * 4] = diagonal;
        elements[2 + 2 * 4] = diagonal;
        elements[3 + 3 * 4] = diagonal;
    }

    mat4 mat4::identity()
    {
        return mat4(1.0f);
    }

    mat4& mat4::multiply(const mat4& other)
    {
        float data[16];
        for (int y = 0; y < 4; y++)
        {
            for (int x = 0; x < 4; x++)
            {
                float sum = 0.0f;
                for (int e = 0; e < 4; e++)
                {
                    sum += elements[x + e * 4] * other.elements[e + y * 4];
                }
                data[x + y * 4] = sum;
            }
        }
        memcpy(elements, data, 4 * 4 * sizeof(float));

        return *this;
    }

    vec3 mat4::multiply(const vec3& other) const
    {
        return vec3(
            columns[0].x * other.x + columns[1].x * other.y + columns[2].x * other.z + columns[3].x,
            columns[0].y * other.x + columns[1].y * other.y + columns[2].y * other.z + columns[3].y,
            columns[0].z * other.x + columns[1].z * other.y + columns[2].z * other.z + columns[3].z
            );
    }

    vec4 mat4::multiply(const vec4& other) const
    {
        return vec4(
            columns[0].x * other.x + columns[1].x * other.y + columns[2].x * other.z + columns[3].x * other.w,
            columns[0].y * other.x + columns[1].y * other.y + columns[2].y * other.z + columns[3].y * other.w,
            columns[0].z * other.x + columns[1].z * other.y + columns[2].z * other.z + columns[3].z * other.w,
            columns[0].w * other.x + columns[1].w * other.y + columns[2].w * other.z + columns[3].w * other.w
            );
    }

    mat4 operator*(mat4 left, const mat4& right)
    {
        return left.multiply(right);
    }

    mat4& mat4::operator*=(const mat4& other)
    {
        return multiply(other);
    }

    vec3 operator*(const mat4& left, const vec3& right)
    {
        return left.multiply(right);
    }

    vec4 operator*(const mat4& left, const vec4& right)
    {
        return left.multiply(right);
    }

    mat4 mat4::orthographic(float left, float right, float bottom, float top, float near, float far)
    {
        mat4 result(1.0f);

        result.elements[0 + 0 * 4] = 2.0f / (right - left);

        result.elements[1 + 1 * 4] = 2.0f / (top - bottom);

        result.elements[2 + 2 * 4] = 2.0f / (near - far);

        result.elements[0 + 3 * 4] = (left + right) / (left - right);
        result.elements[1 + 3 * 4] = (bottom + top) / (bottom - top);
        result.elements[2 + 3 * 4] = (far + near) / (far - near);

        return result;
    }

    mat4 mat4::perspective(float fov, float aspectRatio, float near, float far)
    {
        mat4 result(1.0f);

        float q = 1.0f / tan(toRadians(0.5f * fov));
        float a = q / aspectRatio;

        float b = (near + far) / (near - far);
        float c = (2.0f * near * far) / (near - far);

        result.elements[0 + 0 * 4] = a;
        result.elements[1 + 1 * 4] = q;
        result.elements[2 + 2 * 4] = b;
        result.elements[3 + 2 * 4] = -1.0f;
        result.elements[2 + 3 * 4] = c;

        return result;
    }

    mat4 mat4::translation(const vec3& translation)
    {
        mat4 result(1.0f);

        result.elements[0 + 3 * 4] = translation.x;
        result.elements[1 + 3 * 4] = translation.y;
        result.elements[2 + 3 * 4] = translation.z;

        return result;
    }

    mat4 mat4::rotation(float angle, const vec3& axis)
    {
        mat4 result(1.0f);

        float r = toRadians(angle);
        float c = cos(r);
        float s = sin(r);
        float omc = 1.0f - c;

        float x = axis.x;
        float y = axis.y;
        float z = axis.z;

        result.elements[0 + 0 * 4] = x * omc + c;
        result.elements[1 + 0 * 4] = y * x * omc + z * s;
        result.elements[2 + 0 * 4] = x * z * omc - y * s;

        result.elements[0 + 1 * 4] = x * y * omc - z * s;
        result.elements[1 + 1 * 4] = y * omc + c;
        result.elements[2 + 1 * 4] = y * z * omc + x * s;

        result.elements[0 + 2 * 4] = x * z * omc + y * s;
        result.elements[1 + 2 * 4] = y * z * omc - x * s;
        result.elements[2 + 2 * 4] = z * omc + c;

        return result;
    }

    mat4 mat4::scale(const vec3& scale)
    {
        mat4 result(1.0f);

        result.elements[0 + 0 * 4] = scale.x;
        result.elements[1 + 1 * 4] = scale.y;
        result.elements[2 + 2 * 4] = scale.z;

        return result;
    }
mat4::mat4()
{
对于(int i=0;i<4*4;i++)
元素[i]=0.0f;
}
mat4::mat4(浮动对角线)
{
对于(int i=0;i<4*4;i++)
元素[i]=0.0f;
元素[0+0*4]=对角线;
元素[1+1*4]=对角线;
元素[2+2*4]=对角线;
元素[3+3*4]=对角线;
}
mat4 mat4::identity()
{
返回mat4(1.0f);
}
mat4和mat4::乘法(常数mat4和其他)
{
浮动数据[16];
对于(int y=0;y<4;y++)
{
对于(int x=0;x<4;x++)
{
浮动总和=0.0f;
对于(int e=0;e<4;e++)
{
总和+=元素[x+e*4]*其他元素[e+y*4];
}
数据[x+y*4]=总和;
}
}
memcpy(元素、数据、4*4*sizeof(float));
归还*这个;
}
vec3 mat4::乘法(常量vec3和其他)常量
{
返回向量3(
列[0]。x*其他.x+列[1]。x*其他.y+列[2]。x*其他.z+列[3]。x,
列[0]。y*其他.x+列[1]。y*其他.y+列[2]。y*其他.z+列[3]。y,
列[0]。z*其他.x+列[1]。z*其他.y+列[2]。z*其他.z+列[3]。z
);
}
vec4 mat4::乘法(常量vec4和其他)常量
{
返回向量4(
列[0]。x*其他.x+列[1]。x*其他.y+列[2]。x*其他.z+列[3]。x*其他.w,
列[0]。y*其他.x+列[1]。y*其他.y+列[2]。y*其他.z+列[3]。y*其他.w,
列[0]。z*其他.x+列[1]。z*其他.y+列[2]。z*其他.z+列[3]。z*其他.w,
列[0]。w*其他.x+列[1]。w*其他.y+列[2]。w*其他.z+列[3]。w*其他.w
);
}
mat4运算符*(mat4左侧、常量mat4和右侧)
{
返回左。乘(右);
}
mat4和mat4::运算符*=(常量mat4和其他)
{
返回乘法(其他);
}
vec3运算符*(常量mat4和左侧、常量vec3和右侧)
{
返回左。乘(右);
}
vec4运算符*(常量mat4和左侧、常量vec4和右侧)
{
返回左。乘(右);
}
mat4 mat4::正交(左浮动、右浮动、底部浮动、顶部浮动、近浮动、远浮动)
{
mat4结果(1.0f);
结果.元素[0+0*4]=2.0f/(右-左);
结果:元素[1+1*4]=2.0f/(上下);
结果:元素[2+2*4]=2.0f/(近-远);
结果.元素[0+3*4]=(左+右)/(左-右);
结果.元素[1+3*4]=(底部+顶部)/(底部-顶部);
结果.元素[2+3*4]=(远+近)/(远-近);
返回结果;
}
mat4 mat4::透视图(浮动视野、浮动视角、浮动近距离、浮动远距离)
{
mat4结果(1.0f);
浮球q=1.0f/tan(环面(0.5f*fov));
浮动a=q/aspectRatio;
浮动b=(近+远)/(近-远);
浮点数c=(2.0f*近*远)/(近-远);
结果.元素[0+0*4]=a;
结果.元素[1+1*4]=q;
结果.元素[2+2*4]=b;
结果:元素[3+2*4]=-1.0f;
结果.元素[2+3*4]=c;
返回结果;
}
mat4 mat4::翻译(const vec3和翻译)
{
mat4结果(1.0f);
result.elements[0+3*4]=translation.x;
result.elements[1+3*4]=translation.y;
result.elements[2+3*4]=translation.z;
返回结果;
}
mat4 mat4::旋转(浮动角度、常量向量3和轴)
{
mat4结果(1.0f);
浮动r=托拉半径(角度);
浮点数c=cos(r);
浮点数s=sin(r);
浮动omc=1.0f-c;
浮动x=轴x;
浮动y=轴y;
浮动z=轴z;
结果.元素[0+0*4]=x*omc+c;
结果.元素[1+0*4]=y*x*omc+z*s;
结果.元素[2+0*4]=x*z*omc-y*s;
结果.元素[0+1*4]=x*y*omc-z*s;
结果.元素[1+1*4]=y*omc+c;
结果.元素[2+1*4]=y*z*omc+x*s;
结果.元素[0+2*4]=x*z*omc+y*s;
结果.元素[1+2*4]=y*z*omc-x*s;
结果.元素[2+2*4]=z*omc+c;
返回结果;
}
mat4 mat4::比例(常量向量3和比例)
{
mat4结果(1.0f);
结果.元素[0+0*4]=标度.x;
结果.元素[1+1*4]=标度.y;
结果.元素[2+2*4]=标度.z;
返回结果;
}

计算代码中围绕任意轴旋转的对角线元素的公式似乎是错误的。尝试更改为:

    result.elements[0 + 0 * 4] = x * x + (1.0f - (x * x)) * c;
    result.elements[1 + 0 * 4] = y * x * omc + z * s;
    result.elements[2 + 0 * 4] = x * z * omc - y * s;

    result.elements[0 + 1 * 4] = x * y * omc - z * s;
    result.elements[1 + 1 * 4] = y * y + (1.0f - (y * y)) * c;
    result.elements[2 + 1 * 4] = y * z * omc + x * s;

    result.elements[0 + 2 * 4] = x * z * omc + y * s;
    result.elements[1 + 2 * 4] = y * z * omc - x * s;
    result.elements[2 + 2 * 4] = z * z + (1.0f - (z * z)) * c;

请参阅本手册第5.2节。

那么问题出在您的矩阵代码上,请说明。这解决了问题!非常感谢,我没注意到。