Multitexture in GLSL #150

Any examples of multi texturing (or accessing texture coordinates in general) in GLSL #150 where gl_TexCoord has been depreciated?

when you declare a texture cordinates input you can provide for an array:

in vec2 in_coord[NUM_TEX];
out vec2 out_coord[NUM_TEX];

void main(){
       out_coord[0]=in_coord[0];
       out_coord[1]=in_coord[1];
       out_coord[2]=in_coord[2];
       ....
}
1 Like

I’m still having trouble accessing the second the texture. The first texture is used to map a point sprite, the second is used to set the color, but, all I’m getting is black, any idea what’s wrong?

In C++:

int main( ){
    ofGLWindowSettings settings;
    settings.setGLVersion(3, 2);  // Programmable pipeline
    settings.width = 690;
    settings.height = 460;
    ofCreateWindow(settings);
    ofRunApp( new ofApp());

}

ofImage img;

//--------------------------------------------------------------
void ofApp::setup() {
    
    // OPENGL STATES
    ofSetBackgroundAuto(false);
    ofSetVerticalSync(true);
    ofEnableAlphaBlending();
    ofEnableBlendMode(OF_BLENDMODE_ALPHA);
    
    img.load("ocean2.jpg");
    
    mMesh.setUsage(GL_DYNAMIC_DRAW);
    mMesh.setMode(OF_PRIMITIVE_POINTS);
  
    
    if (ofIsGLProgrammableRenderer()) {
        //mShader.load("", "shaders/myShader/myShader.frag");
        mShader.load("shaders/shaderGL3/Billboard");
        ofLogNotice("Using OpenGL3");
    } else {
        //mShader.load("", "shaders/myShader.frag");
        mShader.load("shaders/shaderGL2/Billboard");
        ofLogNotice("Using OpenGL2");
    }
    
    ofDisableArbTex();
    texture.load("dot.png");
    
    ofBackground(0.0, 0.0, 0.0);

}

//--------------------------------------------------------------
void ofApp::update() {
 
}

//--------------------------------------------------------------
void ofApp::draw(){
    
    /* ALPHA BlENDING */
    ofSetColor(ofColor(255.0));
    ofDrawRectangle(0, 0, ofGetWidth(), ofGetHeight());

    
    ofPushMatrix();
    ofTranslate(ofGetWidth()/2, ofGetHeight()/2);
    mShader.begin();
    ofEnablePointSprites();
    mShader.setUniform1f("rotation", rotateAccelX);
    mShader.setUniform1f("rotationY", rotateAccelY);
    mShader.setUniformTexture("tex0", texture.getTexture(), 1);
    mShader.setUniformTexture("tex1", img.getTexture(), 2);
    mMesh.draw();
    ofDisablePointSprites();
    mShader.end();
    ofPopMatrix();
  
}

Vert:

#version 150

uniform mat4 orientationMatrix;
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
uniform mat4 textureMatrix;
uniform mat4 modelViewProjectionMatrix;

uniform sampler2D tex0;
uniform sampler2D tex1;

uniform float rotation = 1.0;
uniform float rotationY = 1.0;

in vec4  position;
in vec4  color;
in  vec2 texcoord;
out vec2 texCoordVarying;



mat4 rotationMatrix(vec3 axis, float angle)
{
    axis = normalize(axis);
    float s = sin(angle);
    float c = cos(angle);
    float oc = 1.0 - c;
    
    return mat4(oc * axis.x * axis.x + c,           oc * axis.x * axis.y - axis.z * s,  oc * axis.z * axis.x + axis.y * s,  0.0,
                oc * axis.x * axis.y + axis.z * s,  oc * axis.y * axis.y + c,           oc * axis.y * axis.z - axis.x * s,  0.0,
                oc * axis.z * axis.x - axis.y * s,  oc * axis.y * axis.z + axis.x * s,  oc * axis.z * axis.z + c,           0.0,
                0.0,                                0.0,                                0.0,                                1.0);
}

void main() {
	vec3 axis = vec3(1.0, 0.0, 0.0);
	vec3 axisY = vec3(0.0, 0.0, 1.0);
	vec4 pos = projectionMatrix * modelViewMatrix * rotationMatrix(axis, rotation*1.0*gl_VertexID) * rotationMatrix(axisY, rotationY*1.0*gl_VertexID) * position;
	gl_Position = pos; 
	gl_PointSize = 10.0;
	texCoordVarying = texcoord;
}

Frag:

#version 150

uniform sampler2D tex0;
uniform sampler2D tex1;
                
in vec2 texCoordVarying;
out vec4 fragColor;

void main (void) {	 
	vec4 rTxt = texture(tex0, gl_PointCoord)*texture(tex1, texCoordVarying);
	fragColor = rTxt;
}

This is the image I’m trying to map to the point sprite (It’s just a white ring so you can’t see it here…):

This is the image I’m trying to sample to get colors:

In your fragment shader you don’t refer to tex1 only tex0 - is that the issue maybe?

Theo

Whoops, switched it, but, still only seeing black. When I remove * texture(tex1, out_coord[1]) I can see the texture, but when I add it back in everything turns black.

What if you use the same texture coordinate for tex1?

Also sometime the texture id can be funny instead of 1 and 2 when you pass the textures to the shader try 5 and 6

For debugging it might be good to not even load the vert shader and just use the default provided texture coordinate to see if both textures are coming through.

Thank you for the suggestions!

What if you use the same texture coordinate for tex1?

Which texture coordinate?

Also sometime the texture id can be funny instead of 1 and 2 when you pass the textures to the shader try 5 and 6

So, do you mean? Or something else?
uniform sampler2D tex5;
uniform sampler2D tex5;

For debugging it might be good to not even load the vert shader and just use the default provided texture coordinate to see if both textures are coming through.

How will I be able to tell if the textures are coming through? I’m passing them as a uniform, so, wouldn’t they still show up even if the vertex shader is out?

as suggested by Mr. theo, try using the coordinates of the first texture to ensure it is a plot problem…

Hmmm, I tried using the coordinates of the first texture and it didn’t work. The only texture I’ve gotten to work so far is when I use the first texture as a point sprite. What do you mean a “plot” problem?

Change texture location in shader begin() and shader.end()
should be:

mShader.setUniformTexture("tex0", texture.getTexture(), 0);
mShader.setUniformTexture("tex1", img.getTexture(), 1);

Sometimes the texture location can need to be different ( usually when rendering to an fbo )

so it might be also worth trying:

mShader.setUniformTexture("tex0", texture.getTexture(), 5);
mShader.setUniformTexture("tex1", img.getTexture(), 6);

This is a minimal test ( don’t load the .vert shader only the .frag shader )

You can do that by not passing a file for the .vert argument.

mShader.load("", "shaders/myShader.frag");

Maybe make the two textures/images be easy to recognize images so you can tell when they are both drawing.

uniform sampler2D tex0;
uniform sampler2D tex1;

void main (void) {	 
	vec2 st	= gl_TexCoord[0].st;
	vec4 rgbaPix0 = texture(tex0,st);
	vec4 rgbaPix1 = texture(tex1,st);
	fragColor = rgbaPix0 * 0.5 + rgbaPix1 * 0.5;
}

This is pretty confusing, I switched the numbers from (1,2) to (0,1) and nothing seems to have changed. The mapped texture is still showing up but I still can’t get the color texture.

This doesn’t seem to have an effect either. No matter what value I set the textures to, I have no trouble accessing the first one as tex0 and cannot seem to access tex1…

Hey I’m using #150, so I don’t have access to gl_TexCoord, how can I get the coordinates?

Is there some rule where you can’t send two textures that aren’t the same dimensions? Or something equally as dumb? To re-iterate what I’m trying to do, I want one texture to basically map to a point sprite (the same texture for each vertex) and the other texture I want to sample on a per vertex level to get a corresponding color from a texture. Do I need two shaders to do this?

sorry, not having the complete code is difficult to understand the problem.

in any case here is an example of multi texture:

#include "ofMain.h"

#define str(A) #A

class ofApp : public ofBaseApp
{
        public:
        ofImage img1;
        ofImage img2;
        ofShader shader;
        ofEasyCam cam;

        void setup(){
                ofDisableArbTex();
                string version = "\n#version 150\n";

                string frag = str(
                    uniform sampler2D texMap1;
                    uniform sampler2D texMap2;

                    out vec4 fragColor;
                    in vec2 texCoordVarying;

                    void main() {
                        vec4 T1  = texture(texMap1,texCoordVarying);
                        vec4 T2  = texture(texMap2,texCoordVarying);

                        fragColor = T1*T2;
                    }
                );

                string vert = str(
                    uniform mat4 modelViewProjectionMatrix;

                    in  vec4 position;
                    in  vec2 texcoord;
                    out vec2 texCoordVarying;

                    void main() {
                        gl_Position = modelViewProjectionMatrix * position;
                        texCoordVarying = texcoord;
                    }
                );

                shader.setupShaderFromSource(GL_VERTEX_SHADER,  version+vert);
                shader.setupShaderFromSource(GL_FRAGMENT_SHADER,version+frag);
                if(ofIsGLProgrammableRenderer()) {
                    shader.bindDefaults();
                }
                shader.linkProgram();

                img1.load("img.jpg");
                img2.load("img1.jpg");
        }

        void update(){

        }
        void draw(){
                ofEnableDepthTest();
                cam.begin();
                shader.begin();
                shader.setUniformTexture("texMap1",img1.getTexture(),1);
                shader.setUniformTexture("texMap2",img2.getTexture(),2);

                shader.setUniformMatrix4f("modelViewProjectionMatrix",cam.getModelViewProjectionMatrix());

                ofDrawSphere(300);

                shader.end();
                cam.end();
                ofDisableDepthTest();
        }
};

int main(){
        ofGLWindowSettings s;
        s.setGLVersion(3, 2);
        s.width=1366;
        s.height=768;
        ofCreateWindow(s);
        ofRunApp( new ofApp() );
}

1 Like

Ok, I added more of my code and the textures I’m trying to sample. let me know if you need any more info.