www.jpct.net

jPCT-AE - a 3d engine for Android => Support => Topic started by: Wolf17 on February 27, 2015, 06:33:45 am

Title: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: Wolf17 on February 27, 2015, 06:33:45 am
   I am using Thomas' Game sample and his JPCT extentions (Both are Great Help ! Thanks for open sourcing them !!! ) for creating a world with a cuboid and a plane surface which is having a spotlight.
I really know nothing about shaders, but at the same time trying/eager to have some basic shadowsmapping in my work . 
What I did -
1. On My Oncreate Method I loaded custom shaders .
Code: [Select]
ZipInputStream zis = new ZipInputStream(res.openRawResource(R.raw.data));
ZipEntry ze;
try {
while ((ze = zis.getNextEntry()) != null) {
BLABLA....

ShaderProvider.setShader(ze.getName(), sb.toString());
}

zis.closeEntry();
zis.close();
          BLABLAh....
2. On my OnSrfacechanged...
Code: [Select]
shadowHelper = new cz.chladek.jpct.extension.ShadowProjector();
world.getLightController().setShadowHelper(shadowHelper);

3.Ondrawfrme::..
Code: [Select]
shadowHelper.update(world, fb);


4.  Removed
Code: [Select]
              world.renderScene(fb);
world.draw(fb);

fb.display();
This from my ondrawframe.


Also THis is what in the update method..............
Code: [Select]
public void update(World world, FrameBuffer fb) {
if (light != null) {
if (!setted) {
Enumeration<Object3D> objects = world.getObjects();
while (objects.hasMoreElements()) {
Object3D object = objects.nextElement();
if (!object.getName().startsWith("particle")) {
PolygonManager pm = object.getPolygonManager();
int maxID = pm.getMaxPolygonID();
for (int i = 0; i < maxID; i++)
pm.addTexture(i, textureID, TextureInfo.MODE_MODULATE);
}
}
projectionMatrix = projector.getProjectionMatrix(fb, nearPlane, farPlane);
setted = true;
}
updateProjector();
Camera originalCam = world.getCamera();

world.setCameraTo(projector);
fb.setRenderTarget(shadowTexture, 1, 1, 1, 1, true);
fb.clear(RGBColor.WHITE);
Tools.renderWithShader(world, fb, depthShader);
fb.display();
fb.removeRenderTarget();
world.setCameraTo(originalCam);
}
}

And Tools.renderwithshader......................
Code: [Select]
public static void renderWithShader(World world, FrameBuffer fb, GLSLShader shader) {
Enumeration<Object3D> objects = world.getObjects();
while (objects.hasMoreElements()) {
Object3D obj = (Object3D) objects.nextElement();
if (obj.getVisibility()) {
GLSLShader objShader = obj.getShader();
shaders.add(objShader);
obj.setShader(shader);
}
}

world.renderScene(fb);
world.draw(fb);

objects = world.getObjects();
int i = 0;
while (objects.hasMoreElements()) {
Object3D obj = (Object3D) objects.nextElement();
if (obj.getVisibility()) {
GLSLShader objShader = shaders.get(i);
obj.setShader(objShader);
i++;
}
}
shaders.clear();
}


**********************************************************************
  ___ Result was a blank black screen .___...I also used this
Code: [Select]
shadowHelper.blitShadowMap(fb, halfW - 64, fb.getHeight() - size - 10, size);
to blit the shadowTexture ... but it is also blank white blit .

Then I did many funny experiments with different laughable  results but none produced the desired results.

also my log o/p is full of this-
02-27 10:59:17.330: I/jPCT-AE(7147): Additional visibility list (106) created with size: 512
02-27 10:59:17.350: I/jPCT-AE(7147): Additional visibility list (107) created with size: 512
..........
Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: EgonOlsen on February 27, 2015, 10:25:27 am
Looks like as if you have some exception in your code that you just shallow instead of handling it correctly...hence the massive creation of visibility lists. This indicates an unfinished rendering process. Check your code for empty catch-blocks...
Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: Wolf17 on February 27, 2015, 10:51:23 am
If I comment out
 "fb.setRenderTarget(shadowTexture, 1, 1, 1, 1, true);"
and"   fb.removeRenderTarget();"
then I stop getting the log o/p additionallist
and the result is a white framebuffer (due to fb.clear(white).)with black blit shadowtexture.
exact oppsite of first result!..
I Could not find any relation.
Also I wanna know ...That is my code from the first post is O.K for shadows ? Is it complete?
I am actually simply copying/hacking /retrofitting Thomas' example for shadows to work . 
Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: EgonOlsen on February 27, 2015, 12:20:48 pm
As said: If your code creates dozens of visibility lists, you either don't call display in all render paths or you do but your code doesn't reach it, because it bombs out earlier and you are swallowing the exception. It has to be one of those.
Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: Wolf17 on February 27, 2015, 03:25:06 pm
    The  visibility lists is no more there when I put fb.display() on Ondrawframe().
But I still see a blank screen ....and a white blit overlay. When I put logger.log something in my update   
method and in tools.renderwithshader() method...it does show up in my log o/p. Which ,I think suggests that my code does reach till there.
Don't  know whats happening. :(
Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: EgonOlsen on February 27, 2015, 05:51:42 pm
Have you tried to render the scene when viewed from the projector without the depthmap shader,  so that you can see the scene that it actually renders?
Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: EgonOlsen on February 27, 2015, 05:53:17 pm
...and the normal scene without any special shaders? Just to make sure that everything else like ambient lighting is fine and the scene isn't all dark anyway?
Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: Wolf17 on February 27, 2015, 05:56:06 pm
Yes . Everything Works fine when rendering normally.
Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: EgonOlsen on February 27, 2015, 05:57:38 pm
...even the scene when viewed from the projector?
Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: Wolf17 on February 27, 2015, 06:10:05 pm
No , It only renders a black strip over white fb when I only use projector camera and without depthshader. I am doing this...
Code: [Select]
public void update(World world, FrameBuffer fb) {
if (light != null) {
if (!setted) {
Enumeration<Object3D> objects = world.getObjects();
while (objects.hasMoreElements()) {
Object3D object = objects.nextElement();
if (!object.getName().startsWith("particle")) {
PolygonManager pm = object.getPolygonManager();
int maxID = pm.getMaxPolygonID();
for (int i = 0; i < maxID; i++)
pm.addTexture(i, textureID, TextureInfo.MODE_MODULATE);
}
}
projectionMatrix = projector.getProjectionMatrix(fb, nearPlane, farPlane);
setted = true;
}
updateProjector();
Camera originalCam = world.getCamera();
Logger.log("blbllbbalablllllllllllllllllllllll");
world.setCameraTo(projector);
fb.clear(RGBColor.WHITE);
world.renderScene(fb);
world.draw(fb);
fb.display();
}
}

Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: EgonOlsen on February 27, 2015, 06:13:17 pm
Please try the same thing without any custom shaders set. And can you post your shader sources as well?
Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: Wolf17 on February 27, 2015, 06:19:24 pm
These are same which are used in thomas' game .
Vertex shader shadow map
Code: [Select]
uniform mat4 modelViewProjectionMatrix;

attribute vec4 position;

varying vec4 vPosition;

void main(){
vPosition = modelViewProjectionMatrix * position;
gl_Position = vPosition;
}


fragment shader shadowmap
Code: [Select]
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif

uniform float nearPlane;
uniform float farPlane;
uniform float bias;

varying vec4 vPosition;

vec4 packFloat(float value){
#ifdef GL_FRAGMENT_PRECISION_HIGH
const vec4 PACK_FACTORS = vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0);
const vec4 BIT_MASK = vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
vec4 packetValue = fract(PACK_FACTORS * value);
return packetValue - packetValue * BIT_MASK;
#else
const vec3 PACK_FACTORS = vec3(128.0, 128.0 * 256.0, 128.0 * 256.0 * 256.0);
vec3 packetValue = floor(PACK_FACTORS * value);
packetValue -= vec3(0.0, packetValue.r * 256.0, packetValue.g * 256.0);
return vec4(packetValue / 255.0, 1.0);
#endif
}

void main() {
gl_FragColor = packFloat((vPosition.z - nearPlane) / (farPlane - nearPlane) + bias);
}

Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: EgonOlsen on February 27, 2015, 06:25:01 pm
Yes, these are the ones that fill the depthmap. I'm more interested in the ones that are used to render the actual scene.
Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: Wolf17 on February 27, 2015, 06:30:52 pm
I think this package contains those shaders (attachment)
Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: EgonOlsen on February 27, 2015, 06:39:51 pm
Are you actually ever assigning these shaders that you add to this ShaderProvider class  to some object? I don't see anything like that in your code.
Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: Wolf17 on February 27, 2015, 06:47:36 pm

Means like this?
Code: [Select]
public static void renderWithShader(World world, FrameBuffer fb, GLSLShader shader) {
Enumeration<Object3D> objects = world.getObjects();
while (objects.hasMoreElements()) {
Object3D obj = (Object3D) objects.nextElement();
if (obj.getVisibility()) {
GLSLShader objShader = obj.getShader();
shaders.add(objShader);
obj.setShader(shader);
}
}

world.renderScene(fb);
world.draw(fb);
objects = world.getObjects();
int i = 0;
while (objects.hasMoreElements()) {
Object3D obj = (Object3D) objects.nextElement();
if (obj.getVisibility()) {
GLSLShader objShader = shaders.get(i);
obj.setShader(objShader);
i++;
}
}
shaders.clear();
}

Or do I have to do anything else too? This snippet is called when I want to assign depthshader to the object3ds.
Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: EgonOlsen on February 27, 2015, 08:38:17 pm
No, that assigns the depthmap shader. Shadow mapping requires multiple actions. I don't know about Thomas. actual implemention because i haven't checked it out in detail, but it goes something like this:


(*) = You seem to be doing this (not sure if correctly, but there is code that seems to handle this)
(**) = I'm missing that part. All i can see is that you load the shaders from the zip and assign them to the ShaderProvider (whatever that does...). But i don't see that you are actually using them on your objects. If your normal objects are using a custom shader already, you should modify it in a way that it does the shadow mapping as well. If not, you might be able to pick one from the set in the zip, but i'm not sure, which...

Maybe i should finally create a little test case that demonstrates basic shadow mapping on Android... :-\
Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: EgonOlsen on February 27, 2015, 11:11:29 pm
Ok, here you go: http://jpct.de/download/example/ShadowExample.zip (http://jpct.de/download/example/ShadowExample.zip)

And you'll need a slightly updated version of jPCT-AE for this to work correctly in portrait mode. You can grab this here: http://jpct.de/download/beta/jpct_ae.jar (http://jpct.de/download/beta/jpct_ae.jar)

It's based on Thomas.' work but simplified to one ShadowHelper class (a little similar to what desktop jPCT already offers). That's not saying that Thomas.' source code is too complicated, but it has a much larger scope than this small example, so i decided to cut some stuff and modify some parts. Anyway, without his great work, i couldn't have done this in just 2 hours.

Image:
(http://jpct.de/download/example/shadowexample.png)

I hope this helps somehow. This example uses a single shader for all receiver objects. It's based on the most complex default shader that jPCT-AE offers. So performance might not be optimal in all cases. In addition, it assumes that the depthmap is in texture unit 1, which might not be the case for multitextured objects. Anyway. it's just an example to get you started. I hope it helps.

If i find the time, i'll add it to the wiki in some modified form and if i find even more time, i'll add an even more modified version to the actual release... ;)

Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: Wolf17 on February 28, 2015, 04:49:55 am
    Thank You EgonOlsen!! For posting exaple  And also for explaining the basic shadow mapping process.****You really help a lOT!  :)******
I'll try this ! :)
Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: maggie on May 03, 2016, 07:43:10 pm
Ok, here you go: http://jpct.de/download/example/ShadowExample.zip (http://jpct.de/download/example/ShadowExample.zip)

And you'll need a slightly updated version of jPCT-AE for this to work correctly in portrait mode. You can grab this here: http://jpct.de/download/beta/jpct_ae.jar (http://jpct.de/download/beta/jpct_ae.jar)

It's based on Thomas.' work but simplified to one ShadowHelper class (a little similar to what desktop jPCT already offers). That's not saying that Thomas.' source code is too complicated, but it has a much larger scope than this small example, so i decided to cut some stuff and modify some parts. Anyway, without his great work, i couldn't have done this in just 2 hours.

Image:
(http://jpct.de/download/example/shadowexample.png)

I hope this helps somehow. This example uses a single shader for all receiver objects. It's based on the most complex default shader that jPCT-AE offers. So performance might not be optimal in all cases. In addition, it assumes that the depthmap is in texture unit 1, which might not be the case for multitextured objects. Anyway. it's just an example to get you started. I hope it helps.

If i find the time, i'll add it to the wiki in some modified form and if i find even more time, i'll add an even more modified version to the actual release... ;)

Based on this example, I'm trying to have a transparent receiver by simply adding: plane.setTransparency(20)
And here is the result:
(http://s32.postimg.org/p34ir68x1/shadow_transparant.png)

Is it possible to have a dark color shadow with a transparent receiver? Could you please give me a hint how to do that in jpct-ae?
Basically what I want to achieve is exactly the same with this post: http://www.jpct.net/forum2/index.php/topic,2626.msg19433.html (http://www.jpct.net/forum2/index.php/topic,2626.msg19433.html). The only different thing is I'm using jpct-ae.
Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: EgonOlsen on May 03, 2016, 09:53:46 pm
Might be the shader in that particular example. You might want to try the latest beta instead, which comes with a more advanced shadow support in form of the new ShadowHelper class for AE: http://jpct.de/download/beta/jpct_ae.jar (http://jpct.de/download/beta/jpct_ae.jar)
Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: maggie on May 04, 2016, 05:42:54 pm
The shadow still makes the receiver looks like have a "hole"... :(
Plus, the shadow is not mapped correctly. Probably because of my Projector, not so sure if I set all needed parameters correctly.
Here is my code:

Code: [Select]
public void onSurfaceChanged(GL10 gl, int w, int h) {
try {
Config.farPlane = 5000;
buffer = new FrameBuffer(w, h);

world = new World();
world.setAmbientLight(100, 100, 100);

TextureManager tm = TextureManager.getInstance();
tm.addTexture("floor", new Texture(ShadowExample.this.getBaseContext().getAssets().open("floor.jpg")));

myObject = Object3D.mergeAll(Loader.loadOBJ(
getApplicationContext().getAssets().open("teapot.obj"), null, 10));
myObject.build();
myObject.translate(5, 10, -10);
world.addObject(myObject);

plane = ExtendedPrimitives.createPlane(100, 2);
plane.setTexture("floor");
plane.setTransparency(20);
plane.build();
plane.translate(0, 20, 10);
world.addObject(plane);

Camera cam = world.getCamera();
cam.moveCamera(Camera.CAMERA_MOVEOUT, 50);
cam.lookAt(plane.getTransformedCenter());

SimpleVector sv = new SimpleVector(myObject.getTransformedCenter());
sv.y -= 70;
sv.z = 30;

                                sun = new Light(world);
sun.setIntensity(250, 250, 250);
sun.setPosition(sv);

Projector projector = new Projector();
projector.setFOVLimits(0, 999);
float fov = projector.convertDEGAngleIntoFOV(90);
projector.setFOV(fov);
projector.setYFOV(fov);
projector.setPosition(myObject.getTransformedCenter());

sh = new ShadowHelper(buffer, projector, 512);
sh.setLightSource(projector);
sh.addCaster(myObject);
sh.addReceiver(plane);

MemoryHelper.compact();
} catch (Exception e) {
throw new RuntimeException(e);
}
}


Code: [Select]
public void onDrawFrame(GL10 gl) {
if (touchTurn != 0) {
myObject.rotateY(touchTurn);
touchTurn = 0;
}

if (touchTurnUp != 0) {
myObject.rotateX(touchTurnUp);
touchTurnUp = 0;
}

sh.updateShadowMap(buffer, world);

buffer.clear(back);

world.renderScene(buffer);
world.draw(buffer);

buffer.display();

if (System.currentTimeMillis() - time >= 1000) {
Logger.log(fps + "fps");
fps = 0;
time = System.currentTimeMillis();
}
fps++;
}
Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: EgonOlsen on May 04, 2016, 06:12:57 pm
Why is your projector inside of your object? Is that intentional? Apart from that, I'm not sure what the issue should be. I made myself a test case, set the transparency to 20 and the shadows looked just fine. Are you sure that your code uses the ShadowHelper from the jar and not the one from the zip?
Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: maggie on May 04, 2016, 11:05:18 pm
Sorry, it was a mistake. Just ignore that line.
Yup, I'm sure that I use ShadowHelper from the jar  :(
Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: EgonOlsen on May 05, 2016, 01:16:51 pm
Works fine for me...do you have complete test case for me to try?
Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: maggie on May 05, 2016, 07:07:55 pm
Here is the full code:

Code: [Select]
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.MotionEvent;

import com.threed.jpct.Camera;
import com.threed.jpct.Config;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.Light;
import com.threed.jpct.Loader;
import com.threed.jpct.Logger;
import com.threed.jpct.Object3D;
import com.threed.jpct.Projector;
import com.threed.jpct.RGBColor;
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.ExtendedPrimitives;
import com.threed.jpct.util.MemoryHelper;
import com.threed.jpct.util.ShadowHelper;

public class ShadowExample extends Activity {

private GLSurfaceView mGLView;
private MyRenderer renderer = null;
private FrameBuffer buffer = null;
private World world = null;
private RGBColor back = new RGBColor(50, 50, 100);

private float touchTurn = 0;
private float touchTurnUp = 0;

private float xpos = -1;
private float ypos = -1;

private Object3D myObject = null;
private Object3D plane = null;
private int fps = 0;

private Light sun = null;
private ShadowHelper sh;

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGLView = new GLSurfaceView(getApplication());
mGLView.setEGLContextClientVersion(2);
renderer = new MyRenderer();
mGLView.setRenderer(renderer);
setContentView(mGLView);
}

@Override
protected void onPause() {
super.onPause();
mGLView.onPause();
}

@Override
protected void onResume() {
super.onResume();
mGLView.onResume();
}

@Override
protected void onStop() {
super.onStop();
System.exit(0);
}

public boolean onTouchEvent(MotionEvent me) {

if (me.getAction() == MotionEvent.ACTION_DOWN) {
xpos = me.getX();
ypos = me.getY();
return true;
}

if (me.getAction() == MotionEvent.ACTION_UP) {
xpos = -1;
ypos = -1;
touchTurn = 0;
touchTurnUp = 0;
return true;
}

if (me.getAction() == MotionEvent.ACTION_MOVE) {
float xd = me.getX() - xpos;
float yd = me.getY() - ypos;

xpos = me.getX();
ypos = me.getY();

touchTurn = xd / -100f;
touchTurnUp = yd / -100f;
return true;
}

try {
Thread.sleep(15);
} catch (Exception e) {
// No need for this...
}

return super.onTouchEvent(me);
}

protected boolean isFullscreenOpaque() {
return true;
}

class MyRenderer implements GLSurfaceView.Renderer {

private long time = System.currentTimeMillis();

public MyRenderer() {
}

public void onSurfaceChanged(GL10 gl, int w, int h) {
try {
Config.farPlane = 5000;
buffer = new FrameBuffer(w, h);

world = new World();
world.setAmbientLight(100, 100, 100);

TextureManager tm = TextureManager.getInstance();
tm.addTexture("floor", new Texture(ShadowExample.this.getBaseContext().getAssets().open("floor.jpg")));

myObject = Object3D.mergeAll(Loader.loadOBJ(
getApplicationContext().getAssets().open("teapot.obj"), null, 12));
myObject.build();
myObject.translate(0, 10, 0);
world.addObject(myObject);

plane = ExtendedPrimitives.createPlane(100, 2);
plane.setTexture("floor");
plane.setTransparency(20);
plane.build();
plane.translate(0, 40, 10);
world.addObject(plane);

Camera cam = world.getCamera();
cam.moveCamera(Camera.CAMERA_MOVEOUT, 50);
cam.lookAt(plane.getTransformedCenter());

SimpleVector sv = new SimpleVector(myObject.getTransformedCenter());
sv.y -= 100;
sv.z += 30;

sun = new Light(world);
sun.setIntensity(250, 250, 250);
sun.setPosition(sv);

Projector projector = new Projector();
projector.setClippingPlanes(0.001f, 100f);
projector.setFOVLimits(0, 999);
float fov = projector.convertDEGAngleIntoFOV(90);
projector.setFOV(fov);
projector.setYFOV(fov);

sh = new ShadowHelper(buffer, projector, 1024);
sh.setLightMode(true);
sh.setLightSource(projector);

sh.addCaster(myObject);
sh.addReceiver(plane);

MemoryHelper.compact();
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}

public void onDrawFrame(GL10 gl) {
if (touchTurn != 0) {
myObject.rotateY(touchTurn);
touchTurn = 0;
}

if (touchTurnUp != 0) {
myObject.rotateX(touchTurnUp);
touchTurnUp = 0;
}

sh.updateShadowMap(buffer, world);

buffer.clear(back);

world.renderScene(buffer);
world.draw(buffer);

// sh.blit(buffer);

buffer.display();

if (System.currentTimeMillis() - time >= 1000) {
Logger.log(fps + "fps");
fps = 0;
time = System.currentTimeMillis();
}
fps++;
}
}
}

Apart from the shadow color, why there's no shadow at all when I set the projector's position in the sun's position ( projector.setPosition(sun.getPosition) ) ?
Isn't projection's position supposed to control the position of the shadow on the receiver? Just like what sun does with the ShadowHelper in your zip example?
Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: EgonOlsen on May 05, 2016, 09:37:15 pm
The "hole in the ground" was caused a little flaw in the ShadowHelper. You could consider it to be a feature, but I've changed the behaviour anyway. Please re-download the jar: http://jpct.de/download/beta/jpct_ae.jar (http://jpct.de/download/beta/jpct_ae.jar)

Here's a slightly modified example:
Code: [Select]
package com.threed.jpct.examples;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.MotionEvent;

import com.threed.jpct.Camera;
import com.threed.jpct.Config;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.Light;
import com.threed.jpct.Loader;
import com.threed.jpct.Logger;
import com.threed.jpct.Object3D;
import com.threed.jpct.Projector;
import com.threed.jpct.RGBColor;
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.ExtendedPrimitives;
import com.threed.jpct.util.MemoryHelper;
import com.threed.jpct.util.ShadowHelper;

public class ShadowExample extends Activity {

private GLSurfaceView mGLView;
private MyRenderer renderer = null;
private FrameBuffer buffer = null;
private World world = null;
private RGBColor back = new RGBColor(50, 50, 100);

private float touchTurn = 0;
private float touchTurnUp = 0;

private float xpos = -1;
private float ypos = -1;

private Object3D myObject = null;
private Object3D plane = null;
private int fps = 0;

private Light sun = null;
private ShadowHelper sh;

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGLView = new GLSurfaceView(getApplication());
mGLView.setEGLContextClientVersion(2);
renderer = new MyRenderer();
mGLView.setRenderer(renderer);
setContentView(mGLView);
}

@Override
protected void onPause() {
super.onPause();
mGLView.onPause();
}

@Override
protected void onResume() {
super.onResume();
mGLView.onResume();
}

@Override
protected void onStop() {
super.onStop();
System.exit(0);
}

public boolean onTouchEvent(MotionEvent me) {

if (me.getAction() == MotionEvent.ACTION_DOWN) {
xpos = me.getX();
ypos = me.getY();
return true;
}

if (me.getAction() == MotionEvent.ACTION_UP) {
xpos = -1;
ypos = -1;
touchTurn = 0;
touchTurnUp = 0;
return true;
}

if (me.getAction() == MotionEvent.ACTION_MOVE) {
float xd = me.getX() - xpos;
float yd = me.getY() - ypos;

xpos = me.getX();
ypos = me.getY();

touchTurn = xd / -100f;
touchTurnUp = yd / -100f;
return true;
}

try {
Thread.sleep(15);
} catch (Exception e) {
// No need for this...
}

return super.onTouchEvent(me);
}

protected boolean isFullscreenOpaque() {
return true;
}

class MyRenderer implements GLSurfaceView.Renderer {

private long time = System.currentTimeMillis();

public MyRenderer() {
}

public void onSurfaceChanged(GL10 gl, int w, int h) {
try {
Config.farPlane = 5000;
buffer = new FrameBuffer(w, h);

world = new World();
world.setAmbientLight(100, 100, 100);

TextureManager tm = TextureManager.getInstance();
tm.addTexture("floor", new Texture(ShadowExample.this.getBaseContext().getAssets().open("floor.jpg")));

myObject = Object3D.mergeAll(Loader.loadOBJ(
getApplicationContext().getAssets().open("teapot.obj"), null, 12));
myObject.build();
myObject.translate(0, 10, 0);
world.addObject(myObject);

plane = ExtendedPrimitives.createPlane(100, 2);
plane.setTexture("floor");
plane.setTransparency(20);
plane.build();
plane.translate(0, 40, 10);
world.addObject(plane);

Camera cam = world.getCamera();
cam.moveCamera(Camera.CAMERA_MOVEOUT, 50);
cam.lookAt(plane.getTransformedCenter());

SimpleVector sv = new SimpleVector(myObject.getTransformedCenter());
sv.y -= 100;
sv.z += 30;

sun = new Light(world);
sun.setIntensity(250, 250, 250);
sun.setPosition(sv);
 
Projector projector = new Projector();
projector.setClippingPlanes(1f, 300f);
projector.setFOVLimits(0, 999);
float fov = projector.convertDEGAngleIntoFOV(90);
projector.setFOV(fov);
projector.setYFOV(fov);

projector.setPosition(sun.getPosition());
projector.lookAt(myObject.getTransformedCenter());

sh = new ShadowHelper(buffer, projector, 1024);
sh.setLightSource(projector);
sh.setAmbientLight(new RGBColor(50,50,50));
sh.addCaster(myObject);
sh.addReceiver(plane);

MemoryHelper.compact();
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}

public void onDrawFrame(GL10 gl) {
if (touchTurn != 0) {
myObject.rotateY(touchTurn);
touchTurn = 0;
}

if (touchTurnUp != 0) {
myObject.rotateX(touchTurnUp);
touchTurnUp = 0;
}

sh.updateShadowMap(buffer, world);

buffer.clear(back);

world.renderScene(buffer);
world.draw(buffer);

// sh.blit(buffer);

buffer.display();

if (System.currentTimeMillis() - time >= 1000) {
Logger.log(fps + "fps");
fps = 0;
time = System.currentTimeMillis();
}
fps++;
}
}
}

It places the projector at the sun's position. If you want to do that, you have to take two additional things into account:


Hope this helps.
Title: Re: Need help regarding setup of Thomas' shadow implementation in my example.
Post by: maggie on May 05, 2016, 10:07:53 pm
ah ok... Got it.
Cool, now it works. Thank you!  ;D