Multitexture with a shader

Hi, I’m new to OF and quite rusty in OpenGL so I may be doing something silly here… but I’m trying to do a simple multitexture shader and not getting anywhere. Here’s my code:

main.cpp

  
  
#include "ofMain.h"  
#include "testApp.h"  
#include "ofAppGlutWindow.h"  
  
//========================================================================  
int main()  
{  
	ofAppGlutWindow window;  
	ofSetupOpenGL(&window, 512, 512, OF_WINDOW);  
	ofRunApp(new testApp());  
}  
  

testApp.h

  
  
#pragma once  
  
#include "ofMain.h"  
  
class testApp : public ofBaseApp  
{  
	  
public:  
	void setup();  
	void draw();  
  
private:  
	ofShader shader;  
	ofImage image1;  
	ofImage image2;  
};  
  

test.cpp

  
  
#include "testApp.h"  
  
//--------------------------------------------------------------  
void testApp::setup()  
{  
	ofSetLogLevel(OF_LOG_VERBOSE);  
	ofBackground(0, 0, 0);  
	ofSetVerticalSync(false);  
	ofEnableAlphaBlending();  
  
	shader.load("multitexture");  
	image1.loadImage("image1.png"); // 512x512 image  
	image2.loadImage("image2.png"); // 512x512 image  
}  
  
//--------------------------------------------------------------  
void testApp::draw()  
{  
	const int fWidth = ofGetWidth();  
	const int fHeight = ofGetHeight();  
  
	shader.setUniformTexture("tex0", image1, 0);  
	shader.setUniformTexture("tex1", image2, 1);  
	shader.begin();  
  
	glBegin(GL_QUADS);  
	glTexCoord2f(0, 0);			glVertex3f(0, 0, 0);  
	glTexCoord2f(fWidth, 0);		glVertex3f(fWidth, 0, 0);  
	glTexCoord2f(fWidth, fHeight);	glVertex3f(fWidth, fHeight, 0);  
	glTexCoord2f(0, fHeight);		glVertex3f(0, fHeight, 0);  
	glEnd();  
  
	shader.end();  
}  
  

multitexture.vert

  
  
#version 120  
  
varying vec2 texCoord;  
  
void main()  
{  
	texCoord = vec2(gl_MultiTexCoord0);  
	gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;  
}  
  

multitexture.frag

  
  
#extension GL_ARB_texture_rectangle : enable  
  
varying vec2 texCoord;  
uniform sampler2DRect tex0, tex1;  
  
void main()  
{  
	if (texCoord.x < 512.0/2.0)  
		gl_FragColor = texture2DRect(tex0, texCoord);  
	else  
		gl_FragColor = texture2DRect(tex1, texCoord);  
}  
  

I expect this to draw an image over the full size of the output window (512x512) where the left half is image1 and the right is image2. I actually get just image1. It’s like both the tex0 and tex1 samplers have the same texture bound to them. I get no errors in the console (so the shader is loading/compiling fine), I’m using 007 and my GPU can definitely multitexture.

Any ideas?

You’re really close, you just need to bind() both of those textures before using them in the shader, and also pass the textureID into setUniformTexture()

  
  
    image1.bind();  
    image2.bind();  
          
    shader.begin();   
    shader.setUniformTexture("tex0", image1, image1.getTextureReference().getTextureData().textureID);    
    shader.setUniformTexture("tex1", image2, image2.getTextureReference().getTextureData().textureID);     
  
    glBegin(GL_QUADS);    
    glTexCoord2f(0, 0);         glVertex3f(0, 0, 0);    
    glTexCoord2f(fWidth, 0);        glVertex3f(fWidth, 0, 0);    
    glTexCoord2f(fWidth, fHeight);  glVertex3f(fWidth, fHeight, 0);    
    glTexCoord2f(0, fHeight);       glVertex3f(0, fHeight, 0);    
    glEnd();  
      
    shader.end();    
      
    image1.unbind();  
    image2.unbind();  
  
  

before you can use them in your texture and make sure to unbind() them when you’re done.

Thanks for the reply, I have it working now :slight_smile:

  
  
	shader.begin();  
	shader.setUniformTexture("tex0", image1, image1.getTextureReference().getTextureData().textureID);  
	shader.setUniformTexture("tex1", image2, image2.getTextureReference().getTextureData().textureID);  
  
	glBegin(GL_QUADS);  
	glTexCoord2f(0, 0);				glVertex3f(0, 0, 0);  
	glTexCoord2f(fWidth, 0);		glVertex3f(fWidth, 0, 0);  
	glTexCoord2f(fWidth, fHeight);	glVertex3f(fWidth, fHeight, 0);  
	glTexCoord2f(0, fHeight);		glVertex3f(0, fHeight, 0);  
	glEnd();  
  
	shader.end();  
  

I’d tried using the textureID before with no success but I was missing the key step of putting shader.begin() before setting any shader parameters!

I’ve left out the bind/undbind because I’m not sure I see the need for them. Looking at the code for setUniformTexture() I see that it already does the same thing as bind() anyway - at least the important glEnable/glBindTexture part. So for now I’m missing the unbind() call… hmm.

Use gl_FragCoord.xy? Your shader is operating in screen space.

  
  
if(gl_FragCoord.x > 512) gl_FragColor = texture2DRect(tex0, texCoord);    
  

You may have to do some scaling of your textcoords and screen coords.