using a single texture for multiple objects

I am trying to figure out a way to just have one ofImage and pass that as a pointer to draw multiple objects with. I am messing around with a particle emitter and I dont want to have to use an instance on ofImage for every particle I draw so I was thinking if it is possible to do something like this pseudo code in each particle:

  
draw( ofVec3f _position, ofVec3f _velocity, ofImage* _img) {  
    //code to do things  
    _img->draw(x,y);  
}  

Will this work in reducing cpu cycles since it doesn’t have to have hundreds of instances of ofImage?

thanks

ding

1 Like

The ideal way to do this in pseudo code is the following:

  
  
Image img;  
Texture &tex = img.texture();  
tex.bind(0);  
  
//DRAW PARTICLES  
  
tex.unbind(0);  
  
  

If you go about with your suggested method, you’ll be binding/unbinding the texture for each particle drawn, which is unnecessary. Instead you can bind at the start of your particle draw and unbind afterward. The current ofImage and ofTexture classes don’t have methods for doing the above, which is bit odd so I would humbly submit to the authors that it would be a good idea to break the functionality out a bit as (at least for my tastes) things are encapsulated to the point of being overly constrained.

It should be a simple matter however to add methods as suggested above. Look at ofTexture::draw for how to implement bind/unbind methods.

hi –

nice points otherside. I would argue that we have a kind of trade off in functionality between offering up every single operation (and handling people’s mismanagement of objects) and making things simple and easy to understand for a beginner. On the flip side, we have made all elements protected, so it’s quite possible (and encouraged) to extend any class and make those operations visible, ie,

  
  
class ofBindableTexture : public ofTexture  
  

I’m sure that it’s useful, it’s just a question of usage – how many people need to bind their own textures and whether or not it makes sense to have this more advanced operation at the base level. One thing we are actively doing is paying attention to usage, and if it’s the kind of thing people want to do more often, it will get in to the base… I hope that makes sense. we are definitely flexible and trying to create an api that’s simple enough for beginners and extendable / optimized enough for experts.

if the simplicity of the api is too constrained for you, we encourage you to jump and extend away… I don’t think there is anything wrong with having a simple base and a more elaborate subclasses, then you wont be frustrated, because able to do the stuff you want and the beginners are not frustrated, because they don’t understand which function to call in what order, b/c the api has too many options.

ding, you are right to pass the ofImage like that, or like (…, ofImage & _img). Otherwise, you will do pass by copy, very expensive because it will copy the ofImage object per draw call…

hope that helps!
take care,
zach

I hear your point about simplicity, but I think it can be expressed on many levels such that both a beginner and an advanced user find things approachable. I would argue that the constant need to extend of classes through inheritance indicates a need for a different refactoring of class behavior such that combinatorial complexity is increased while keeping the basic interface simple. By combinatorial complexity, I’m referring more to the total number of possible ways of connecting things not that it’s particularly “complex” to use.

For example, instead of embedding Texture in Image, I would argue instead for a generic class Matrix that would mediate the connections between relevant classes like Texture, Image, Video, Camera, Mesh, etc. In this case, I could draw images, turn images into meshes, go from textures to meshes, etc. I don’t think breaking things out like this would impose any performance penalty either.

anyway, just a thought. As for binding, I don’t think it’s terribly difficult to understand and it would greatly aid multitexturing. Having to subclass ofTexture just to get multitexturing seems like abuse of inheritance and fractures the design quickly.

I still disagree, but I’d say the following in a super friendly way: **patches speak louder then words. ** if you have an idea of how to improve something, throw it up there and let the community talk about and play with it.

for example:
http://www.openframeworks.cc/forum/view-…-ght=events
is a great, because stefan is suggesting something and giving us a chance to try it.

Theo and I feel a great deal of responsibility for the core, and for keeping the core simple and easy to use for beginners, but that doesn’t mean we aren’t open to suggestions. But at the same time, we have a clear design idea that may or may not jive with someone that has been rolling their own industrial strength code for a while. That’s not our goal – our goal is to make a very simple, easy and extednable tool that makes coding fun and reduces frustration, but also gets experts a chance to get involved. Also, we are trying *not* to change the core too much so that code doesn’t break.

we have an addon system by which people can add their own code and styles of doing stuff. You could create your combinatorially complex classes and throw it up there as a more powerful alternative to ofImage and ofTexture. For us that’s great, because you don’t even have to deal with core and also, you, since you have a clear idea of how you would do that system, would manage it and answer questions, take bug reports, etc.

anyway, I just think you can take that energy to change the core and either (a) throw up some examples for the community to play with and discuss or (b) craft an addon where you can do stuff your own way

take care,
zach

Hi Guys,

As this is something which I’ve personally encountered, I feel I should add my thoughts as well.

For my particle systems, I ended up not using the ofImage::draw() command at all for this very reason. I did not want to extend the ofImage or ofTexture class as it felt unnecessary and overkill for what I needed to do. I simply used pure opengl calls, bound the texture before iterating, and then drew each particle with opengl QUAD commands.

I’m not going to comment on Otherside’s suggested class architecture as I think those kind of discussions can go on forever and there are billions of pretty hefty books out there that talk purely about the philosophy of structuring classes…

But I would like to say, I do agree that simply ‘bind()’ and ‘unbind()’ methods would be very useful for ofImages (and ofTextures). The old code wouldn’t have to break… the draw command can stay as it is. But for anyone building particle systems, or drawing the same sprite many times, it would be very useful to bind first, then iterate a new command such as drawFastQuad(x, y, width, height), and then unbind. In fact I used quads rendered via a display list, I haven’t actually timed the performance difference, but when there are 5000+ particles on screen I psychologically feel more comfortable knowing its running the most efficiently as possible! :stuck_out_tongue:

This could all be done by extending ofTexture and ofImage, but I do think it would be useful to so many people (as so many people are interested in some forms of particle systems), that I also think it could be in the core by simply adding a few methods to the existing classes.

Just my 2p…

So I have been reading that simply using glDisable(GL_TEXTURE_2D); is not enough. You must pass 0 to the texture like: glBindTexture(GL_TEXTURE_2D, 0) is that right? So I still don’t get how that will speed things up. Say I have to draw like 1000 particles on screen. So I do like:

-bind texture
-iterate 1000 time
–pass texture pointer/or address to the particle
–draw particle texture
-iterate done
-unbind texture

So if it is just one image I am working with this would have no benefit at all? I am guessing that this would be beneficial only if I was repeating the above step multiple times with a different texture each time. Is that right?

ding

hi memo,

thanks – in some way hearing other people ask for this is good for us - we only know what people want when they tell us about their usage, and no one has asked for this before. youre right - it’s no problem to add manual bind to ofTexutre - but at the same time, playing devil’s advocate, maybe it’s better to create a “sprite” addon that allows for tighter control? I think a sprite object is conceptually different enough from an ofImage or ofTexture that it makes sense, at least in my mind.

does binding even take that long? maybe it’d be good to test at least :slight_smile:

I’ll kick around some ideas in the meantime. we’ve been thinking about some hooks like setUseTexture(false) to allow for greater overriding, some hooks we are throwing into 0.06 are things like, setUseSetupScreen(false) which could allow people to do their own setupScreen (however they want), for 3d etc, and we could try out a setAutoBind(false) for textures…

anyway, the whole point is we are striving to keep to the core simple and listen to people’s needs –

-zach

To me(if I am understanding things right) it seems that you would only need to have an unbind function seeing as the draw method already rebinds the texture automatically.

  
void ofTexture::draw(float x, float y, float w, float h){  
	glEnable(textureTarget);  
	// bind the texture  
	glBindTexture( textureTarget, (GLuint)textureName[0] );  

Is this correct? So an unbind method might be something like:

  
glDisable(textureTarget);  
glBindTexture(textureTarget, 0);  

Am I understanding things right?

ding

Hi ding,
Yes, that’ how to to it:

  
  
   
void  ofTexture:bind() {  
  glEnable(textureTarget);  
   // bind the texture  
   glBindTexture( textureTarget, (GLuint)textureName[0] );  
}  
  
void ofTexture:unbind() {  
  glDisable(textureTarget);  
  glBindTexture(textureTarget, 0);  
}  
  
  

Hi ding, the current draw function bind and unbinds the texture automatically. I wouldn’t bet my life on the fact that this can have considerable overheads when used thousands of times per frame - but I used to develop video games in the late 90s early 00s… I wasn’t an engine coder, but our engine coders always tried to minimize the number of gl commands as much as possible. Even duplicate commands supposedly have overheads. Maybe these days with powerbeasts nvidia and ati are pumping out this is a bit overkill, but the habits live on.

Essentially when you are drawing a texture with opengl, you are not really drawing a texture with opengl - there are 2 steps involved. First you tell the opengl state machine which texture to use - that texture becomes active. Then you draw quads, triangles etc. Until you change textures, or unbind any texture, everything you draw will be with that texture.

So I still don’t get how that will speed things up.

everytime you issue the command glBindTexture( target, name ); there is a bit of overhead, even if it is the same texture you are binding. LIke I said, I don’t know if in this day and age this is a big deal - should do some tests - but 4-5 years ago it was definitely worth avoiding. If you want to have as many particles as possible, then I would suggest this optimization route. If you only want a couple hundred it probably won’t matter.

So if it is just one image I am working with this would have no benefit at all? I am guessing that this would be beneficial only if I was repeating the above step multiple times with a different texture each time. Is that right?

not exactly, as I mentioned above, the overhead comes from actually telling opengl which texture to use, for every single particle. Everytime you call the ofImage::draw() function, its binding the same texture again.

To me(if I am understanding things right) it seems that you would only need to have an unbind function seeing as the draw method already rebinds the texture automatically.

We would still need the bind function, because the purpose of this is to have a new draw function which does not bind the texture. a fastDraw() function which just draws a quad:

  
  
function fastDrawQuad(x, y, scaleX, scaleY) {  
 		// the texture coordinates and vertex coordinates should be precalculated   
		glPushMatrix();  
		glTranslatef(x, y, 0);  
		glScalef(scaleX, scaleY, 1);  
		glBegin( GL_QUADS );  
			glTexCoord2f(tx0,ty0);			glVertex3i(px0, py0,0);  
			glTexCoord2f(tx1,ty0);			glVertex3i(px1, py0,0);  
			glTexCoord2f(tx1,ty1);			glVertex3i(px1, py1,0);  
			glTexCoord2f(tx0,ty1);			glVertex3i(px0, py1,0);  
		glEnd();  
		glPopMatrix();  
}  
  

That is all you need to do 5000 times for 5000 particles, all the stuff found in the draw function, before and after you can do just once before rendering the particle system.

Ultimately the code should be something like

  
  
bindTexture() {  
		glEnable(textureTarget);   
		glBindTexture( textureTarget, (GLuint)textureName[0] )  
}  
  
preCalcCoordinates() {  
		// calculate tx0, tx0, ty0, ty1, px0... etc.  
}  
  
for(each particle) {  
   ofImage.fastDrawQuad();    
}  
  
unbind() {  
		glDisable(textureTarget);   
		glBindTexture( textureTarget, 0);  
}  
  

again to repeat - unless you really really want to push your machine to the limits, then you don’t really need to go through all this trouble.

@Zach:
I understand that you guys are trying to keep it simple… and that can be quite hard when dealing with C++!!! at the end of the day its free software! so we can’t complain and demand anything!! I think its just gonna evolve as user needs become more and more obvious… but essentially I think its best be a balance of minimal steps and easy to use methods which have slightly less performance (e.g. the ofImage::draw()) but also include methods for more advanced users as alternatives (e.g. the bind, unbind, fast draw methods).

Having written this, maybe it does make sense to do implement this through class extending. THough I would prefer if the simple classes extended the advanced classes instead of the other way round. E.g. in the core there is (ignore the class names):

class ofImageAdvanced, which has the binding, unbinding, fast draw functionality etc.

and extending that is ofImage, which has the all in one draw() command.

just a thought

(I remember a similar issue came up with the loading of images with textures, and the ability to create the texture manually at some point after the image was loaded - an issue in multithreaded apps).

I think there will be a noticeable speedup because ofImage::draw() calls glDisable/glEnable. This will definitely have an impact on driver state and thus performance.

As for inheriting to extend toward ofImageAdvanced, the reason I’m very much against this model of extension is because it fractures the functionality to the detriment of keeping the API clean and simple. If one were to make an ofImageAdvanced with said changes, how would they be used with ofTexture? Would you have a mix-in class that contains the Advanced features? Would you duplicate the code? I would propose that the easiest solution is to put everything having to do with textures (binding, drawing, etc.) in ofTexture so you don’t have this splitting and duplicating of code.

Anyway, my 2p. Just trying to constructively critique the code and provide some kind of feedback on the design.

I would propose that the easiest solution is to put everything having to do with textures (binding, drawing, etc.) in ofTexture so you don’t have this splitting and duplicating of code.

Fair enough, I think it makes more sense to only have one class as well. I only suggested having the advanced class and simple class so it would be easier for beginners to learn the API - they wouldn’t be bombarded with hundreds of methods when looking through the documentation or header files- they would only have to look at the simple classes methods. Though I think this can still be achieved with a single class by physically grouping and commenting methods as simple or advanced in the header files - so newcomers only need to look through the basic methods first, and when they are more comfortable they can look at the more advanced functions…

P.S. I think the ofTexture would need the bind, unbind, draw, fastDraw etc… but so would the ofImage… as they are associated through composition, and the ofImage would need to pass on the messages to its associated ofTexture.

You’re right that if ofImage has an ofTexture inside it you need someway to access those methods. Earlier in the thread I proposed a solution with a Matrix class to mediate so you would move ofTexture out of ofImage (which seems really awkward to me and I think this is a case in point). Also by extension so does ofCamera, ofVideo, etc. The complexity adds up very quickly.

As for things being intimidating to beginners, I think all of this is way too speculative and I feel that if there are proper examples and docs with a good solid design, it won’t be so overwhelming. The key components of a Texture class IMHO are

bind()
unbind()
frommatrix()
startcapture()
endcapture()
dim()

You really don’t need more than these 6 methods for 99% of things. I don’t think that’s too much for beginners to understand.

In the current model of ofImage, instead of adding bind/unbind etc, I would simply add an ofTexture accessor:

  
  
const ofTexture& ofImage::texture();  

or if you’re brave

  
  
ofTexture& ofImage::texture();  

With the former function ofTexture’s methods would have to be properly const correct such as:

  
  
void ofTexture::bind() const;  
void ofTexture::drawAdvanced() const;  
void ofTexture::unbind() const;  

I think it’s not too complicated to get some of the ideas here in place – the lesson I’m getting is to try to bump up a bit ofTexture and provide some means of accessing it – this isn’t too complicated or hard to swallow. At the same time, I think we have a good position which is to try to be as conservative as possible about the core. too many libraries in my opinion are overly complicated and in this case - getting a starting point and having clean and clear functions that don’t require you to know too much about underlying technologies are crucial – esp when just getting into c++. we are trying to keep our ear to the ground and implement needed changes, and we appreciate arguments and discussion, etc.

I do however think that a sprite class ofxSprite, etc is not a bad idea and could have more functionality then ofTexture or ofImage, etc.

physically grouping and commenting methods as simple or advanced in the header files - so newcomers only need to look through the basic methods first, and when they are more comfortable they can look at the more advanced functions…

this is a good idea that I like about processing - certain functions, like setUseTexture() don’t necessarily make sense until you need to dig deeper, but they are very helpful once you do something like load hundreds of images. Part of the magic will be communicating enough info to get started but he right info about how to fix / diagnose problems, etc.

thanks !
zach

Well I’ve been doing some test with this bind/unbind stuff and I am consistently getting 5-8 ms. better performance drawing 500-650 .png particles using bind/unbind
I just hacked ofTexture like this:

  
//---------------------------------------------------CHANGED STUFF  
void ofTexture::bind(){  
	glEnable(textureTarget);  
	// bind the texture  
	glBindTexture( textureTarget, (GLuint)textureName[0] );  
}  
  
void ofTexture::unbind(){  
	glDisable(textureTarget);  
	// unbind texture  
	glBindTexture(textureTarget, 0);   
}  
  
void ofTexture::quickDraw(float x, float y, float w, float h){  
	  
	GLint px0 = 0;		// up to you to get the aspect ratio right  
	GLint py0 = 0;  
	GLint px1 = (GLint)w;  
	GLint py1 = (GLint)h;  
	  
	if (bFlipTexture == true){  
		GLint temp = py0;  
		py0 = py1;  
		py1 = temp;  
	}  
	  
	// for rect mode center, let's do this:  
	if (ofGetRectMode() == OF_RECTMODE_CENTER){  
		px0 = (GLint)-w/2;  
		py0 = (GLint)-h/2;  
		px1 = (GLint)+w/2;  
		py1 = (GLint)+h/2;  
	}  
	  
	// -------------------------------------------------  
	// complete hack to remove border artifacts.  
	// slightly, slightly alters an image, scaling...  
	// to remove the border.  
	// we need a better solution for this, but  
	// to constantly add a 2 pixel border on all uploaded images  
	// is insane..  
	  
	GLfloat offsetw = 0;  
	GLfloat offseth = 0;  
	  
	if (textureTarget == GL_TEXTURE_2D){  
		offsetw = 1.0f/(tex_w);  
		offseth = 1.0f/(tex_h);  
	}  
	// -------------------------------------------------  
	  
	GLfloat tx0 = 0+offsetw;  
	GLfloat ty0 = 0+offseth;  
	GLfloat tx1 = tex_t - offsetw;  
	GLfloat ty1 = tex_u - offseth;  
	  
	glPushMatrix();  
	glTranslated(x, y, 0);  
	glBegin( GL_QUADS );  
	glTexCoord2f(tx0,ty0);			glVertex3i(px0, py0,0);  
	glTexCoord2f(tx1,ty0);			glVertex3i(px1, py0,0);  
	glTexCoord2f(tx1,ty1);			glVertex3i(px1, py1,0);  
	glTexCoord2f(tx0,ty1);			glVertex3i(px0, py1,0);  
	glEnd();  
	glPopMatrix();  
  
}  

and ofImage like this:

  
//------------------------------------CHANGED STUFF  
void ofImage::bind() {  
	if (bUseTexture){  
		tex.bind();  
	}  
}  
  
void ofImage::unbind() {  
	if (bUseTexture){  
		tex.unbind();  
	}  
}  
  
void ofImage::quickDraw(float _x, float _y, float _w, float _h) {  
	if (bUseTexture){  
		tex.quickDraw(_x, _y, _w, _h);  
	}  
	  
}  

So when I need to do a quickDraw I just:

  
particleImg.bind();  
for(int i=0; i<particles.size(); i++){  
	particles[i].quickDraw();  
}  
particleImg.unbind();  

BTW I still pass a pointer of the img to each of the particles at creation time. something like:

  
particles.push_back(Particles(pos, iniVel, &particleImg));  

and in the particle I have these in their proper place:

  
//class var  
ofImage*	img;  
//constructor  
Particles(ofxVec3f _pos, ofxVec3f _vel, ofImage * _img);  
//draw method  
img->quickDraw(pos.x, pos.y, pos.z+life, pos.z+life);  
  

Any thoughts on this stuff?

ding

Thats exactly right. Compared to what is the 5-8ms performance gain? (i.e. what percentage?).

In the quickdraw I would also try losing everything before the glPushMatrix() and precalculate it all assuming (w,h) to be the image dimensions (or a fixed size like 100, 100 - whatever suits your needs). Then use glScale() (after the glTranslated()) to scale the particles up or down - dunno if the performance gain is worthwhile, but while you’re at it timing it all, could be useful to find out!

While you’re at it, you could even try using a display list to see if it makes much difference! (It would be best to share one quad display list between all particles, sprites etc… but for that the textures would need to be GL_TEXTURE_2D not GL_TEXTURE_RECTANGLE_ARB so that the UV coordinates for all would be the same ranging from 0…1 instead of 0…image_dimensions. I don’t think we have control over whether an ofTexture is GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE_ARB in openframeworks?)
http://www.glprogramming.com/red/chapter07.html

I’m not at my machine right now, but can send you the code later on when I am…

P.S. I agree with otherside that not all the new methods of ofTexture need to be carried across to ofImage. If ofImage has an accessor method for its ofTexture, then the ofTexture::bind(), ofTexture::unbind() and ofTexture::quickDraw() can be accessed via that.

i.e.

  
ofTexture *tex = myImage.getTexture();  
tex->bind();  
for(...) tex->quickDraw(...);  
text->unbind();  
  

not because its faster or better, but just so you don’t have to modify the ofImage class everytime the ofTexture class is modified - the basic functions can be done directly through ofImage, and more advanced functions can be done via the ofTexture.

Actually I do need them to be GL_TEXTURE_RECTANGLE_ARB for my purposes. In of you can set that globally by using:

  
ofSetRectMode(OF_RECTMODE_CENTER);  

ding

oh! I forgot to mention that my machine is a g4 powerbook 1.5ghz with 512mb of ram running leopard :frowning:

ding

Hi ding,
for the record, GL_TEXTURE_RECTANGLE_ARB and OF_RECTMODE_CENTER are two quite different things actually.

OF_RECTMODE_CENTER is a purely OpenFrameworks flag which simply affects the arithmetic calculating where to draw the texture. As you probably already know, OF_RECTMODE_CENTER just means that the x,y position you provide is where the center of the quad goes, and OF_RECTMODE_CORNER means the the x,y position is where the top left corner goes.

GL_TEXTURE_RECTANGLE_ARB (vs GL_TEXTURE_2D) comes from opengl and is generally completely transparent to the user (of coder)… i.e. he/she doesn’t really know or care which one is being used unless he/she really wants to know.
GL_TEXTURE_RECTANGLE_ARB means the texture can be any dimensions (not limited to powers of 2) and texture coordinates glTexCoord2f(u, v) are in pixels (0… width, 0… height).
GL_TEXTURE_2D means the texture coordinates glTexCoord2f(u, v) are always 0…1 (so we can have a single quad display list used for all particles, textures etc.) but texture has to be a power of 2 - unless you have the opengl extension GL_ARB_texture_non_power_of_two which most modern cards (and usually those that also support GL_TEXTURE_RECTANGLE_ARB) would have.

All of this should be (and is) transparent to the average of coder unless he/she wants to delve into it, but again I would propose an advanced method to actually be able to delve into this. It was quicker and easier for me to change ofTexture than it would have been to extend ofTexture, and extend ofImage to use the new superclass of oftexture etc - and I think the new classes would actually increase the learning curve as well…

I’m not suggesting a radical change to ofTexture, but just the ability to set whether it would be GL_TEXTURE_RECTANGLE_ARB or GL_TEXTURE_2D (or anything else in the future). It would be fully backwards compatible, and those not interested in this can just ignore the method.

On a different note, when you say you gained 5-8ms, what was the timings before you changed to the new method of rendering (keeping the bind/unbind outside of the loop). If you are trying to squeeze as much as possible out of your old G4 I would recommend trying the display list method as well…

I’ll post a sample when I get a chance…