Span OpenGL Texture over multiple Vertices

Hello again,

I am currently thinking about a concept to use a QUAD_STRIP Ribbon as a slideshow or something similar. But I want to use a smooth ribbon which means that I will propably use quite many Vertices. The problem is that I want every image on the ribbon to have similar / the same width which would propably mean that I would have to span every image over many vertices and not only one. Another problem is that the vertices would propably not all have the same width so my Question is: Is there a way to get the textures/images added to the ribbon with the same width? Maybe through a shader?

If you dont understand what I mean pls tell me!

Thanks in advance!

EDIT: Would it be easier to put all images of the slideshow into one huge texture?

one way to do this is just texture each segment of the ribbon with the appropriate section of the texture so that they’re all aligned.

since it’s a quad strip this isnt really that hard since you always have 4 points for each segment.

testApp.h

  
			  
#ifndef _TEST_APP  
  
#define _TEST_APP  
  
  
  
  
  
#include "ofMain.h"  
  
#include "ofAddons.h"  
  
#include <vector>  
  
  
  
class testApp : public ofSimpleApp{  
  
	  
  
	public:  
  
		  
  
		void setup();  
  
		void update();  
  
		void draw();  
  
		  
  
		void keyPressed(int key);  
  
		void keyReleased(int key);  
  
		void mouseMoved(int x, int y );  
  
		void mouseDragged(int x, int y, int button);  
  
		void mousePressed(int x, int y, int button);  
  
		void mouseReleased();  
  
		  
  
		vector<ofPoint *> points;  
		int ribbonWidth;  
		int ribbonHeight;  
		ofImage ribbonTexture;  
	  
		float mouseY;  
		float mouseX;  
		  
  
};  
  
  
  
#endif  
  

testApp.cpp:

  
  
#include "testApp.h"  
  
  
  
  
  
//--------------------------------------------------------------  
  
void testApp::setup(){	   
  
	points.clear();  
	  
	ofPoint * newPoint;  
	for(int i=0; i<10; i++)  
	{  
		newPoint = new ofPoint(i*100,200);  
		points.push_back(newPoint);  
	}  
	  
	  
	ribbonTexture.loadImage("image.png");  
	  
	ribbonWidth = points[points.size()-1]->x - points[0]->x;  
	ribbonHeight = 500;  
	  
	mouseY=0;  
  
}  
  
  
  
//--------------------------------------------------------------  
  
void testApp::update(){  
  
	glBindTexture(GL_TEXTURE_RECTANGLE_ARB, (GLuint)ribbonTexture.tex.textureName[0]);  
  
}  
  
  
  
//--------------------------------------------------------------  
  
void testApp::draw(){  
  
	float divX = ribbonWidth / ribbonTexture.width; // movie mapping  
	float divY = ribbonHeight / ribbonTexture.height; //these adjust how the movie is mapped.   
	ofSetColor(255,255,255);  
	  
	glEnable(GL_TEXTURE_RECTANGLE_ARB);  
		  
	glBegin(GL_QUAD_STRIP);  
	  
		for(int i=0; i<points.size(); i++)  
		{  
			glTexCoord3f(mouseX+points[i]->x/divX,0/divY, sin(i)*100);  
			  
			glVertex3f(points[i]->x,points[i]->y, sin(i)*100);  
			  
			glTexCoord3f((mouseX+points[i]->x)/divX,ribbonTexture.height, sin(i)*100);  
  
			glVertex3f(points[i]->x,points[i]->y+ribbonHeight, sin(i)*100);  
		}  
	  
	glEnd();  
	  
	glDisable(GL_TEXTURE_RECTANGLE_ARB);  
  
}  
  
  
  
//--------------------------------------------------------------  
  
void testApp::keyPressed  (int key){   
  
	  
  
}  
  
  
  
//--------------------------------------------------------------  
  
void testApp::keyReleased  (int key){   
  
	  
  
}  
  
  
  
//--------------------------------------------------------------  
  
void testApp::mouseMoved(int x, int y ){  
	mouseY=y;  
	mouseX=x;  
  
}  
  
  
  
//--------------------------------------------------------------  
  
void testApp::mouseDragged(int x, int y, int button){  
  
}  
  
  
  
//--------------------------------------------------------------  
  
void testApp::mousePressed(int x, int y, int button){  
  
}  
  
  
  
//--------------------------------------------------------------  
  
void testApp::mouseReleased(){  
  
  
  
}  
  

note: in ofImage.h the tex property must be moved into the public from protected for this to work

i just no realized that i didn’t exactly address what you were asking, but in my example i used the divx and divy values to map the texture to multiple quadstrip portions. if you wanted to have images of different sizes, you could just replace the line that has glTexCoord3f((mouseX+points[i]->x)/divX,ribbonTexture.height, sin(i)*100);

with

glTexCoord3f((mouseX+points[i]->x)/divX,[whatever height the image you’re up to on the mapping is], sin(i)*100);

and then add in some way to adjust the mapping based on whatever image you’re up to and the width of all the images[/b]

thank you very much, I had some first success with the same approach even though yours seems to be a little further than mine allready :slight_smile:

Hello again,

I unfortunately have a new problem. Since I am limited with the width of a texture I would still need to add more than one texture to the ribbon. But I can’t get a solution for that since as far as I know I can’t simply switch the texture between glBegin and glEnd.

I thought about using multitexturing but that does not make sense since I want to add each texture after each other and not at once. The only way I know is to fake the effect by drawing one ribbon for each texture and connect them with each other.
But that’s obviously not the best way when it comes to performance.

Is there any way to get this done?
thanks

Well, if you can’t batch more than one image per texture and you’re trying to use more images than available texture units per ribbon, then I guess the only way is to do like you say and split your drawing into batches.

Performance wise you will always take the hit for the state change (loading a new texture into a texture unit),but you might overcome that by putting all your vertex data into a single vertex array that is defined before you start drawing and passing only the vertex pointer and a list on indices to the draw command.

Here’s some info:

http://www.songho.ca/opengl/gl-vertexarray.html

Using vertex arrays, although bit more complicated than using immediate mode calls, is a good idea not only for performance (you can use them with VBO’s to cache static geometry on the hardware memory, for instance) but also because they are the only way to draw geometry on both OpenGL ES and future versions of OpenGL beyond OpenGL 3.

Cheers,
P.

so if I understand you right, you would make one array for all the vertex data and more arrays for the tex Coords.

then you would switch the pointer to the texture array after each texture like this:
glTexCoordPointer(2, GL_FLOAT, 0, tex2);

and draw the next part with:
glDrawRangeElements(…);

so you can attach more than just one texture onto the same array? and always draw the related parts of it by definig the correct range?

thats like I do it now but it would make me call glDrawRangeElements(); something between 3-10 times but also allows me to get up to 100 images in original resolution of 320x240 onto the ribbon.

is there a better way?