microj

10-26-2012, 03:03 PM

So I'm currently taking a graphics class, where so far we have used the deprecated glBegin/End functions to draw everything. I have really enjoyed working in openGL so i'm trying to learn more and I want to convert a project I did in the class to work in webGL.

The project draws a random tree (like the green leafy kind, well minus the leaves). Using the glBegin/End, it was fairly easy. I had a function that drew a truncated cone like so - cone(bot_radius,top_radius,height).

I then had a draw tree function drawing more cones recursively sort of like so.

drawtree(bot_r,top_r,height)

cone(bot_r,top_r,height)

glPushMatrix();

glTranslate(to top of last branch);

glRotate(around axis of last branch);

drawtree(new_bot_r,new_top_r);

glPopMatrix();

...

This was fairly simple to do and had good results but I'm struggling to implement it in webGL. I understand how I have to bind my vertex information into these buffer arrays to get sent to the graphics card, and I can draw a single cone. I don't however understand how to use the cone buffer i'm making to then fill a tree buffer (or if that is even the proper approach).

This is how i'm binding my cone.

var vertices = [];

var i=0;

for (i = 0; i <= 360; i+=5) {

vertices=vertices.concat([bot_r*Math.cos(degtoRad(i)),0,bot_r*Math.sin(degto Rad(i))]);

vertices=vertices.concat([top_r*Math.cos(degtoRad(i)),height,top_r*Math.sin( degtoRad(i))]);

textureCoords=textureCoords.concat(i/90, 0.0);

textureCoords=textureCoords.concat(i/90, 1.0);

}

coneVertexPositionBuffer = gl.createBuffer();

gl.bindBuffer(gl.ARRAY_BUFFER, coneVertexPositionBuffer);

gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

How could I go about using this to recursively create my tree? I'm using https://github.com/toji/gl-matrix in order to do my matrix stuff.

My idea was to use that loop that creates the cone, but just keep a global array of vertices for my tree so that when i call cone recursively, it will continue to append the vertices. With this approach I can get multiple cones to draw, but I can't get them to rotate and translate. To do that I tried to wrap my recursive call in Push/PopMatrix, and then use helper functions from the above library for the translation and rotation, to no avail (if i do that correctly, should it work?).

I also forsee another problem. If I do get that to work, I will have my tree array, and the vertecies for the branches will be all over the array(so when i finish one branch the next vertex will be at the bottom of the next branch). I feel like this willd draw a bunch of polygons where they shouldn't be, is there a way to not connect a certain part in my vertex array?

The following i'm just looking for some hints.

Along those lines, in the future I would like to have the branches smoothly transition from one to the next instead of sharply jut out of each other. Is there a nice way to sort of make those sharp corners curve without just adding more vertices in between? Also for the future, I want to be able to make the branches move together (like with wind) and possiby grow over time. Obviously to do that you would have to be changing the vertex information on the graphics card, any hints as to where to start with this idea?

The project draws a random tree (like the green leafy kind, well minus the leaves). Using the glBegin/End, it was fairly easy. I had a function that drew a truncated cone like so - cone(bot_radius,top_radius,height).

I then had a draw tree function drawing more cones recursively sort of like so.

drawtree(bot_r,top_r,height)

cone(bot_r,top_r,height)

glPushMatrix();

glTranslate(to top of last branch);

glRotate(around axis of last branch);

drawtree(new_bot_r,new_top_r);

glPopMatrix();

...

This was fairly simple to do and had good results but I'm struggling to implement it in webGL. I understand how I have to bind my vertex information into these buffer arrays to get sent to the graphics card, and I can draw a single cone. I don't however understand how to use the cone buffer i'm making to then fill a tree buffer (or if that is even the proper approach).

This is how i'm binding my cone.

var vertices = [];

var i=0;

for (i = 0; i <= 360; i+=5) {

vertices=vertices.concat([bot_r*Math.cos(degtoRad(i)),0,bot_r*Math.sin(degto Rad(i))]);

vertices=vertices.concat([top_r*Math.cos(degtoRad(i)),height,top_r*Math.sin( degtoRad(i))]);

textureCoords=textureCoords.concat(i/90, 0.0);

textureCoords=textureCoords.concat(i/90, 1.0);

}

coneVertexPositionBuffer = gl.createBuffer();

gl.bindBuffer(gl.ARRAY_BUFFER, coneVertexPositionBuffer);

gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

How could I go about using this to recursively create my tree? I'm using https://github.com/toji/gl-matrix in order to do my matrix stuff.

My idea was to use that loop that creates the cone, but just keep a global array of vertices for my tree so that when i call cone recursively, it will continue to append the vertices. With this approach I can get multiple cones to draw, but I can't get them to rotate and translate. To do that I tried to wrap my recursive call in Push/PopMatrix, and then use helper functions from the above library for the translation and rotation, to no avail (if i do that correctly, should it work?).

I also forsee another problem. If I do get that to work, I will have my tree array, and the vertecies for the branches will be all over the array(so when i finish one branch the next vertex will be at the bottom of the next branch). I feel like this willd draw a bunch of polygons where they shouldn't be, is there a way to not connect a certain part in my vertex array?

The following i'm just looking for some hints.

Along those lines, in the future I would like to have the branches smoothly transition from one to the next instead of sharply jut out of each other. Is there a nice way to sort of make those sharp corners curve without just adding more vertices in between? Also for the future, I want to be able to make the branches move together (like with wind) and possiby grow over time. Obviously to do that you would have to be changing the vertex information on the graphics card, any hints as to where to start with this idea?