【问题标题】:Fractal tree in modern OpenGL (OpenGL 3.3 and above)现代 OpenGL 中的分形树(OpenGL 3.3 及更高版本)
【发布时间】:2016-07-17 01:58:33
【问题描述】:

我需要一种使用现代 OpenGL 绘制 3D 分形树的方法。有什么建议吗?

我不一定需要完整的源代码,只是想知道如何去做。

我想做的是制作一棵 3D 树。在固定功能的 OpenGL 中,绘制一个好看的逼真的树并不难,但我不知道如何在现代 Opengl 中做到这一点。

我认为为每个分支使用圆柱模型并使用glm 将其转换到正确的位置和大小是个好主意,因为在这种情况下我可以使用模型的纹理坐标和法线,但是我被卡住了,我不知道该怎么做。

这是在固定函数 OpenGL 中使用递归制作的分形 2D 树。如果有人有兴趣,我可以发送整个源代码。

void drawTree(int currentDepth, int maxDepth)
{
    if (currentDepth > maxDepth)
        return;

    if (currentDepth <= maxDepth - 2)
    {
        glColor3d(0.45, 0.2, 0.05);
        glLineWidth(10 * static_cast<GLfloat>(pow(TREE_FACTOR, currentDepth)));
    }
    else
    {
        glColor3d(0, 0.5, 0);
        glLineWidth(30 * static_cast<GLfloat>(pow(TREE_FACTOR, currentDepth)));
    }

    double lineLen = TREE_LINE_BASE_LEN * pow(TREE_FACTOR, currentDepth);
    glBegin(GL_LINES);
    glVertex2d(0, 0);
    glVertex2d(0, lineLen);
    glEnd();

    int angle1 = 10 + rand() % 40;
    int angle2 = 10 + rand() % 40;

    glTranslated(0, lineLen, 0);
    glRotated(-angle1, 0, 0, 1);
    drawTree(currentDepth + 1, maxDepth);
    glRotated(angle1 + angle2, 0, 0, 1);
    drawTree(currentDepth + 1, maxDepth);
    glRotated(-angle2, 0, 0, 1);
    glTranslated(0, -lineLen, 0);
}

如何在现代 OpenGL 中使用 VAO、VBO 和着色器制作这样的东西?

【问题讨论】:

  • 但我被卡住了 - 我们不知道在哪里,在什么地方。 使用圆柱模型是个好主意 - 但是您当前的方法使用简单的线条。您想将其重写为现代 OpenGL,还是想要一种全新的方法?使用现代 OpenGL 绘制简单的线条是完全可能的,而且并不难。坦率地说,您需要进行的第一个(也是概念上最突出的)更改是将您的代码转换为使用glVertex2dv - 在更改之后,它只是设置和着色器:)
  • 缓冲递归 drawTree 中生成的参数,您将获得顶点缓冲方法
  • glVertex2dvglBegin/glEnd 对中使用,这些函数已被弃用。
  • 我尝试存储生成的参数,并设法用线条绘制了一个简单的分形树,但我怎样才能使树干变粗而树枝变细。现在看起来像这样:prntscr.com/am1ck1
  • 你需要将你的参数缓冲到glLineWidth 并在你的着色器程序中使用它

标签: c++ opengl fractals glm-math l-systems


【解决方案1】:

快速的想法。

void SudoCreateChild(const mat4x4& m2w_noscale, const int depth)
{
    if(depth>=MAX_DEPTH){
        return;
    }
    /// Creates the M2W matrix
    mat4x4 m2w=m2w_noscale * mat4x4::identity*(1/depth);
    /// Draw the branch
    DrawCylinder(m2w);
    /// Create the children branches
    for(int i=0; i<CHILDREN_NUMBER; ++i){
        float angle=(2.0f*PI/CHILDREN_NUMBER)*i;
        /// Initial rotation of PI/4 plus equal rotation between siblins
        mat4x4 rotation=mat4x4::rotate(angle, vector3(0,1,0))*mat4x4::rotate(PI*0.25, vector3(1,0,0))
        /// Size of the branch is 1/depth
        mat4x4 translation=mat4x4::translate(vector3(vector3(0,1,0)*(1/(depth+1))));
        /// Recursively create the branches
        SudoCreateChild(m2w_noscale*translation*rotation, depth+1);
    }
}

int main(void)
{
    SudoCreateChild(mat4x4::identity, 1);
    return 0;
}

【讨论】:

  • 我已经按照您在代码示例中显示的那样做,但它给了我这个:prntscr.com/am3kj9 with CHILDREN_NUMBER = 3 知道为什么会发生这种情况吗?
  • 我的错,我忘记连接父矩阵,我已经编辑了代码
猜你喜欢
  • 1970-01-01
  • 2017-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多