Anybody able to explain this

pretty straight forward question for the shader i set 2 textures(rockwall.tga,rockwall_normal.tga) and this doesn’t look like a rockwall al all.



almost seems like it pulled something from the jme class files. tell me if should post code and shaders but i don’t think it’s either of them because there all in the same folder rockwall.tga and rockwall_normal.tga are the only tga’s in the folder and same for the shaders and there isn’t anything unnormal about the code

Looks like missing texture or other texturestate problems - the texture of the fps text is used instead (the last texture that was active before drawing the quad). Any warnings about texture in the std err?

Oct 1, 2005 3:19:24 PM com.jme.app.BaseGame start
INFO: Application started.
Oct 1, 2005 3:19:24 PM com.jme.system.PropertiesIO <init>
INFO: PropertiesIO created
Oct 1, 2005 3:19:24 PM com.jme.system.PropertiesIO load
INFO: Read properties
Oct 1, 2005 3:19:27 PM com.jme.system.lwjgl.LWJGLDisplaySystem <init>
INFO: LWJGL Display System created.
Oct 1, 2005 3:19:28 PM com.jme.system.PropertiesIO save
INFO: Saved properties
Oct 1, 2005 3:19:28 PM com.jme.system.lwjgl.LWJGLDisplaySystem <init>
INFO: LWJGL Display System created.
Oct 1, 2005 3:19:30 PM com.jme.renderer.lwjgl.LWJGLRenderer <init>
INFO: LWJGLRenderer created. W:  640H: 480
Oct 1, 2005 3:19:30 PM com.jme.renderer.AbstractCamera <init>
INFO: Camera created.
Oct 1, 2005 3:19:30 PM com.jme.util.lwjgl.LWJGLTimer <init>
INFO: Timer resolution: 1000 ticks per second
Oct 1, 2005 3:19:30 PM com.jme.scene.Node <init>
INFO: Node created.
Oct 1, 2005 3:19:31 PM com.jme.scene.Node <init>
INFO: Node created.
Oct 1, 2005 3:19:31 PM com.jme.scene.Node attachChild
INFO: Child (FPS label) attached to this node (FPS node)
Oct 1, 2005 3:19:31 PM com.jme.scene.Node attachChild
INFO: Child (glslQuad) attached to this node (rootNode)





Oct 1, 2005 3:19:34 PM com.jme.app.SimpleGame cleanup
INFO: Cleaning up resources.
Oct 1, 2005 3:19:34 PM com.jme.app.BaseGame start
INFO: Application ending.
Press any key to continue...


not that I see

I've noticed that it doesn't necessarily tell you when it can't find a texture…maybe that's under certain circumstances though…



darkfrog

i'd post the code but my code isn't on this computer it's pretty straight forward i'll put in what i remember relating to it


Texture diffuse = TGALoader("rockwall.tga");
Texture normal = TGALoader("rockwall_normal.tga");
so.setUniform("TextureUnit0",diffuse);
so.setUniform("TextureUnit1",normal);//so being shader object
//also I changed my TGALoader code so it sends back a texture not a image
//A simple
Texture x =new Texture();
x.setImage(image);


I do not think it is a texture problem maybe how concert is the glsl shader object code? or it could be like you said a texture state problem but i never use texture state in my code so does that rule out texture state?

It looks like maybe you didn't call updateRenderState on that object.

what do you mean?

I mean exactly that.  :)  Do you call updateRenderState() on the spatial after setting it's texture?

I send a texture only to the shader object i never use a spatial anywhere in the program it's just a quad.  This is the glsl demo with my shaders and textures

Ok, sorry i didn't see this was a shader (didn't read carefully enough.)  Still, like was said above, it's obviously pulling from the font texture that is in use in your fps counter.  Thus it is likely referencing the active texture rather than the texture you pass in.  What does your shader look like?

bump2.vert

varying vec2 texCoord;
varying vec3 direction;
varying vec3 halfVec;


uniform vec3 cameraPos;
uniform vec3 lightPos;

void main()
{
   // Transform to clip space and save texture coord.
   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
   texCoord = gl_MultiTexCoord0.xy;

   // Calculate light direction.
   vec3 lightDir = normalize(vec3(lightPos-gl_Vertex.xyz));

   // Save a copy of the s tangent which was sent through the color (glColor3f).
   vec3 color = gl_Color.xyz;

   // Calculate the binormal as the cross between tangent and normal.
   vec3 binormal = cross(color, gl_Normal);
  
   // Create the matrix used to convert the light direction to texture space.
   mat3 tbnMatrix = mat3(color, binormal, gl_Normal);

   // Convert light direction to texture space.
   direction = tbnMatrix * lightDir;
   halfVec=direction+cameraPos;
}


bump2.frag

varying vec2 texCoord;
varying vec3 direction;
varying vec3 halfVec;


uniform sampler2D TextureUnit0;
uniform sampler2D TextureUnit1;


void main()
{
   vec3 decalCol = texture2D(TextureUnit0, texCoord).xyz;
  
  
   // Most image editors will save color values in the 0 to 1 (0 to 255).
   // But our normals can be from -1 to 1 (-255 to 255) so we must expand it out.
   // From its clamped version like so...
   vec3 normal =  2.0 * (texture2D(TextureUnit1, texCoord).rgb - 0.5);
   vec3 lightDir=normalize(direction);
   // Normalize the light direction on a per pixel level.
   vec3 halfAngle=normalize(halfVec);

   float diffuse = dot(normal, lightDir);
   float specular = dot(normal, halfAngle);

   float specFactor = specular * specular;
   specular = specFactor * specFactor;
   specFactor = specular * specular;

   // To make things simple I hardcoded material values but we could have passed
   // these as uniform parameters.
   vec3 dMat = vec3(0.8, 0.8, 0.8);
   vec3 sMat = vec3(0.8, 0.8, 0.8);
   float ambient = 0.4;

   // Combine the decal with the bump value.
   gl_FragColor.xyz = decalCol * (dMat * (ambient + diffuse) + sMat * specFactor);
}

Hmm, how do you load your textures?  The code you typed in from memory that uses TGALoader is invalid.  I'm wondering if the texture's id was not yet set when you add it to the shader object.

TGALoader code

   public static Texture TGALoader(String filename)throws IOException
   {
      Image image= new Image();
      FileInputStream fis;
   
      
         fis= new FileInputStream(filename);
         image=TGALoader.loadImage(fis);
      

      Texture texture=new Texture();
      texture.setImage(image);
      return texture;
   }

Yep, that's the problem.  When you set the Texture on the ShaderObject, it copies the texture id.  If you use TextureManager to load your texture, it is preloaded into GL and an id is obtained.  Your loader does not do this, so no valid id is set on the ShaderObject.

soooo what should i do have it send back an Image and use TextureManager?

That should work, yes.

I don't see how Texture Manager could help there aren't any methods to send back a texture from a jme image do you mean TextureState by any chance?

No, I didn't.  I was thinking awt Image as you might have guessed from looking at TextureManager.  Or you could have a look at what TextureManager does to a Texture to ensure an id is created.  In any case, we should add a check in the GLSL code to ensure set Textures do not have invalid ids.

guess i could use Texture.getTextureId to get the valid ID of it. what ID off the top of your head do you think i should get?  And the as for the GLSL code well it's also pretty straight forward i think this is a flaw in jme but heres the code


    private Quad createBrickQuad() {
        GLSLShaderObjectsState so = display.getRenderer()
                .createGLSLShaderObjectsState();

        // Check is GLSL is supported on current hardware.
        if (!so.isSupported()) {
            display.close();
            System.exit(0);
        }
        diffused=TGALoader("rockwall.tga");
        normal=TGALoader("rockwall_normal.tga");
        Texture d=new Texture();
        Texture t=new Texture();
        d.setImage(diffused);
        t.setImage(normal);
       
      File f=null,v=null;
      URL frag=null,vert=null;
      try
      {
         f=new File("bump.frag");
         frag=f.toURL();
         v=new File("bump.vert");
         vert=v.toURL();
      }
      catch(MalformedURLException e)
      {
         System.out.println("error line 52");
      }
        so.load(vert,frag);
        so.setUniform("lightPos", 0.0f, 0.0f, 4.0f);
        Vector3f camPos=cam.getDirection();
        so.setUniform("cameraPos",camPos.x,camPos.y,camPos.z);
        TextureState ts = display.getRenderer().createTextureState();
        so.setUniform("TextureUnit0",d);
        so.setUniform("TextureUnit1",t);
        so.setEnabled(true);

        //Generate the torus
        Quad box = new Quad("glslQuad", 1f, 1f);
        box.setRenderState(so);

        return box;
    }

I don't think you understand.  Each texture has a field for texture id.  This value is normally filled in after the texture has been used in drawing a scene at least once. (this is because OpenGL has to be queried for the next id to use, you can't just make it up yourself.)  So if you create it by hand in your init method, it has not aquired a texture id yet.  Therefore, when you pass the Texture as a Shader uniform, it has an invalid texture id and does not work.



Using TextureManager instead of your custom made TGA loader would help because TextureManager automatically makes a temporary TextureState, puts the texture into it, and applies the state in order to force an id to be generated for that texture.  This also allows us to more efficiently cache textures and a few other benefits (like preloading textures, etc.)  The important part though is that it sets the id for you by the aforementioned applying of the texture.