Im using libGDX and this is a Desktop project.
I have 2 models, one is the character and the other is the map, as you can see in the image below:
My question is:
How do I project the shadow of the character on the floor?
As you can see the character doesn't have a shadow, thus the Ambience Light. What do I have to use or how do I achieve this? Should I fake a shadow or is there a real way to project shadows?
Any comments or sugestions are welcome.
You can use following code:
Environment environment;
DirectionalShadowLight shadowLight;
#Override
public void show() {
modelBatch = new ModelBatch();
environment = new Environment();
environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 1.0f, 1f, .6f, 1f));
environment.add((shadowLight = new DirectionalShadowLight(1024, 1024, 60f, 60f, .1f, 50f))
.set(1f, 1f, 1f, 40.0f, -35f, -35f));
environment.shadowMap = shadowLight;
shadowBatch = new ModelBatch(new DepthShaderProvider());
}
#Override
public void render(float delta) {
//create shadow texture
shadowLight.begin(Vector3.Zero, camera.direction);
shadowBatch.begin(shadowLight.getCamera());
shadowBatch.render(instances);
shadowBatch.end();
shadowLight.end();
//render scene
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
modelBatch.begin(cam);
modelBatch.render(instances, environment); //environment has shadowMap!
modelBatch.end();
}
Sometime in 2015, a better shadow system was added to the libGDX testbed, separately from the "experimental, do not use" stuff mentioned in #Nolesh's answer.
The code is in the libGDX tests, so you'd need to copy it to your own project. A short description of how it works was posted on the libGDX forums by the author, realitix. Note that there doesn't seem to be a fully runnable example, but the JavaDoc for the ShadowSystem interface contains the following:
// Init system:
Array<ModelBatch> passBatches = new Array<ModelBatch>();
ModelBatch mainBatch;
ShadowSystem system = new XXXShadowSystem();
system.init();
for (int i = 0; i < system.getPassQuantity(); i++) {
passBatches.add(new ModelBatch(system.getPassShaderProvider(i)));
}
mainBatch = new ModelBatch(system.getShaderProvider());
// Render scene with shadows:
system.begin(camera, instances);
system.update();
for (int i = 0; i < system.getPassQuantity(); i++) {
system.begin(i);
Camera camera;
while ((camera = system.next()) != null) {
passBatches.get(i).begin(camera);
passBatches.get(i).render(instances, environment);
passBatches.get(i).end();
}
camera = null;
system.end(i);
}
system.end();
HdpiUtils.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
mainBatch.begin(cam);
mainBatch.render(instances, environment);
mainBatch.end();
It's not as good as having a proper API for shadowing, but better than having to implement the entire thing from scratch.
Related
I am trying to make a 2D OpenGL project using LWJGL 2, and I am having trouble with basic rendering.
Main class:
public class ScratchCord {
private Renderer renderer;
public TextureManager manager;
private int i = 0;
private int i2 = 0;
private ScratchCord() {
renderer = new Renderer(this);
manager = new TextureManager();
ContextAttribs attribs = new ContextAttribs(3, 2).withForwardCompatible(true).withProfileCore(true);
try {
Display.setDisplayMode(new DisplayMode(1240, 740));
Display.create(new PixelFormat(), attribs);
Display.setTitle("ScratchCord");
} catch (LWJGLException e) {
e.printStackTrace();
}
GL11.glViewport(0, 0, 1240, 740);
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, 1240, 740, 0, -1, 1);
}
private void start() {
while (!Display.isCloseRequested()) {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
renderer.draw(i, i2, "ScratchCord/src/main/resources/textures/download.jpg", 200, 200);
Display.sync(60);
Display.update();
i += 1;
i2 += 1;
}
}
public static void main(String[] args) {
System.setProperty("org.lwjgl.util.NoChecks","true");
ScratchCord scratchCord = new ScratchCord();
scratchCord.start();
}
}
For some reason, I get a FunctionNotSupported error, but the code works in http://www.cokeandcode.com/info/tut2d-4.html.
I tried setting the OpenGl version to 2.0, and I got an error in Display.create and the OpenGL context was not created.
I've heard that sometimes graphics drivers can break LWJGL, but mine are updated and other projects I have works.
Also some people say that the function just isn't in 3.2, and if so how would I do this?
Your machine likely does not support Legacy GL, making it a "Core" context. Core contexts have deprecated legacy functions, like matrix operations, unavailable.
Find a tutorial that is for modern core opengl.
I'm using libGdx 1.9.6 and I've got an issue. I've searched multiple forums, read various tutorials but nothing fits. I've created a simple cube in blender, textured it and export it to FBX (using fbx-conv). I've also downloaded the BDX-Blender-Exporter. I've tested Blender 2.69 and 2.76b without any changes to the result.
The model is loaded and shown :
blended cube
If I change the background color to (0,0,0,0) or (0,0,0,1) then only a black screen appears.
Here's the code (libGDX 1.9.6, Android-Studio 2.3.3)
public class modelloader implements ApplicationListener {
private PerspectiveCamera camera;
private ModelBatch modelBatch;
private Model model;
private ModelInstance modelInstance;
private Environment environment;
private CameraInputController camController;
private AssetManager as;
#Override
public void create() {
camera = new PerspectiveCamera(
75,
Gdx.graphics.getWidth(),
Gdx.graphics.getHeight());
camera.position.set(0f,0f,7f);
camera.lookAt(0f,0f,0f);
camera.near = 0.1f;
camera.far = 300.0f;
modelBatch = new ModelBatch();
as = new AssetManager();
as.load("moon.g3db",Model.class);
as.finishLoading();
model = as.get("moon.g3db",Model.class);
model.materials.get(0).set(new BlendingAttribute(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA));
modelInstance = new ModelInstance(model);
modelInstance.transform.rotate(1, 0, 0, 0);
modelInstance.transform.translate(0, 0, -2);
environment = new Environment();
environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.8f, 0.8f, 0.8f, 1.0f));
environment.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -0.8f, 0.3f, 1f));
camController = new CameraInputController(camera);
camController.forwardTarget = true;
Gdx.input.setInputProcessor(camController);
}
#Override
public void dispose() {
modelBatch.dispose();
model.dispose();
}
#Override
public void render() {
camController.update();
Gdx.gl20.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Gdx.gl20.glClearColor(1,1,1,0);
Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
camera.update(true);
modelBatch.begin(camera);
modelBatch.render(modelInstance, environment);
modelBatch.end();
}
The model is also only shown when the line
model.materials.get(0).set(new BlendingAttribute(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA));
exists.
Here's the blender file :
cube.blend
Where could be the problem?
Holy mackerel, it was the texture file... it was 1024x1024 png... but somehow corruptet... once opened and resaved and all works.... countless hours and this is the only thing I've not checked... Thanks for the help guys! –
After I updated my OS, i found that my models were not rendering their textures properly in LibGDX. The model would appear black instead of having a texture. This happened right after i updated my OS so, i don't know if it has anything to do with that.
Here is how it looks in blender:
and Here is how it looks in libGdx:
Notice how the textures for the model are not rendering.
Here is my create() method:
public void create () {
camera=new PerspectiveCamera(67,800,480);
camera.position.set(0f, 0f, 10f);
camera.lookAt(0f, 0f, 0f);
camera.near=1f;
camera.far=50f;
batch=new ModelBatch();
UBJsonReader jsonreader=new UBJsonReader();
G3dModelLoader modelloader=new G3dModelLoader(jsonreader);
playermodel=modelloader.loadModel(Gdx.files.getFileHandle("paulmodel.g3db", Files.FileType.Internal));
player=new ModelInstance(playermodel,0,0,0);
environment=new Environment();
environment.set(new ColorAttribute(ColorAttribute.AmbientLight,0.65f,0.65f,0.65f,1f));
}
Here is my Render() method:
public void render () {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
Gdx.gl20.glEnable(GL20.GL_DEPTH_TEST);
camera.update();
batch.begin(camera);
batch.render(player, environment);
batch.end();
camera.rotateAround(new Vector3(0f, 0f, 0f), new Vector3(0f, 1f, 0f), 0.5f);
}
Here is my model
Also, i seem to begetting an error distrib/android-emugl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp:glActiveTexture:177 error 0x500
If you need anything else, please ask and i will post it.
Thanks in advance!
EDIT:
Here is the .G3dJ file as requested.
EDIT:
It works perfectly fine on a real phone but, it doesn't work on an AVD. Does this mean that it should work on all phones? Also, i have made the textures in the format of 2^n by 2^n pixels.
I cannot print any message in the LogCat with libGDX using the method:
Gdx.app.log(tag, message);
In my onCreate method I've set:
Gdx.app.setLogLevel(Application.LOG_INFO); //debug or error, same story
Render method:
public void render() {
if (loading && assets.update())
doneLoading();
Gdx.app.log("application", "loaded"); //not showed
camController.update();
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Gdx.gl.glClearColor(0, 0, 0.2f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
modelBatch.begin(cam);
modelBatch.render(instances, environment);
modelBatch.end();
}
doneLoading() method:
private void doneLoading() {
I_model = assets.get("data/male_teen.g3db", Model.class);
I_instance = new ModelInstance(I_model);
instances.add(I_instance);
loading = false;
}
Suggestions?
I've deleted the filter that is created automatically by Eclipse. Cleaned the project and reinstalled on the device. Now it works.
I am trying to render a Tiled Map on to an Android device. However, when I test it on my android phone, only the top layer is rendered on to the screen (out of two layers total). Is there a way to fix this? I am using Libgdx as well as Tiled Map Editor.
Below is some of the code for my project which implements the Screen interface. The omitted code is not necessary for the question but can be shown if needed.
public class Play implements Screen {
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
renderer.setView(cam);
renderer.render();
/*code ommited*/
renderer.getSpriteBatch().begin();
animateAgent(time);
sr.setProjectionMatrix(cam.combined);
try {
animateBullets(sr);
} catch(IndexOutOfBoundsException e) {}
renderer.getSpriteBatch().end();
}
public void show() {
cam = new OrthographicCamera();
cam.setToOrtho(false);
cam.position.set(0,0,0);
cam.zoom = 8.0f;
cam.update();
map = new TmxMapLoader().load("data/batMap.tmx");
blocked = (TiledMapTileLayer) map.getLayers().get(1);
renderer = new OrthogonalTiledMapRenderer(map);
atlas = new TextureAtlas("data/specOps.txt");
agent = atlas.createSprites("agent");
/* code ommitted */
player = new Player(agent,blocked,bullets);
Gdx.input.setInputProcessor(player);
}
}
Here's how it currently looks:
and here's how it should look:
You are only getting one layer at
blocked = (TiledMapTileLayer) map.getLayers().get(1);
or are you getting the other layer elsewhere?
Try:
map.getLayers().get(0).setVisible(true);
map.getLayers().get(1).setVisible(true);