Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: multipass-multitexturing problem

  1. #1
    Junior Member Newbie
    Join Date
    Aug 2006
    Posts
    23

    multipass-multitexturing problem

    I have a hundred images I want to draw to an object. I have it working fine (albeit a bit slow) with only multipass. To speed things up I want to render them eight (for my card) at a time. However, when I do that only the first eight show. There seems to be a blending problem. One odd thing, I can render eight on the first pass and then one on each following pass.

    To recap these rendering patterns work:
    1,1,1,1,....1
    8,1,1,1,....1
    and this one doesn't
    8,8,8,....8,4

    I have very little experience with OpenGL so I can't tell if this likely to be a bug in my card or bug in my code. I feel my code is right and that there is a problem in my video card. What does it sound like to you guys? Is there a problem with combining mulitpass and multitexturing?

  2. #2
    Super Moderator OpenGL Lord
    Join Date
    Dec 2003
    Location
    Grenoble - France
    Posts
    5,655

    Re: multipass-multitexturing problem

    it is probably your code.
    What is your video card and driver / os ?

  3. #3
    Junior Member Newbie
    Join Date
    Aug 2006
    Posts
    23

    Re: multipass-multitexturing problem

    The card is an ATI 9800 pro. The driver version is 8.282.0.0. The driver date is 8/2/2006. The OS is Winsows XP.

    Here is my code. It's in Java using JOGL (Java's bindings for OpenGL). It should be easy to follow the OpenGL part though. Basically on the first pass I decal the textures and then on every pass after that I blend them. It only works if you set the numberOfTextures to 1 after the first pass.

    Code :
    	public void displayLayer(GL gl){
     
    		for(LandSurfaceShard shard:shards){
    			positionCamera(gl,shard.shardOffsetX,shard.shardOffsetY,shard.shardOffsetZ);
    			boolean shardDrawn=false;
    			boolean textureDrawn=false;
    			boolean firstPass=true;
    			int multiTextureCounter=0;
     
    			for(Survey survey:layer.getSurveyList()){
     
    				// .........Math removed..........
     
    				for(SurveyTile surveyTile:survey.getSurveyTileList()){
    					Boundary tileBoundary=surveyTile.getBoundary(survey.surveyX,survey.surveyY,survey.yAxisDegreesFromNorth,survey.surveyReferenceEarthRadius);
    					if(!shard.boundary.overlaps(tileBoundary)){
    						continue;
    					}
     
    					textureDrawn=false;
    					gl.glActiveTexture(GL_TEXTURE[multiTextureCounter]);
    					gl.glBindTexture(GL.GL_TEXTURE_2D,surveyTile.openGLImageName);
    					gl.glEnable(GL.GL_TEXTURE_2D);
     
    					if(firstPass){
    						gl.glDisable(GL.GL_BLEND);
    						gl.glTexEnvf(GL.GL_TEXTURE_ENV,GL.GL_TEXTURE_ENV_MODE,GL.GL_DECAL);
    					}else{
    						gl.glEnable(GL.GL_BLEND);
    						gl.glBlendFunc(GL.GL_SRC_ALPHA,GL.GL_ONE_MINUS_SRC_ALPHA);
    						gl.glTexEnvf(GL.GL_TEXTURE_ENV,GL.GL_TEXTURE_ENV_MODE,GL.GL_MODULATE);
    					}
     
    					gl.glEnable(GL.GL_TEXTURE_GEN_S);
    					gl.glEnable(GL.GL_TEXTURE_GEN_T);
     
    					gl.glTexGeni(GL.GL_S,GL.GL_TEXTURE_GEN_MODE,GL.GL_OBJECT_LINEAR);
    					gl.glTexGeni(GL.GL_T,GL.GL_TEXTURE_GEN_MODE,GL.GL_OBJECT_LINEAR);
     
    					// .........math removed...........
     
    					gl.glTexGendv(GL.GL_S,GL.GL_OBJECT_PLANE,sParametersBuffer);
    					gl.glTexGendv(GL.GL_T,GL.GL_OBJECT_PLANE,tParametersBuffer);
     
    					multiTextureCounter++;
     
    					if(multiTextureCounter==this.numberOfTextures){
    						shard.display(gl);   //this draws the polygons
     
    						for(int textureIndex=0;textureIndex<multiTextureCounter;textureIndex++){
    							gl.glActiveTexture(GL_TEXTURE[textureIndex]);
    							gl.glDisable(GL.GL_TEXTURE_2D);
    						}
     
    						firstPass=false;
    						textureDrawn=true;
    						shardDrawn=true;
    						multiTextureCounter=0;
    					}
    				}
     
    				if(!textureDrawn){
    					shard.display(gl);
     
    					for(int textureIndex=0;textureIndex<multiTextureCounter;textureIndex++){
    						gl.glActiveTexture(GL_TEXTURE[textureIndex]);
    						gl.glDisable(GL.GL_TEXTURE_2D);
    					}
     
    					firstPass=false;
    					multiTextureCounter=0;
    				}
    			}
     
    			if(!shardDrawn){
    				shard.display(gl);
     
    				for(int textureIndex=0;textureIndex<multiTextureCounter;textureIndex++){
    					gl.glActiveTexture(GL_TEXTURE[textureIndex]);
    					gl.glDisable(GL.GL_TEXTURE_2D);
    				}
    			}
     
    		}
     
    		gl.glFlush();
    	}

  4. #4
    Junior Member Newbie
    Join Date
    Aug 2006
    Posts
    23

    Re: multipass-multitexturing problem

    I managed to test this with a different video card and I got the same result. So I guess the problem is in the code and not the card.

    I have been looking around the web for examples of multipass-multitexture and I can't find any. I can only find examples that use only one technique or the other and not both at once. If anyone knows of an example could he please post the link.

  5. #5
    Senior Member OpenGL Guru zed's Avatar
    Join Date
    Jul 2000
    Location
    S41.16.25 E173.16.21
    Posts
    2,609

    Re: multipass-multitexturing problem

    it looks like you are using the fixed pipeline with 8 textures
    i believe most cards will only let u use 4 with that
    if u use shaders eg glsl or cg u can access more textures (normally at least 16)

  6. #6
    Super Moderator OpenGL Guru
    Join Date
    Feb 2000
    Location
    Montreal, Canada
    Posts
    4,421

    Re: multipass-multitexturing problem

    Originally posted by wgj000:
    I have a hundred images I want to draw to an object. I have it working fine (albeit a bit slow) with only multipass. To speed things up I want to render them eight (for my card) at a time. However, when I do that only the first eight show. There seems to be a blending problem. One odd thing, I can render eight on the first pass and then one on each following pass.
    Check to see how many texture units you have.
    It would be something with glGetInteger(GL_MAX_TEXTURE_UNITS) or something like that.
    ATI 9800 has 8 units for the fixed pipe.
    16 for shaders. Actually, I think all cards from 9500 and above are like that.
    ------------------------------
    Sig: http://glhlib.sourceforge.net
    an open source GLU replacement library. Much more modern than GLU.
    float matrix[16], inverse_matrix[16];
    glhLoadIdentityf2(matrix);
    glhTranslatef2(matrix, 0.0, 0.0, 5.0);
    glhRotateAboutXf2(matrix, angleInRadians);
    glhScalef2(matrix, 1.0, 1.0, -1.0);
    glhQuickInvertMatrixf2(matrix, inverse_matrix);
    glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
    glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);

  7. #7
    Junior Member Newbie
    Join Date
    Aug 2006
    Posts
    23

    Re: multipass-multitexturing problem

    I have 8 texture units. The variable this.numberOfTextures is determined from glGetInteger(GL_MAX_TEXTURE_UNITS). However, I can set it to whatever I want. It works if I set it to one. If fails if I set it to 2 or any other number. It also works if I set it to a number <=8 on the first pass and 1 for every other pass.

    There seems to be a lack of information on doing multipass and multitexturing at the same time on the web. My worry is that when I try use multiple textures the the behavior of the card changes and multipass blending doesn't work. But then maybe it's just more complicated then I thought. If anyone knows for sure that multipass and multitexture at the same time is possible it would be helpful to tell me so. At least that way I can keep plugging away at the problem with confidence that I will eventually figure it out.

  8. #8
    Junior Member Regular Contributor
    Join Date
    Jul 2005
    Location
    Berlin, Germany
    Posts
    188

    Re: multipass-multitexturing problem

    When you're switching from multipass to multitexture+multipass, you have to be careful to choose the correct texture environment functions to achieve the same end result. I'll demonstrate what i mean for three textures.

    With multipass only, using glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA), your result looks like this:

    Code :
      Variables:
        d  - destination (color value in framebuffer)
        ai - alpha value of texture i
        ti - color value of texture i
     
      d'   = (1-a1)d + a1*t1
      d''  = (1-a2)d' + a2*t2
           = (1-a2)((1-a1)d + a1*t1) + a2*t2
      d''' = (1-a3)d'' + a3*t3
           = (1-a3)((1-a2)((1-a1)d + a1*t1) + a2*t2) + a3*t3
    When you try to move to multitexture, you have to split out the input d, as you don't have acces to frame buffer values in the texturing stage:

    Code :
      d''' = (1-a3)(1-a2)(1-a1)d
           + (1-a3)(1-a2)a1*t1
           + (1-a3)a2*t2
           + a3*t3
    In this form, it can be implemented using a combination of blending and multitexturing. For example using the blend function glBlendFunc(GL_SRC_ALPHA, GL_ONE).

    In this case, you need your texturing stage to output

    Code :
      alpha = (1-a3)(1-a2)(1-a1)
      color = (1-a3)(1-a2)a1*t1
            + (1-a3)a2*t2
            + a3*t3
            = (1-a3)((1-a2)a1*t1 + a2*t2) + a3*t3
    To achieve this, you need the following texture unit setup:

    Code :
    Unit0:
      alpha = 1-alpha
      color = alpha*color
     
    Unit1:
      alpha = previous * (1-alpha)
      color = (1-alpha)*previous + alpha * color
     
    Unit2 and following use the same setup as unit1.
    355/113 -- Not the famous irrational number PI, but an incredible simulation!

  9. #9
    Junior Member Newbie
    Join Date
    Aug 2006
    Posts
    23

    Re: multipass-multitexturing problem

    All that makes sense. Correct me if I'm wrong, but doesn't that require that all the multitextuing take place in a single pass. I have too many textures to do in a single pass. I need to merge the new multitexture with the contents of the frame buffer. You say that during multitextuing I don't have access to the framebuffer values. This sound like what I'm trying to do is not possible. It that your understanding?

  10. #10
    Junior Member Regular Contributor
    Join Date
    Jul 2005
    Location
    Berlin, Germany
    Posts
    188

    Re: multipass-multitexturing problem

    No, you misunderstood. It is possible to combine multiple passes, it's just that when you have more than one texture per pass, you need to use different texture environments and blend functions.

    The texture unit setup i outlined above works for one or more textures per pass in one or more passes. The combination of GL_MODULATE and glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) only works for one texture per pass.

    Btw, i just realized that my solution discards the result of the lighting process. If you want to include that, you'll have to switch the last texture unit to

    Code :
      alpha = previous
      color = previous * primary
    This, of course, reduces the number of units available to merge textures by one.
    355/113 -- Not the famous irrational number PI, but an incredible simulation!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •