I know you guys have a lot on your plate and probably loads of todo’s for the new oF release, but I thought I’d post a little request for some changes to ofTexture (this was discussed a while ago, but maybe forgotten :P).
http://forum.openframeworks.cc/t/using-a-single-texture-for-multiple-objects/858/0
Some of the functionality mentioned in that thread can be done by extending/wrapping ofImage in an ofxSprite - which I’m happy to do - but to be able to do that some minor changes need to be done to ofTexture. Unfortunately I cannot add this functionality by extending ofTexture because an ofTexture is embedded into ofImage. So I would have to extend ofTexture and then rewrite ofImage if I wanted to use these methods. They are completely transparent to the user and 100% backwards compatible so should cause no problems.
The enableTextureTarget/bind/unbind/disableTextureTarget can be a massive bottleneck if you want to draw the same image a few thousand times (22fps vs 35fps for 15K draws).
Also the bind()/unbind() methods give the possibility of using alternative drawing methods in the future, e.g. if you have a few thousand instances want to draw using VBO’s and not using the ofImage/ofTexture draw at all, you can just bind() the ofTexture, then send your VBO and bob’s yer uncle.
(I know there have been some major changes to ofTexture with a pixels struct, so this code might not be accurate anymore, but you get the jist of it)
public:
void bind();
void unbind();
void quickDraw(float x, float y);
void quickDraw(float x, float y, float w, float h);
void drawQuad();
int getWidth();
int getHeight();
float getInvWidth();
float getInvHeight();
protected:
float invWidth, invHeight;
GLfloat tx0, ty0, tx1, ty1;
GLint px0, py0, px1, py1;
void ofTexture::bind() {
glEnable(textureTarget);
glBindTexture(textureTarget, (GLuint)textureName[0] );
}
void ofTexture::unbind() {
glDisable(textureTarget);
glBindTexture(textureTarget, 0);
}
// translates to the desired position and scales to desired size, then draws a quad (without binding and unbinding)
void ofTexture::quickDraw(float x, float y, float w, float h) {
glPushMatrix();
glTranslatef(x, y, 0);
glScalef(w * invWidth, h * invHeight, 1.0f);
if (ofGetRectMode() == OF_RECTMODE_CENTER) glTranslatef(-width * 0.5f, -height * 0.5f, 0);
drawQuad();
glPopMatrix();
}
void ofTexture::quickDraw(float x, float y) {
quickDraw(x, y, width, height);
}
// draws a single quad with the correct dimenions and texture coordinates
void ofTexture::drawQuad() {
// tx0, px0 etc. calculations are in allocate();
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();
}
// functionality is already divided into different functions
// so no need to duplicate code, this can just call the new functions
void ofTexture::draw(float x, float y, float w, float h){
bind();
quickDraw(x, y, w, h);
unbind();
}
void ofTexture::allocate(...) {
....
....
// precalculate these here as drawQuad needs them.
px0 = 0;
py0 = 0;
px1 = (GLint)width;
py1 = (GLint)height;
if (bFlipTexture == true){
GLint temp = py0;
py0 = py1;
py1 = temp;
}
GLfloat offsetw = 0;
GLfloat offseth = 0;
if (textureTarget == GL_TEXTURE_2D){
offsetw = 1.0f/(tex_w);
offseth = 1.0f/(tex_h);
}
// -------------------------------------------------
tx0 = 0+offsetw;
ty0 = 0+offseth;
tx1 = tex_t - offsetw;
ty1 = tex_u - offseth;
invWidth = 1.0f/ width;
invHeight = 1.0f / height;
}