www.jpct.net

jPCT - a 3d engine for Java => Support => Topic started by: rolz on December 26, 2005, 05:01:16 pm

Title: Applying multitexture to single poly in object
Post by: rolz 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) ?
Title: Applying multitexture to single poly in object
Post by: EgonOlsen on December 26, 2005, 05:02:56 pm
Not yet. I'll add it in a future release.
Title: Applying multitexture to single poly in object
Post by: rolz 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 ?
Title: Applying multitexture to single poly in object
Post by: EgonOlsen 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?
Title: Applying multitexture to single poly in object
Post by: rolz 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.
Title: Applying multitexture to single poly in object
Post by: EgonOlsen on December 27, 2005, 07:31:44 pm
I see...I'll have a look at it next year... :wink:
Title: Applying multitexture to single poly in object
Post by: EgonOlsen 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);
  }
}
Title: Applying multitexture to single poly in object
Post by: rolz 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)
Title: Applying multitexture to single poly in object
Post by: EgonOlsen 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:
(http://www.jpct.net/img/clamp_example.png)

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:
(http://www.jpct.net/img/shadow.png)

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
Title: Applying multitexture to single poly in object
Post by: rolz 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:
(http://www.jpct.net/img/clamp_example.png)

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:
(http://www.jpct.net/img/shadow.png)

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. ;)
Title: Applying multitexture to single poly in object
Post by: rolz 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 ?
Title: Applying multitexture to single poly in object
Post by: EgonOlsen 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.
Title: Applying multitexture to single poly in object
Post by: rolz 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 ?  :(
Title: Applying multitexture to single poly in object
Post by: rolz 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 ............ !@#$#!@#@#.
Title: Applying multitexture to single poly in object
Post by: EgonOlsen 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.
Title: Applying multitexture to single poly in object
Post by: EgonOlsen on January 10, 2006, 01:01:43 am
Just wanted to let you know that your problem is not forgotten. I'm working on it and i have an alpha version of it running for the "normal" OpenGL renderer. I'll start working on the AWTGLRenderer on wednesday (at least i hope so).
Title: Applying multitexture to single poly in object
Post by: rolz on January 10, 2006, 09:14:38 am
Thanks for the support, hope to see this feature working soon.

 Regarding fullscreen opengl renderer - I would like to ask for your guidance.
 The problem is that i am still getting reports of compatibility issues with AWT+opengl on some gf2mx cards. The user either gets the blank screen (with only 2D interface) or the performance is about 10 fps on pretty good hardware, which makes me thing something is wrong.

  I am concerned this is some weird bug with lwjgl/AWT/drivers combination, and chances are i just won't be able to solve it.  I am not sure what is the best solution for this cause, actually i had 2 things in mind:

 - stick with AWT/GL combination, with no guarrantee that problems will be solved
 - switch to regular LWJGL renderer which works, but then i would have to redo all 2d, and probably lose so much desired AWT flexibility.

What would you recommend ?
Title: Applying multitexture to single poly in object
Post by: EgonOlsen on January 11, 2006, 12:03:30 am
I would stick with AWT and concentrate on the game play itself. I'm not sure what causes the problem with the MX, but it could be anything. Java in all its flavours is still having problem with AA enabled in the drivers for example. I've tested Techno on a GF2MX under Linux and it was quite slow due to the CPU (PII-450), but it was playable. With current drivers, the MX should behave like any other outdated GeForce card (in theory...). If it's better in windowed mode, i think that this is a good solution for a game like Techno.
Switching to native LWJGL will cause you a lot of work but with an uncertain success. Maybe it will run better on some of these systems but fail on others. Too bad that i can't contribute with experiences from Paradroidz, which does native LWJGL fullscreen...i assume that i'm just getting no feedback from people where it doesn't work.
The other pro of the AWTGL-stuff is, that you'll largely benefit from dual cpu/core setups. I haven't tested this myself, but i once published a benchmark and the fps increased up to 80% on dual cpu machines with the  AWTGLRenderer.

P.S.: Adding multi pass texturing is a pain... :wink:
Title: Applying multitexture to single poly in object
Post by: rolz on January 11, 2006, 09:27:46 am
Helge,

Thanks for the reply, I wouldnt consider switching from AWT GL to native lwjgl without good reasons. ;)


Regarding multitexturing - Terrain decorations and shadows were redesigned to use multitexturing - and they really look awesome now:  
*Removed*
Title: Applying multitexture to single poly in object
Post by: rolz on January 11, 2006, 08:16:30 pm
more teasers

*Removed*
Title: Applying multitexture to single poly in object
Post by: EgonOlsen on January 11, 2006, 08:20:41 pm
After adding more new bugs than features, here's a version that will hopefully  work well enough to test multi pass rendering: http://www.jpct.net/download/beta/jpctapi110_pre2.zip

There are some drawbacks/problems with multi pass compared to one pass multi texturing. This affects the areas of transparency, fogging and accuracy.
I'm not sure if this approach is suitable for what you have in mind...well, we'll see...here's how the OpenGL pipeline handles one pass multi texturing:

(http://www.jpct.net/img/opengl_mt_pipeline.png)

As you can see, it's pretty straight forward. The texture in stage 1 is modulated with the vertex colors, then blended together with the one in stage 2...n. Then, the blending with the screen is done (which means applying transparency in this case) and the results are fogged.

Here's how the multi pass approach works:

(http://www.jpct.net/img/opengl_mp_pipeline.png)

The textures are applied in multiple passes now, which means that they are blended with the screens content one after the other. This has some problems.

Transparency: Can only be applied to the first texture, because it's the only one that won't be blended with the screen anyway because of the texture blending that's needed. But you can only do one blending, either the alpha blending for transparency or the color blending for the textures. Result: Transparency on multi pass polygons is there but much less than on single pass ones. And writing to the depth buffer has to be turned on for transparent multi pass polygons. For single pass, it's turned of by jPCT.

Fogging: You can either apply fog after each texturing pass (which is what i did) or just after the first or just after the last. In each case, you'll never get the same results as you would get with a single pass. Either the fogging will be too intense (my choice for the moment) or not intense enough (with both other options). So fogging multi pass textured polygons is a problem...maybe shifting the fog's starting position away in combination with no additional shadows (from characters or whatever) but the environment ones from that position on is an option?

Accuracy: That isn't much of a problem, but current hardware does the blending with a higher internal accuracy than the framebuffer provides. That means that you'll lose some color information by writing into the framebuffer for each pass. That's most noticable when using MODE_ADD. BLEND and MODULATE shouldn't be affected that much (if even).

How to enable multi pass: You don't have to. jPCT will use it on polygons that need it (i.e. that have a higher texture layer count than the hardware can render in one pass) automatically. There are some new settings in Config: maxTextureLayers, glMultiPassSorting and glOverrideStageCount.
Title: Applying multitexture to single poly in object
Post by: rolz on January 12, 2006, 10:11:51 am
Just downloaded the patch - works great, except the fogging problem.
I have a couple ideas how to overcome it:

- switch to vertex fogging (looks less realistic than pixel but it works)
- restrict camera to z rotations only - this will prevent player from seeing borders of visibility area (which are not completelly hidden with vertex fog) and stick to classic RPG izometriс view (as in Diablo, BG, NWN)

so far, it looks like this:
*Removed*

And, thanks again for prompt responce !  Great job, btw. Exactly same thing as i had in mind.
Title: Applying multitexture to single poly in object
Post by: EgonOlsen on January 12, 2006, 07:34:24 pm
Quote from: "rolz"

- switch to vertex fogging (looks less realistic than pixel but it works)
- restrict camera to z rotations only - this will prevent player from seeing borders of visibility area (which are not completelly hidden with vertex fog) and stick to classic RPG izometriс view (as in Diablo, BG, NWN)
Vertex fog works fine for exactly one fog color: black! I'm not sure if it's really a good looking option. Maybe limiting the visible area is the best solution....:?:
The screen shot looks cool. Great that the extension seems to work that well.
Title: Applying multitexture to single poly in object
Post by: EgonOlsen on January 16, 2006, 08:25:12 pm
A new version that fixes a bug in 2D blitting (the AWTGLRenderer doesn't seem to be affected by this, but it was wrong anyway) and adds support for the alpha channel of transparent objects:
http://www.jpct.net/download/beta/jpctapi110_pre3.zip