现代 OpenGL 中的分形树(OpenGL 3.3 及更高版本)
Fractal tree in modern OpenGL (OpenGL 3.3 and above)
我需要一种使用现代 OpenGL 绘制 3D 分形树的方法。有什么建议吗?
我不一定需要完整的源代码,只是知道如何做。
我想做的是制作一棵 3D 树。在固定功能的 OpenGL 中,绘制一棵好看的逼真树并不难,但我不知道如何在现代 Opengl 中做到这一点。
我认为为每个分支使用圆柱体模型并使用 glm
将其变换到正确的位置和大小是个好主意,因为在这种情况下我可以使用纹理坐标和法线模型,但我卡住了,我不知道该怎么做。
这是用固定函数 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、VBO 和着色器制作类似的东西?
快速的想法。
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;
}
我需要一种使用现代 OpenGL 绘制 3D 分形树的方法。有什么建议吗?
我不一定需要完整的源代码,只是知道如何做。
我想做的是制作一棵 3D 树。在固定功能的 OpenGL 中,绘制一棵好看的逼真树并不难,但我不知道如何在现代 Opengl 中做到这一点。
我认为为每个分支使用圆柱体模型并使用 glm
将其变换到正确的位置和大小是个好主意,因为在这种情况下我可以使用纹理坐标和法线模型,但我卡住了,我不知道该怎么做。
这是用固定函数 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、VBO 和着色器制作类似的东西?
快速的想法。
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;
}