2016-03-29 2 views
3

Мне нужен подход для рисования трехмерного фрактального дерева с современным OpenGL. Какие-либо предложения?Фрактальное дерево в современном OpenGL (OpenGL 3.3 и выше)

Мне не обязательно нужен полный исходный код, просто идея, как это сделать.

Что я пытаюсь сделать, это сделать 3D-дерево. В OpenGL с фиксированной функциональностью не так сложно нарисовать красивое реалистичное дерево, но я не знаю, как это сделать в современном Opengl.

Я думал, что было бы неплохо использовать модель цилиндра для каждой ветки и использовать glm, чтобы преобразовать его в нужное место и размер, потому что в этом случае я мог бы использовать координаты текстуры и нормали модели, но я застрял, и я не знаю, как это сделать.

Это фрактальное 2D дерево, выполненное в фиксированной функции OpenGL с рекурсией. Если кому-то интересно, я могу отправить весь исходный код.

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 и VBOs и шейдерами?

enter image description here

+1

* но я застрял * - и мы не знаем, где и на что. * хорошая идея использовать модель цилиндра * - но ваш текущий подход использует простые линии. Вы хотите переписать это на современный OpenGL как есть, или вы хотите совершенно новый подход? Это вполне возможно и не так сложно рисовать простые строки с современным OpenGL. И, откровенно говоря, первое (и концептуально самое важное) изменение, которое вам нужно было бы сделать, было бы превратить ваш код в использование 'glVertex2dv' - после этого изменения, это просто настройка и шейдеры :) –

+1

буфера аргументов, сгенерированных в вашей рекурсивной 'drawTree', и вы получите подход с вершинным буфером – BeyelerStudios

+0

Но' glVertex2dv' используется в парах 'glBegin/glEnd', и эти функции устарели. –

ответ

2

Быстрая идея.

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; 
} 
+0

Я сделал так, как вы показали в примере кода, но это дало мне это: http://prntscr.com/am3kj9 с CHILDREN_NUMBER = 3 Любая идея, почему это происходит? –

+0

моя ошибка, я забыл конкатенировать родительскую матрицу, я редактировал код –

+0

глупый, конечно. Он отлично работает: http://prntscr.com/amcto9 –

Смежные вопросы