Compile() Darkens My Ground Plane

Started by AGP, June 24, 2014, 05:14:00 AM

Previous topic - Next topic

AGP

If I call compile() on any object in my game the ground becomes darker and stops matching the sky box. How come? And setAdditionalColor(Color.white) makes the ground blend into the sky box again, but destroys my shadows.

AGP

Just to clarify, if I compile anything at all, the ground gets darker.

By the way, I'm making a Superman vs Iron Man game for my son and I can tell you that there is a bug--and it can be nothing but a bug--either in jpct or with my video driver wherein if I compile Iron Man with compile(true), EVERYTHING gets messed up (I have to use the third, most flexible compile method instead or Superman himself mecomes metallic and everything else gets messed up). It should be noted that Iron Man has an environment map in its TextureInfo's first slot (new TextureInfo(tm.getTextureID("EnvironmentMap"))).

EgonOlsen

Most likely because the lighting calculations differ between compiled and not compiled objects. The former ignore Config.lightMul and use an implicit value of 1. The latter uses whatever has been configured. Either that, or you forgot to call build() on the ground plane.
About the others issue...no idea. Sounds like either a problem with the video driver or you are doing something strange. What exactly means 'everything is messed up'?

AGP

The following image illustrates the problems. The first image is how I'm experiencing the "messed up" problem (it's down to only Iron Patriot now, Marks 3 and 42 work fine). All Iron Men are compiled by the exact same code (for (int i = 0; i < ironMan.model.getSize(); i++) ironMan.model.get(i).compile(true, true, true, false, Config.glBatchSize)).

But even on the second image the ground is darker than it used to be (it used to blend perfectly with the skybox). Config.lightMul was never called.


EgonOlsen

So somehow, the model has either faulty texture coordinates or the texture doesn't fit the coordinates that are there...is there any call to shareCompiledData() or shareTextureData() in the context of these models?

You also might want to try compile(true, true, false, false, Config.glBatchSize) instead of compile(true, true, true, false, Config.glBatchSize). Display lists are an outdated concept and VBOs should be prefered. But because you are compiling to dynamic, it shouldn't matter anyway. What's with a simple compile(true);?

About the ground plane: It's either Config.glLightMul (set it to 1 and see if the uncompiled version changes) or the fact that the hybrid pipeline can handle overbright values where the hardware one can't due to hardware restrictions. This is no bug or anything that can be changed, so you have to tweak your plane's brightness to look good in compiled mode.

AGP

So, you're saying that if the Iron Patriot has bad texture coordinates the whole scene would break? But the Iron Patriot is the only thing that looks right in this example... And no, I haven't called shareCompiledData().

EgonOlsen

Quote from: AGP on July 03, 2014, 11:00:56 AM
So, you're saying that if the Iron Patriot has bad texture coordinates the whole scene would break?
No, that's not what i meant. I just meant that the superman model might have a problem with it's coordinates for whatever reasons. Or it's a problem with the driver or something. Can you provide me with a test case?

AGP

What's with a simple compile(true);?

Compile(true) produces the same broken effect with all Iron Men. Compile(true, true, false, false, Config.glBatchSize) makes the scene work for both Mark 3 and Mark 42, but still breaks with Iron Patriot. Would you like me to send you the Iron Patriot model?

EgonOlsen

I created a test case, but i can't see anything wrong with the results.

Image:


Source:

import java.awt.Color;
import java.io.FileInputStream;

import raft.jpct.bones.Animated3D;
import raft.jpct.bones.AnimatedGroup;
import raft.jpct.bones.BonesIO;

import com.threed.jpct.FrameBuffer;
import com.threed.jpct.IRenderer;
import com.threed.jpct.Object3D;
import com.threed.jpct.Primitives;
import com.threed.jpct.Projector;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.Texture;
import com.threed.jpct.TextureManager;
import com.threed.jpct.World;
import com.threed.jpct.util.ShadowHelper;

public class Patriot {

private World world;

private FrameBuffer buffer;

private AnimatedGroup mesh;

private Object3D ground;
private Object3D cube;

private ShadowHelper shady;

public static void main(String[] args) throws Exception {
new Patriot().loop();
}

public Patriot() throws Exception {
world = new World();
world.setAmbientLight(255, 255, 255);

TextureManager.getInstance().addTexture("IronPatriot.jpg", new Texture("patriot/IronPatriot.jpg"));

mesh = BonesIO.loadGroup(new FileInputStream("patriot/IronPatriot.mesh.bones"));

for (Animated3D o : mesh) {
o.setTexture("IronPatriot.jpg");
o.compile(true);
o.build();
o.discardMeshData();
o.setVisibility(true);
}

mesh.addToWorld(world);

ground = Primitives.getPlane(2, 100);
ground.compile();
ground.build();
ground.rotateX((float) Math.PI / 2f);
world.addObject(ground);

cube=Primitives.getCube(20);
cube.calcTextureWrap();
cube.setTexture("IronPatriot.jpg");
cube.build();
cube.compile();
world.addObject(cube);


SimpleVector pos = mesh.getRoot().getTransformedCenter();
cube.translate(150,-100,0);
ground.translate(100, -85, 0);

pos.z -= 200;
pos.y -= 130;
pos.x += 100;
world.getCamera().setPosition(pos);
}

private void loop() throws Exception {
buffer = new FrameBuffer(800, 600, FrameBuffer.SAMPLINGMODE_HARDWARE_ONLY);
buffer.disableRenderer(IRenderer.RENDERER_SOFTWARE);
buffer.enableRenderer(IRenderer.RENDERER_OPENGL);

Projector proj = new Projector();
proj.setPosition(100, -300, 300);
proj.lookAt(mesh.getRoot().getTransformedCenter());
proj.setFOVLimits(0, 5);
proj.setFovAngle(1.5f);

shady = new ShadowHelper(world, buffer, proj, 2048);
shady.addCaster(cube);
shady.addReceiver(ground);
shady.setAmbientLight(Color.DARK_GRAY);

for (Animated3D o : mesh) {
shady.addCaster(o);
}

long time = 0;
float index = 0;
int fps = 0;
long st = System.currentTimeMillis();

while (!org.lwjgl.opengl.Display.isCloseRequested()) {

if (time == 0) {
time = System.nanoTime() / 1000000L;
}

long dt = (System.nanoTime() / 1000000L) - time;
time = dt + time;
index += dt / 10000f;

while (index > 1) {
index -= 1;
}

mesh.animateSkin(index, 0);
buffer.clear(java.awt.Color.BLUE);

shady.updateShadowMap();
shady.drawScene();

buffer.update();
buffer.displayGLOnly();
fps++;
if (System.currentTimeMillis() - st >= 1000) {
st = System.currentTimeMillis();
System.out.println(fps + "fps");
fps = 0;
}
}
buffer.disableRenderer(IRenderer.RENDERER_OPENGL);
buffer.dispose();
System.exit(0);
}
}



AGP

#9
Notice that neither the ground plane nor Iron Patriot itself look wrong in my screenshot (but it is compiling Iron Patriot that causes the problem with everything else). And maybe it only happens in combination with Superman. I'll send you the whole thing so that you can see for yourself.

AGP

#10
But I should note that your example doesn't use an environment map. It may very well be the problem...

Oh, and add a SkyBox too, please.

EgonOlsen

Quote from: AGP on July 08, 2014, 03:18:34 AM
But I should note that your example doesn't use an environment map. It may very well be the problem...
Looks like it. I've enabled it on the animated model and suddenly, my cube gets texture coordinates too if i compile both. I'll look into it.

EgonOlsen

Please give this version a try: http://jpct.de/download/beta/jpct.jar

There was a problem with the OpenGL state management in this case. I'm not sure if it caused your problem, but it certainly caused mine. Looks ok now:



Code:
import java.awt.Color;
import java.io.FileInputStream;

import raft.jpct.bones.Animated3D;
import raft.jpct.bones.AnimatedGroup;
import raft.jpct.bones.BonesIO;

import com.threed.jpct.FrameBuffer;
import com.threed.jpct.IRenderer;
import com.threed.jpct.Object3D;
import com.threed.jpct.Primitives;
import com.threed.jpct.Projector;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.Texture;
import com.threed.jpct.TextureInfo;
import com.threed.jpct.TextureManager;
import com.threed.jpct.World;
import com.threed.jpct.util.ShadowHelper;

public class Patriot {

private World world;

private FrameBuffer buffer;

private AnimatedGroup mesh;

private Object3D ground;
private Object3D cube;

private ShadowHelper shady;

public static void main(String[] args) throws Exception {
new Patriot().loop();
}

public Patriot() throws Exception {
world = new World();
world.setAmbientLight(255, 255, 255);

TextureManager tm=TextureManager.getInstance();
tm.addTexture("env", new Texture("textures/environment.jpg"));
tm.addTexture("IronPatriot.jpg", new Texture("patriot/IronPatriot.jpg"));

mesh = BonesIO.loadGroup(new FileInputStream("patriot/IronPatriot.mesh.bones"));

TextureInfo ti=new TextureInfo(tm.getTextureID("env"));
ti.add(tm.getTextureID("IronPatriot.jpg"), TextureInfo.MODE_MODULATE);

for (Animated3D o : mesh) {
o.setEnvmapped(Object3D.ENVMAP_ENABLED);
o.setTexture(ti);
o.compile(true);
o.build();
o.discardMeshData();
o.setVisibility(true);
}

mesh.addToWorld(world);

ground = Primitives.getPlane(2, 100);
ground.compile();
ground.build();
ground.rotateX((float) Math.PI / 2f);
world.addObject(ground);

cube=Primitives.getCube(20);
cube.calcTextureWrap();
cube.setTexture("IronPatriot.jpg");
cube.build();
cube.compile();
world.addObject(cube);


SimpleVector pos = mesh.getRoot().getTransformedCenter();
cube.translate(150,-100,0);
ground.translate(100, -85, 0);

pos.z -= 200;
pos.y -= 130;
pos.x += 100;
world.getCamera().setPosition(pos);
}

private void loop() throws Exception {
buffer = new FrameBuffer(800, 600, FrameBuffer.SAMPLINGMODE_HARDWARE_ONLY);
buffer.disableRenderer(IRenderer.RENDERER_SOFTWARE);
buffer.enableRenderer(IRenderer.RENDERER_OPENGL);

Projector proj = new Projector();
proj.setPosition(100, -300, 300);
proj.lookAt(mesh.getRoot().getTransformedCenter());
proj.setFOVLimits(0, 5);
proj.setFovAngle(1.5f);

shady = new ShadowHelper(world, buffer, proj, 2048);
shady.addCaster(cube);
shady.addReceiver(ground);
shady.setAmbientLight(Color.DARK_GRAY);

for (Animated3D o : mesh) {
shady.addCaster(o);
}

long time = 0;
float index = 0;
int fps = 0;
long st = System.currentTimeMillis();

while (!org.lwjgl.opengl.Display.isCloseRequested()) {

if (time == 0) {
time = System.nanoTime() / 1000000L;
}

long dt = (System.nanoTime() / 1000000L) - time;
time = dt + time;
index += dt / 10000f;

while (index > 1) {
index -= 1;
}

mesh.animateSkin(index, 0);
buffer.clear(java.awt.Color.BLUE);
cube.rotateY(0.01f);

shady.updateShadowMap();
shady.drawScene();

buffer.update();
buffer.displayGLOnly();
fps++;
if (System.currentTimeMillis() - st >= 1000) {
st = System.currentTimeMillis();
System.out.println(fps + "fps");
fps = 0;
}
}
buffer.disableRenderer(IRenderer.RENDERER_OPENGL);
buffer.dispose();
System.exit(0);
}
}

AGP

Awesome, thanks very much. It works, now. Any idea why it didn't break with the other models?

EgonOlsen

It had something to do with render order. If the model with the environment map had been rendered, all subsequent models were possible victims of this bug.