Author Topic: Applying multitexture to single poly in object  (Read 9954 times)

Offline rolz

  • float
  • ****
  • Posts: 280
  • Technocrat
    • View Profile
Applying multitexture to single poly in object
« on: December 26, 2005, 05:01:16 pm »
Helge,


We've got object3d.setTexture(TextureInfo) method that works just fine, but is it by any way possible to apply multitexture to a single poly ? like
PolygonManager.setPolygonTexture(polyId, textureInfo) ?
Regards,
Andrei

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11776
    • View Profile
    • http://www.jpct.net
Applying multitexture to single poly in object
« Reply #1 on: December 26, 2005, 05:02:56 pm »
Not yet. I'll add it in a future release.

Offline rolz

  • float
  • ****
  • Posts: 280
  • Technocrat
    • View Profile
Applying multitexture to single poly in object
« Reply #2 on: December 26, 2005, 05:49:25 pm »
Ok, thanks.  

Helge, another quick thing - is there a way to disable tiling for specific layer in TextureInfo ?
Regards,
Andrei

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11776
    • View Profile
    • http://www.jpct.net
Applying multitexture to single poly in object
« Reply #3 on: December 27, 2005, 06:11:32 pm »
Quote from: "rolz"
Helge, another quick thing - is there a way to disable tiling for specific layer in TextureInfo ?
No. Do you really need that?

Offline rolz

  • float
  • ****
  • Posts: 280
  • Technocrat
    • View Profile
Applying multitexture to single poly in object
« Reply #4 on: December 27, 2005, 07:28:49 pm »
Well, let's say i have a small texture i want to place over a polygon - a blood stain, a shadow - it is expected that texture image is smaller than the polygon to which i plan to apply it.  
After applying the texture, it is tiled all over the polygon - repeated several times. I thought it would be great to have a way to somehow handle tiling, as per this case.

p.s. another example - the "shadow" texture could occupy more than 1 polygon -  let's say it occupies 1 entire polygon and partially several adjacent polygons. With tiling, "shadow" is placed fine on one polygod and is tiled across these "partially occupied" polygons.
Regards,
Andrei

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11776
    • View Profile
    • http://www.jpct.net
Applying multitexture to single poly in object
« Reply #5 on: December 27, 2005, 07:31:44 pm »
I see...I'll have a look at it next year... :wink:

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11776
    • View Profile
    • http://www.jpct.net
Applying multitexture to single poly in object
« Reply #6 on: January 03, 2006, 07:32:55 pm »
Here you go: *edit: download removed!*
It includes both changes, i.e. an extended setPolygonTexture(...) in the PolygonManager and the possibility to set a texture to clamping mode. In OpenGL, this is bound to the texture, so i had to add the method to Texture too, albeit i'm not really happy with that. Anyway...i hope i haven't broken anything else as i haven't tested this version very much. Here's some example code, that moves a decal over a plane using multi texturing only:

Code: [Select]
import com.threed.jpct.*;
import org.lwjgl.opengl.*;
import java.awt.event.*;
import com.threed.jpct.util.*;

public class MTMove {

  public static void main(String[] args) throws Exception {
    MTMove mt = new MTMove();
    mt.doIt();
  }

  private void doIt() throws Exception {
    FrameBuffer fb=new FrameBuffer(640, 480, FrameBuffer.SAMPLINGMODE_HARDWARE_ONLY);
    fb.disableRenderer(IRenderer.RENDERER_SOFTWARE);
    fb.enableRenderer(IRenderer.RENDERER_OPENGL);

    World w=new World();
    w.setAmbientLight(255,255,255);

    TextureManager tm=TextureManager.getInstance();
    Texture base=new Texture("base.jpg");
    Texture decal=new Texture("decal.jpg");

    tm.addTexture("base", base);
    tm.addTexture("decal", decal);

    decal.enableGLClamping();

    int bid=tm.getTextureID("base");
    int did=tm.getTextureID("decal");

    Object3D plane=new Object3D(9);
    plane.setCulling(Object3D.CULLING_DISABLED);

    TextureInfo tInf1 = new TextureInfo(bid, -1, -1, 2, -1, -1, 2);
    tInf1.add(did, -1, -1, 2, -1, -1, 2, TextureInfo.MODE_ADD);
    TextureInfo tInf2 = new TextureInfo(bid, 2, -1, 2, 2, -1, 2);
    tInf2.add(did, 2, -1, 2, 2, -1, 2, TextureInfo.MODE_ADD);
    plane.addTriangle(new SimpleVector( -10, -10, 30), new SimpleVector( -10, 10, 30), new SimpleVector(10, -10, 30), tInf1);
    plane.addTriangle(new SimpleVector( -10, 10, 30), new SimpleVector(10, 10, 30), new SimpleVector(10, -10, 30), tInf2);

    w.addObject(plane);
    w.buildAllObjects();

    KeyMapper km=new KeyMapper();
    PolygonManager pm = plane.getPolygonManager();

    float u=-1;
    float v=-1;

    int bs=0;

    while (!Display.isCloseRequested()) {
      fb.clear();
      w.renderScene(fb);
      w.draw(fb);
      fb.displayGLOnly();

      KeyState key=null;

      while(key!=KeyState.NONE) {
        key = km.poll();
        int keyc=key.getKeyCode();
        if (keyc == KeyEvent.VK_W) {
          bs ^= 4;
        }
        if (keyc == KeyEvent.VK_S) {
          bs ^= 8;
        }
        if (keyc == KeyEvent.VK_A) {
          bs ^= 2;
        }
        if (keyc == KeyEvent.VK_D) {
          bs ^= 1;
        }
      }

      if ((bs & 4) == 4) {
        u += 0.01f;
      }
      if ((bs & 8) == 8) {
        u -= 0.01f;
      }
      if ((bs & 2) == 2) {
        v += 0.01f;
      }
      if ((bs & 1) == 1) {
        v -= 0.01f;
      }

      if (bs!=0) {
        tInf1 = new TextureInfo(bid, -1, -1, 2, -1, -1, 2);
        tInf1.add(did, u, v, u + 3, v, u, v + 3, TextureInfo.MODE_ADD);
        tInf2 = new TextureInfo(bid, 2, -1, 2, 2, -1, 2);
        tInf2.add(did, u + 3, v, u + 3, v + 3, u, v + 3, TextureInfo.MODE_ADD);
        pm.setPolygonTexture(0, tInf1);
        pm.setPolygonTexture(1, tInf2);
      }

      Thread.sleep(10);
    }

    km.destroy();
    fb.disableRenderer(IRenderer.RENDERER_OPENGL);
    System.exit(0);
  }
}

Offline rolz

  • float
  • ****
  • Posts: 280
  • Technocrat
    • View Profile
Applying multitexture to single poly in object
« Reply #7 on: January 04, 2006, 08:59:23 pm »
Thanks for the great update, it was really just what i needed !

I've got multitexturing working properly, here is the quick shot:
*Removed*

A couple of questions/ requests:

1. removing unused textures
 I am going to generate shadows for ground objects from their silhouette. It makes sense to remove unused texture from TextureManager when the object is no longer visible (e.g. object has been removed).
 Currently i will have to implement a pool of "shadow" textures and replace unused textures with newly generated, but i dont feel like this is better than just removing unused textures from videocard's memory. What would you suggest ?

2. TextureInfo.MODE_ADD transparency ?
I am using TextureInfo.MODE_ADD when placing additional texture over the base texture. I have noticed that the second texture is ~50% transparent. Is it possible to adjust transparency value when placing one texture over another ? (e.g. put a bloodstain on the ground and make it almost opaque, like with object3d.setTransparency(255)

3. alpha channel for textures
 is there a way to use PNG as texture ? basicly, what i want is a semi-transparent texture which fades away from the center to borders ( smooth shadow)
« Last Edit: November 07, 2010, 10:58:04 pm by EgonOlsen »
Regards,
Andrei

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11776
    • View Profile
    • http://www.jpct.net
Applying multitexture to single poly in object
« Reply #8 on: January 05, 2006, 12:30:06 am »
Great that it worked so far. Now to your questions... :wink:

1. Removing textures from the TextureManager is difficult, because the TextureManager doesn't know if the texture is still in use by an object. It can't even query the objects, because it doesn't know them. It would be possible to remove it anyway, but that will cause a crash or at least a white object (when using the dummy texture instead..if possible...i'll have to check this out) in case it will be used again. An easier task would be to simply unload it from the graphics card's memory and let jPCT upload it again if needed. That would free at least the memory on the video card but not in the TextureManager itself. Or leave it like it is and go for the pooling...not sure, which way to go...


2. No, but you could try to use MODE_MODULATE instead. But: The current implementation uses GL_CLAMP at the borders. According to the specs (some cards/drivers (Nvidia) seem to ignore them but anyway...), this will cause black (or whatever colored) borders for bilinear filtering. This will look strange if the texture is actually clamped. If you have tried this, you'll have already noticed it. I could use GL_CLAMP_TO_EDGE to get rid of this, but that's GL 1.2...but that shouldn't be a problem and i may still use GL_CLAMP as a fallback solution. To understand this better, i've made a picture:


3. Currently not. If clamping is set to GL_CLAMP_TO_EDGE in the future, it should be possible to get what you want with MODE_MODULATE. It's not possible to create shadows by using MODE_ADD anyway.

Like so:


To play around with MODE_MODULATE, here is a jar with  GL_CLAMP_TO_EDGE hacked into the renderer (i.e. no fallback to GL_CLAMP for GL 1.1): http://www.jpct.net/download/beta/jpct.jar

Offline rolz

  • float
  • ****
  • Posts: 280
  • Technocrat
    • View Profile
Applying multitexture to single poly in object
« Reply #9 on: January 05, 2006, 08:55:46 am »
Thanks for prompt response,

Quote from: "EgonOlsen"

1. Removing textures from the TextureManager is difficult, because the TextureManager doesn't know if the texture is still in use by an object. It can't even query the objects, because it doesn't know them. It would be possible to remove it anyway, but that will cause a crash or at least a white object (when using the dummy texture instead..if possible...i'll have to check this out) in case it will be used again. An easier task would be to simply unload it from the graphics card's memory and let jPCT upload it again if needed. That would free at least the memory on the video card but not in the TextureManager itself. Or leave it like it is and go for the pooling...not sure, which way to go...

I think it is ok to leave as is then, let's see if i get into troubles with textures generated on the fly.

Quote

2. No, but you could try to use MODE_MODULATE instead. But: The current implementation uses GL_CLAMP at the borders. According to the specs (some cards/drivers (Nvidia) seem to ignore them but anyway...), this will cause black (or whatever colored) borders for bilinear filtering. This will look strange if the texture is actually clamped. If you have tried this, you'll have already noticed it. I could use GL_CLAMP_TO_EDGE to get rid of this, but that's GL 1.2...but that shouldn't be a problem and i may still use GL_CLAMP as a fallback solution. To understand this better, i've made a picture:


3. Currently not. If clamping is set to GL_CLAMP_TO_EDGE in the future, it should be possible to get what you want with MODE_MODULATE. It's not possible to create shadows by using MODE_ADD anyway.

Like so:


To play around with MODE_MODULATE, here is a jar with  GL_CLAMP_TO_EDGE hacked into the renderer (i.e. no fallback to GL_CLAMP for GL 1.1): http://www.jpct.net/download/beta/jpct.jar


Just tried and it worked just as planned. Thank you again for prompt response. Hope to post more screenshots when I have something to show. ;)
Regards,
Andrei

Offline rolz

  • float
  • ****
  • Posts: 280
  • Technocrat
    • View Profile
Applying multitexture to single poly in object
« Reply #10 on: January 05, 2006, 04:35:13 pm »
Textures won't display at all if there are 3+ textures on polygon already. Is it hardware limit, or it can be somehow overriden ?
Regards,
Andrei

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11776
    • View Profile
    • http://www.jpct.net
Applying multitexture to single poly in object
« Reply #11 on: January 05, 2006, 05:44:06 pm »
Quote from: "rolz"
Textures won't display at all if there are 3+ textures on polygon already. Is it hardware limit, or it can be somehow overriden ?
If 3 is max, it's a hardware limit. jPCT itself is limited to 4 textures/polygon but that's just for optimization purposes and because i don't know of any current hardware that supports more. When initializing the renderer, it tells you the max. number of texture stages supported (the number in brackets behind the init-message) by your hardware.
2 should be possible on almost every hardware (starting with Riva TNT, GF2(MX), GF4MX etc.). More current cards (GF3+, ATI Radeon 9x00 etc) supports 3 or 4, but if you want to support older ones, i suggest to limit yourself to 2. If you add more than the hardware supports, jPCT will ignore them.

Offline rolz

  • float
  • ****
  • Posts: 280
  • Technocrat
    • View Profile
Applying multitexture to single poly in object
« Reply #12 on: January 05, 2006, 06:38:28 pm »
well, yes, it's look like that it's 4.
*Removed*

I've talked to a guy who helped me to understand multitexturing, he mentioned that it should be possible to lay more textures per polygon than video card allows to do in single pass. He mentioned "multipass multitexturing" - do you have an idea what is that, and if it will fit JPCT ?  :(
« Last Edit: November 07, 2010, 10:58:20 pm by EgonOlsen »
Regards,
Andrei

Offline rolz

  • float
  • ****
  • Posts: 280
  • Technocrat
    • View Profile
Applying multitexture to single poly in object
« Reply #13 on: January 05, 2006, 06:43:47 pm »
I am in despair ...  :cry:  :cry:  :cry:
spent a couple of nights trying to make multitexturing work and now stuck at those restrictions ............ !@#$#!@#@#.
Regards,
Andrei

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 11776
    • View Profile
    • http://www.jpct.net
Applying multitexture to single poly in object
« Reply #14 on: January 06, 2006, 12:14:53 am »
Yes, i've already thought about adding a multipass rendering thingy to the engine to overcome these limitations. I think that it would require quite a change to the current pipeline...i'll look into it, when i find the time.