glutSolidSphere & glutWireSphere replacement

Here is one for someone wanting to contribute to OF but doesn’t know where to start.

OpenGL ES is currently missing a sphere drawing function.

From ofGraphics.cpp:

// this needs to be swapped out with non-glut code
// for good references see cinder’s implementation from paul bourke:
// https://github.com/cinder/Cinder/blob/master/src/cinder/gl/gl.cpp
// void drawSphere( const Vec3f &center, float radius, int segments )
// and processing’s implementation of icospheres:
// https://code.google.com/p/processing/source/browse/trunk/processing/core/src/processing/core/PGraphics.java?r=7543
// public void sphere(float r)

https://github.com/openframeworks/openFrameworks/blob/develop/libs/openFrameworks/graphics/ofGraphics.cpp#L875

For reference look at the ofBox function.
https://github.com/openframeworks/openFrameworks/blob/develop/libs/openFrameworks/graphics/ofGraphics.cpp#L916

It would in an ideal world use GL_TRIANGLES, not strips so it draws in one batch, support texturing and not warp towards the poles too much.

Will get to it myself at some point, but just throwing it out there!

/A

those are my comments :slight_smile:

ofBox is an ok model, but it’s not perfect. it breaks the OF model a little by having texture coords enabled by default, and by having normal information (though ofBox is the first 3d drawing function anyway, so there wouldn’t have been normals before). it’s also unclear whether it should be corner or center mode by default… everyone has different preferences and use cases.

Well certainly normal information seems like something the 3D objects should have and optionally texture coordinates.

And yes you are right there is the corner issue, although I’m thinking that for 3D the center is probably the most used mode?

Also something I was thinking about is whether it would make sense to separate mesh generation and object drawing?

So ofBox woud look something like:

[tt]
static ofMesh vertexData;

void ofBox(float size){
ofGenerateBoxMesh(&vertexData, size);
renderer->draw(vertexData);
}[/tt]

This way it would be easy to generate your own mesh and pop it into a ofVbo to avoid generating the vertices (and uploading them to the card) every time you draw a box, if you are an advanced user looking to draw a lot of them.

There is just the box and the sphere now of course, but it would be nice to in the future support subdivided planes, cylinders, torus, etc etc.

And I would be super keen to see some sort of OF equivalent of the Utah teapot :wink:

/A

i think the way OF handles circles is smart. generating is done when necessary, and then stored internally. it’s drawn with a vertex array rather than a vbo (for compatibility reasons, i think).

personally i feel like the processing model is perfect for answering two of these questions:

1 corner or center? have rectMode() ellipseMode() -> ofSetBoxMode(), ofSetSphereMode() w OF_CORNER_MODE, OF_CENTER_MODE
2 to generate or not? generate internally, user should only be required to say ofBox() and ofSphere() and be done.
3 textured or not? i would love to see every drawing function in OF automatically have autogenerated texcoords when you flip a switch like ofSetTexCoords(true) or something similar. but this has to be explored more…

i would love to see every drawing function in OF automatically have autogenerated texcoords when you flip a switch like ofSetTexCoords(true) or something similar. but this has to be explored more…

+1 on this. I was thinking it over today and really can’t see a downside to it, since we already have switches for ARB and some other features, it does fit w/the general structure of OF.

I’m also liking the idea of generating sphere/box/teapot meshes for VAs and storing them for calls. I think storing them as VBOs might be confusing since the internal drawing routines are already using vertex arrays, but that’s just an initial thought. They could be generated with some default settings, and then changing ofGeomUseTexCoords() (bad name, I know) would regenerate them w/the new defaults.

an aside: i was thinking about this some more last night and realized, the reason VBO doesn’t make sense is because it needs to be cairo-compatible.

Absolutely, this all makes perfect sense.

What I was suggesting was just a small refactoring to allow advanced users to get access to the geometry generation.

At the moment if I say wanted the geometry for a sphere for various nefarious purposes I would either write my own code or copy paste the OF code (once we’ve replaced the glut functions) which seems like a shame since it’s already there.

I think it should definitely use an ofMesh as it does now, ofVbo can take it’s data from an ofMesh, so if you are an advanced user and you want to draw a bunch of spheres using VBOs you could just fill up an ofMesh with the sphere data, give it to a VBO and use that to draw from now on. Or do deformations on the mesh data or whatever you have in mind.

To the user it would still just look like: ofSphere( 30.0f );

So I suggest something like this, which only re-generates the mesh data when needed, but separates the drawing and the generation so that if you need the data to play around with you can call ofGenerateSphereMesh(…) yourself.

[tt]static ofMesh scratchSphereVertexData;
int currentSphereMeshDetail = -1;
float currentSphereMeshRadius = -1.0f;

//----------------------------------------
void ofSphere(float radius, int sphereDetail = 20 ){

// Do we already have exaclty this mesh?
if( sphereDetail == ofGetSphereDetail() &&
(ofGetUseTexCoords() && scratchSphereVertexData.hasTexCoords()) &&
currentSphereMeshRadius == radius ) {
} else { // Otherwise generate one and save the parameters we used
ofGenerateSphereMesh( &scratchSphereVertexData, sphereDetail, radius );
currentSphereMeshDetail = sphereDetail;
currentSphereMeshRadius = radius;
}

renderer->draw(scratchSphereVertexData);
}[/tt]

Now we only have 3D spheres and boxes, but I think it would be nice to in the future have a few more drawing functions like ofTorus, etc and then getting access to the data if needed makes more sense.

Then there is the issue wether we should even generate primitives at any other size than 1.0f and the ofScale up when drawing, but I’m sure there are various good points for and against there.

yes, i think there should be functions like:

  
  
ofMesh ofGetSphere(float radius);  
  

then each renderer will have a sphere method which renders a sphere by calling that function and caching it if it really makes things faster.

about using vbo or no, this is implemented per renderer so each renderer can decide how to do it, in the case of the current renderer i thing it should be plain vertex arrays since the rest of the primitives also use vertex arrays but the new openglES2 renderer or a future openGL3 one could use a vbo internally.

actually to use a vbo you just need to do:

  
ofVboMesh sphere = ofGetSphere(radius);  

i sent kyle a link to a library which has lots of primitives like cilinder, torus, cone… kyel, i cannot find the link, do you have it? the library was called GLTools.

Arturo, is it this from the superbible? http://code.google.com/p/oglsuperbible5/source/browse/trunk/Src/GLTools

yes, i think it’s that one, i remember it having more primitives, but it was from the examples in a book and it was in google code so it’s almost sure that one. I like the naming, ofMakeSphere…

With regards to this I started porting over some of the primitives from Ogre Procedural ( http://code.google.com/p/ogre-procedural/ ) to OF, you can have a look at the commit on my fork here:

https://github.com/andreasmuller/openFrameworks/blob/develop-opengles2/libs/openFrameworks/3d/of3dPrimitives.h

Let me know what you think.

Oh I should mention I have not looked into the wireframe drawing of this yet.

omg that’s awesome!

super complete, and nicely abstracted.

you even have the tex coord generation.

i’d love to see this added.

Really nice! I’d like to see this in core as well, I especially like that these don’t contain the ofMesh, but simply operate on it instead, so you could maybe keep those as props of the application. Only thing that’s missing from GLUT is the Teapot :slight_smile:

One thing I was wondering about was if we should ever generate a mesh larger than 1.0 in size and instead use ofScale to draw it at the size the user has requested.

This way we would speed things up a lot for beginners (the mesh is never regenerated unless you change the resolution) but advanced users can still generate their own ofMeshes and pass them along to VBOs or whatever they want.

Yes I also want the Teapot! And as I’ve been harping on about, I would love for OF to have a “signature” shape of it’s own :slight_smile:

Ogre Procedural has a few more shapes I haven’t ported over yet, an Ico Sphere and a torus know in particular, this was the low hanging fruit. I needed something with great normals to try to ES 2.0 renderer lighting with and I’m having issues with assimp on iOS devices a the moment.

Ogre Procedural is released under the MIT license, which as far as I understand simply requires that I include proper credit and the MIT license in the affected files?

the only thing about generating at anything other than 1.0 and scaling is that you need to un-scale normals somehow… that said, GL_NORMALIZE might be faster than regenerating the ofMesh at the right size each time…

Was just glancing at ofSphere() and saw this :slight_smile:

  
	// TODO: add an implementation using ofMesh  
#ifndef TARGET_OPENGLES  
	// this needs to be swapped out with non-glut code  

I see you’ve made some progress on the ES 2.0/iOS front. Lacking one of those devices I can’t check the status, but is this getting closer to being ready for a pull request? I’d love to see this get included in core (and, selfishly, it would make a chapter I’m re-writing for my book way easier).

The problem with the sphere is not related with openGL ES 2 actually but that is using glut which is not present in openGL ES. So I think you can count with the implementation for a platform independent sphere + the rest of the 3D primitives soon (at least in git you know how the OF release cycles are :slight_smile:

Sounds good, I’ll just proceed as if it’ll work :slight_smile: Though I don’t think there’s anything wrong with using GLUT in the windowing code, but the glutSolidSphere really has to go.

Looking at hahakids git repo though he had run into some ES problems with the primitives but fixed them all apparently (I can’t check due to iOS-lackingness).

mmh, the only difference i can think of between ES and plain openGL for something like this is the type of the indices (int for openGL and short for ES) but that’s already solved in ofMesh by using ofIndexType which is defined as one or the other depending on the platform

Andreas do you remember having any problem with this in iOS?