TEXTURED MESH SHADER PROBLEM!!!

Hello i want to texture a 640*480 mesh with a 640*480 image…but somehow the texture seems to be always quadratic. In order to so i use a shader.

TestApp - Source




ofShader shader;
ofImage colormap, bumpmap;
ofMesh mainMesh;
ofImage texImage;

void testApp::setup(){

ofDisableArbTex();
shader.load(“displace.vert”, “displace.frag”);

int width = 640;
int height = 480;
texImage.allocate(width,height,ofImageType::OF_IMAGE_COLOR);
texImage.loadImage(“art.jpg”);

mainMesh.setMode(OF_PRIMITIVE_TRIANGLE_STRIP);

//add one vertex to the mesh for each pixel
for (int y = 0; y < height; y++){
for (int x = 0; x<width; x++){
mainMesh.addVertex(ofPoint(x,y,0)); // mesh index = x + y*width
mainMesh.addTexCoord(ofVec2f((float)x/float(width),(float)y/float(height)));
}
}
}

void testApp::update() {
}
void testApp::draw(){

ofBackground(0);
ofSetColor(255,255,255);

shader.begin();
shader.setUniformTexture(“colormap”, texImage.getTextureReference(), 1);
mainMesh.drawVertices();
shader.end();
}





Fragment Shader


uniform sampler2D colormap;
varying vec2 TexCoord;
varying vec4 color;

void main(void) {
gl_FragColor = texture2D(colormap,TexCoord.st);
}


Vertex Shader


uniform sampler2D colormap;

varying vec2 TexCoord;
varying vec4 color;

void main(void) {
TexCoord = gl_MultiTexCoord0.st;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}


if someone please could take the time and look at this issue - it would be very nice…Please help a brother out!!!
Everything looks so right to me - i feel stupid! AAAH

Thank you very much and sorry for all the code - stuff

Mio

Depending on what you plan on doing, you don’t need to use a shader to texture a mesh.

You don’t need to set a vertex for every pixel, you can just use a minimal set that defines the shape you want, then in the fragment shader use gl_FragCoord.xy which will give you the per pixel coordinate. If you are using normalized tex coords [0,1] you will need to normalize the FragCoords for the texture lookup. just pass in the dimensions as a vec2 uniform and go vec2 texcoords = gl_FragCoord.xy / dims

But this is how you could do it and skip the shader

  
  
void testApp::setup(){  
      
    ofEnableNormalizedTexCoords();  
      
    int width = 640;  
    int height = 480;  
    texImage.loadImage("art.jpg");  
    texImage.resize(width, height);  
      
    mainMesh.setMode(OF_PRIMITIVE_TRIANGLE_STRIP);  
      
    mainMesh.addVertex(ofPoint(0, 0, 0));  
    mainMesh.addTexCoord(ofVec2f(0, 0));  
    mainMesh.addVertex(ofPoint(width, 0, 0));  
    mainMesh.addTexCoord(ofVec2f(1, 0));  
    mainMesh.addVertex(ofPoint(0, height, 0));  
    mainMesh.addTexCoord(ofVec2f(0, 1));  
    mainMesh.addVertex(ofPoint(width, height, 0));  
    mainMesh.addTexCoord(ofVec2f(1, 1));  
  
}  
  
void testApp::draw(){  
  
    texImage.getTextureReference().bind();  
    mainMesh.draw();  
    texImage.getTextureReference().unbind();  
      
}  
  
  

if you want to use un-normalized coordinates, comment out the ofEnableNormalizedTexCoords() line and in the mesh setup, use width/height variables instead of 1’s for the tex coords

wow that does look very nice and yes it works…thank you very much for taking the time.

However there is still a problem…for my purpose i need to draw a vert for each pixel cause i want to deform each vert in the vertex shader…but somehow trying your hints didnt worked…i just dont get it.

i tried your ofEnableNormalizedTexCoords(); which i didnt know of before. but still its quadratic. As soon as i try the mesh with your four verts everything is cool. but not with verts for each pixel…

do you have an idea what this could be related to? i mean where is the difference between our codes…except the vert resolution? im lost!!! AAAAH

hey no problem, i found this stuff really confusing as well.

Your mesh is set to make triangles, but I think the way you are generating the vertexes isn’t really making triangles. Try using

mainMesh.setMode(OF_PRIMITIVE_POINTS);

So your vertexes will be points rather than connected triangle vertexes that give faces. Since you are setting one per pixel it should look the same

hmm thats just crazy … i tried it but still no success…

see when i try this in fragment shader:

gl_FragColor = vec4(TexCoord.s,0,0,1);

i will get a nice gradient in color red…going from black to full red…which shows the full 640*480 map…however when i add the color of the image with texture2D… then i get the image in weird dimensions…so somehow it seems to be related to the way the image itself is set in texture coords. what could be wrong there?

When you have arb disabled, I think your texture will be resized to a power of 2 by oF in the background. So your texcoords might be wrong cause you have x/640 whereas with the automatic resizing everything should be relative to a power of 2 size. Or something. It confuses me still what exactly happens when Arb is disabled.

This works for me with Arb on.

  
  
void testApp::setup(){  
      
    shader.load("displace.vert", "displace.frag");  
      
    int width = 640;  
    int height = 480;  
    texImage.loadImage("art.jpg");  
    texImage.resize(width, height);  
      
    mainMesh.setMode(OF_PRIMITIVE_POINTS);  
      
  
//    //add one vertex to the mesh for each pixel  
    for (int y = 0; y < height; y++){  
        for (int x = 0; x<width; x++){  
            mainMesh.addVertex(ofPoint(x,y,0));   // mesh index = x + y*width  
            mainMesh.addTexCoord(ofVec2f(x, y));  
        }  
    }  
}  
  
//--------------------------------------------------------------  
void testApp::draw(){  
  
    shader.begin();  
    shader.setUniformTexture("colormap", texImage.getTextureReference(), 1);  
    mainMesh.drawVertices();  
    shader.end();  
  
}  
  
frag shader:  
  
uniform sampler2DRect colormap;  
varying vec2  TexCoord;  
varying vec4 color;  
  
void main(void) {  
    gl_FragColor =  texture2DRect(colormap, TexCoord.st);  
}  
  
  

if you really need arb off, try and make your image/mesh power of 2 sized, then when you draw maybe use ofScale(640/1024.0, 480/512.0);

This seems to work but I dont really know if its the right way to do it:

  
  
void testApp::setup(){  
      
    ofDisableArbTex();  
    shader.load("displace.vert", "displace.frag");  
      
    int width = ofNextPow2(640);  
    int height = ofNextPow2(480);  
    texImage.loadImage("art.jpg");  
    texImage.resize(width, height);  
      
    printf("tex dim %0.f %0.f\n", texImage.getWidth(), texImage.getHeight());  
      
    mainMesh.setMode(OF_PRIMITIVE_POINTS);  
      
//    //add one vertex to the mesh for each pixel  
    for (int y = 0; y < height; y++){  
        for (int x = 0; x<width; x++){  
            mainMesh.addVertex(ofPoint(x,y,0));   // mesh index = x + y*width  
            mainMesh.addTexCoord(ofVec2f((float)x/float(width),(float)y/float(height)));  
        }  
    }  
}  
  
void testApp::draw(){  
  
    ofPushMatrix();  
    ofScale(640/1024.0, 480/512.0);  
    shader.begin();  
    shader.setUniformTexture("colormap", texImage.getTextureReference(), 1);  
    mainMesh.drawVertices();  
    shader.end();  
    ofPopMatrix();  
      
}  
  
frag shader  
  
uniform sampler2D colormap;  
varying vec2  TexCoord;  
varying vec4 color;  
  
void main(void) {  
    gl_FragColor =  texture2D(colormap,TexCoord.st);  
}  
  

Maybe someone who understands arb on/off better can help say what is going on

Hey pants - thx so much for looking at it - but still no success…

you first version with Arb on…doesnt show me anything…codewise it looks like everything is included that i need…to displace each vert in shader…

but all i get is a black image…

the arb off version works fine for me …
even though im not sure if this scaling thing is the way to go for…

Im still curious … all i try is to use a shader to texture a Mesh with an image…shouldnt this be a total basic…Im not getting it…i have done so with other objects and its all good…im getting crazy!!! lol

Please if someone see the mistake help me out!!!

pants…you are- right!!!

it is definitly about the powof2 thing…so my texture is 640*480 but on gpu the texture is next pow of two for x and y - which is 1024 * 512;

to fix this i wrote a shader based mixture of what pants already described;

//--------------------------------------------------------------
//--------------------------------------------------------------
//--------------------------------------------------------------
ofMesh mainMesh;
ofImage texImage;

float powOfTwoX;
float powOfTwoY;
//--------------------------------------------------------------
void testApp::setup(){

shader.load(“displace.vert”, “displace.frag”);

ofDisableArbTex();

int width = 640;
int height = 480;

powOfTwoX=(float)ofNextPow2(width)/float(width);
powOfTwoY=(float)ofNextPow2(height)/float(height);

texImage.allocate(640,480,ofImageType::OF_IMAGE_COLOR);
texImage.loadImage(“art.jpg”);

mainMesh.setMode(OF_PRIMITIVE_POINTS);

for (int y = 0; y < height; y++){
for (int x = 0; x<width; x++){
mainMesh.addVertex(ofPoint(x,y,0)); // mesh index = x + y*width
mainMesh.addTexCoord(ofVec2f((float)x/(float)width, (float)y/(float)height));
}
}

}

//--------------------------------------------------------------
void testApp::update() {

}
//--------------------------------------------------------------
void testApp::draw(){
shader.setUniformTexture(“colormap”, texImage.getTextureReference(), 1);
shader.begin();
shader.setUniform1f(“resXPow2”,powOfTwoX);
shader.setUniform1f(“resYPow2”,powOfTwoY);
mainMesh.draw();
shader.end();
}
//--------------------------------------------------------------
//--------------------------------------------------------------
//--------------------------------------------------------------
Vertex shader
//--------------------------------------------------------------
//--------------------------------------------------------------
uniform sampler2D colormap;

uniform float resXPow2;
uniform float resYPow2;

varying vec2 Coord;
varying vec2 TexCoord;
varying vec4 color;

void main(void) {

Coord = gl_MultiTexCoord0.st;
TexCoord.x = Coord.x/resXPow2;//resXPow2;
TexCoord.y = Coord.y/resYPow2;

color = texture2D(colormap,TexCoord.st);
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

propably not the most elegant solution but works perfect!!! …btw. Texcoord references the place on the texture - Coord is the corresponding position on the vertex of the mesh…

Thank you so much