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.
Related
Im working on my 3D Game with LibGdx.
After looking some other Threads and posts with some realy good tutorials I get the first shader working. My Problem now is to get a Cel/Outline/Toon Shader working.
Therefore I found also a tutorial and a project but they havnt worked.
After reading some posts how to solve this shading Problem (with rendering the Object twice,...) I tried this method but got some sideeffects.
Actually I got as result a darfred rendering Scene.
My Question is now, If my Models just need some other Material or why I get these results.
I wrote a cel shader based on the KBAL tutorial that results in renderings like the one above. I've been meaning to write up something on it since the library has changed a lot since then. It seems like you got stuck on the depth shader, which is one of the parts from the original tutorial that needed the most updating.
Besides compatibility updates, I removed one render pass by modifying the uber shader that comes with LibGDX to perform the discretization in the KBAL tutorial's toonify() function during the initial rendering of geometry rather than in a post pass. Aside from that it follows the same pattern.
The code below is a bare bones implementation of my cel shader code. The class is derived extends AbstractScreen which implements some base functionality for LibGDX's Screen interface. Read more about Screen's here and see the CelTutorialScreen source within a full project context here.
package com.hh.ghoststory.screen;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.g3d.Environment;
import com.badlogic.gdx.graphics.g3d.Model;
import com.badlogic.gdx.graphics.g3d.ModelBatch;
import com.badlogic.gdx.graphics.g3d.ModelInstance;
import com.badlogic.gdx.graphics.g3d.environment.DirectionalLight;
import com.badlogic.gdx.graphics.glutils.FrameBuffer;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.utils.Array;
import com.hh.ghoststory.GhostStory;
import com.hh.ghoststory.render.shaders.CelDepthShaderProvider;
import com.hh.ghoststory.render.shaders.CelLineShaderProgram;
public class CelTutorialScreen extends AbstractScreen {
private PerspectiveCamera camera = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
private AssetManager assetManager = new AssetManager();
private Array<ModelInstance> instances = new Array<ModelInstance>();
private FrameBuffer fbo;
private TextureRegion textureRegion;
private ShaderProgram lineShader = new CelLineShaderProgram();
private SpriteBatch spriteBatch = new SpriteBatch();
private ModelBatch modelBatch = new ModelBatch(Gdx.files.classpath("com/badlogic/gdx/graphics/g3d/shaders/default.vertex.glsl").readString(), Gdx.files.internal("shaders/cel.main.fragment.glsl").readString());
private ModelBatch depthBatch = new ModelBatch(new CelDepthShaderProvider());
private Environment environment = new Environment();
public CelTutorialScreen(GhostStory game) {
super(game);
Gdx.gl.glClearColor(1.0f, 0.0f, 1.0f, 0.0f);
Gdx.gl.glClear(GL20.GL_DEPTH_BUFFER_BIT | GL20.GL_COLOR_BUFFER_BIT);
// setup camera
camera.position.set(5, 5, 5);
camera.lookAt(0, 0, 0);
camera.near = 1;
camera.far = 1000;
camera.update();
// add a light
environment.add(new DirectionalLight().set(0.8f, 0.8f, 1.8f, -1f, -0.8f, 0.2f));
// load our model
assetManager.load("models/spider.g3dj", Model.class);
loading = true;
}
#Override
public void render(float delta) {
if (loading && assetManager.update())
doneLoading();
camera.update();
Gdx.gl.glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
Gdx.gl.glClear(GL20.GL_DEPTH_BUFFER_BIT | GL20.GL_COLOR_BUFFER_BIT);
// render depth map to fbo
captureDepth();
// draw the scene
renderScene();
// put fbo texture in a TextureRegion and flip it
prepTextureRegion();
// draw the cel outlines
drawOutlines();
}
/*
* Draws the cel outlines using the CelLineShaderProgram
*/
protected void drawOutlines() {
spriteBatch.setShader(lineShader);
lineShader.setUniformf("u_size", Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
spriteBatch.begin();
spriteBatch.draw(textureRegion, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
spriteBatch.end();
spriteBatch.setShader(null);
}
/*
* Stores fbo texture in a TextureRegion and flips it vertically.
*/
protected void prepTextureRegion() {
textureRegion = new TextureRegion(fbo.getColorBufferTexture());
textureRegion.flip(false, true);
}
/*
* Draws the depth pass to an fbo, using a ModelBatch created with CelDepthShaderProvider()
*/
protected void captureDepth() {
fbo.begin();
Gdx.gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
Gdx.gl.glClear(GL20.GL_DEPTH_BUFFER_BIT | GL20.GL_COLOR_BUFFER_BIT);
depthBatch.begin(camera);
depthBatch.render(instances);
depthBatch.end();
fbo.end();
}
/*
* Renders the scene.
*/
protected void renderScene() {
Gdx.gl.glClear(GL20.GL_DEPTH_BUFFER_BIT | GL20.GL_COLOR_BUFFER_BIT);
modelBatch.begin(camera);
modelBatch.render(instances, environment);
modelBatch.end();
}
#Override
protected void doneLoading() {
loading = false;
instances.add(new ModelInstance(assetManager.get("models/spider.g3dj", Model.class)));
}
/*
* Set camera width and height, SpriteBatch projection matrix, and reinit the FBOs
*/
#Override
public void resize(int width, int height) {
camera.position.set(camera.position);
camera.viewportWidth = width;
camera.viewportHeight = height;
camera.update();
if (fbo != null) fbo.dispose();
fbo = new FrameBuffer(Pixmap.Format.RGBA8888, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true);
spriteBatch.setProjectionMatrix(new Matrix4().setToOrtho2D(0, 0, width, height));
}
#Override
public void dispose() {
assetManager.dispose();
modelBatch.dispose();
depthBatch.dispose();
spriteBatch.dispose();
fbo.dispose();
lineShader.dispose();
}
}
The render performs 3 passes to create the end product.
The first is contained in the captureDepth() function.
protected void captureDepth() {
fbo.begin();
Gdx.gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
Gdx.gl.glClear(GL20.GL_DEPTH_BUFFER_BIT | GL20.GL_COLOR_BUFFER_BIT);
depthBatch.begin(camera);
depthBatch.render(instances);
depthBatch.end();
fbo.end();
}
A framebuffer is started, glClear is called and then the depthBatch ModelBatch() renders the model instances (only one in this case) before the framebuffer is ended.
The depthBatch is a ModelBatch that uses a CelDepthShaderProvider, which provides a CelDepthShader. CellDepthShaderProvider is a small class that extends BaseShaderProvider and overrides createShader to return an instance of CelDepthShader, which registers and sets u_near and u_far uniforms as well as sets up the use of the cel depth vertex and fragment GLSL shaders.
I'm guessing the GLSL files are where you're running into issues. The vertex shader I linked to is the same as the KBAL vertex shader with the exception of line 125, which removed some artifacts on the cel edges:
v_depth = (pos.z + u_near) / (u_far - u_near);
The fragment shader is very similar to the one in the KBAL tutorial, but is actually copied from LibGDX's built in depth fragment shader. It's quite possible that the current LigGDX DepthShader could be used instead of my CelDepthShader, but I haven't had time to look into this.
After the first pass, the packed depth map has been captured by the FBO. The second pass is ready to be run and will draw the scene with LibGDXs' default vertex shader and a slightly modified version of its fragment shader.
The changes from the default fragment shader are in lines 140-150 where the specular value is discretized before being added to gl_FragColor:
if (specIntensity > 0.6)
specFactor = 1.0;
else if (specIntensity > 0.3)
specFactor = 0.5;
else
specFactor = 0.1;
specular *= specFactor;
And 173-182 where the overall gl_FragColor is discretized:
float intensity = max(gl_FragColor.r, max(gl_FragColor.g, gl_FragColor.b));
float factor;
if (intensity > 0.8)
factor = 1.0;
else if (intensity > 0.5)
factor = 0.8;
else if (intensity > 0.25)
factor = 0.3;
else
factor = 0.1;
And that's it for the main cel pass.
Next in render() the prepTextureRegion() function is called. This just puts the depth texture captured to our fbo into a texture region and flips it vertically before using it to draw the cel outlines in the final pass.
The final pass is performed in drawOutlines() and makes use of a SpriteBatch since we're drawing a 2d texture instead of geometry. The call to spriteBatch.setShader(lineshader) sets the SpriteBatch to use an instance of CelLineShaderProgram, another class that extends ShaderProgram. It sets a u_size uniform and uses cel.line.vertex.glsl and cel.line.fragment.glsl.
This shader program runs the Laplace filter. The vertex shader is copied from the KBAL edge shader and updated to work with newer versions of LibGDX, it passes the sampled coordinate of the depth map as well as its top, bottom, left and right neighboring texels to the fragment shader as varyings.
The fragment shader uses an updated method of unpacking the depth values based on code from the getShadowness() function here as recommended by Xoppa.
There are some improvements to this process that could be made. For one, I haven't implemented the super sampling in the original tutorial.
Also, it's not really noticeable in this still image, but once you have a controllable camera in the scene, or geometry moving around, you'll notice the per pixel lighting looks a little weird, especially with limited polygons in your geometry. There is a per-pixel lighting fragment shader in the LibGDX shadow system tests that could be used as a base to implement this with cel shading. The shadow systems might even be a good base to create a multi-pass rendering system for cel shading. And there is undoubtedly code that could be removed from the modified base LibGDX shaders I've used, as well as other optimizations and cleanup.
Hope this helps you or anyone else looking for info on multipass cel shading.
I have tried to make a ellipse object in libgdx. Sorry if i can't describe properly but im a newbie in java.
My code looks like:
public class GameScreen implements Screen{
MyGame game;
OrthographicCamera camera;
SpriteBatch batch;
...
Ellipse playBounds;
public GameScreen(MyGame game) {
this.game = game;
camera = new OrthographicCamera();
camera.setToOrtho(false, 1080, 1920);
batch = new SpriteBatch();
state = GAME_READY;
touchPoint = new Vector3();
pauseBounds = new com.badlogic.gdx.math.Rectangle(1080-128,1920-128,128,128);
playBounds= new Ellipse()
}
...
public void render(float delta) {
Gdx.gl.glClearColor(1F, 1F, 1F, 1F);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
generalupdate();
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(Assets.sprite_bg, 0, 0);
switch (state){
case GAME_READY:{
batch.draw(Assets.sprite_startScreen, 0, 0);
batch.draw(Assets.sprite_playButton,218,800,644,225);
break;
}
Basically it draws background, a welcome screen and a button(with "play" on it)
So here i made a touch detection.
if (Gdx.input.justTouched()) {
camera.unproject(touchPoint.set(Gdx.input.getX(), Gdx.input.getY(), 0));
if (state==GAME_READY);
if (playBounds.contains(touchPoint.x, touchPoint.y)) {
state=GAME_RUNNING;
Drawing works fine but the problem is when i touch the button it doesnt work instead if i touch near it game starts as it should
Alright, ignoring the several errors in the code which I will just assume were made here instead of the actual code, I believe the problem could be that you are not setting the values in the Ellipse. By this I mean the width, height, x, and y.
An nice way to do this would be to use the constructor:
Ellipse(float x, float y, float width, float height)
instead of just :
Ellipse()
That way you can set the values right away. Refer to this website for more info in Ellipses for LibGDX.
If that doesn't solve your problem you may have to post a little more of the relevant parts of your code.
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.
How can I move Sprite fluently?I have tried in this way.
#Override
public void render(float delta) {
Gdx.graphics.getGL20().glClearColor( 1F, 1F, 1F, 1F );
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
batch.begin();
mySprite.draw(batch);
mySprite.setX(BladeAnimation.bladeFalling());
batch.end();
}
I have changed xPosition with other function but the animation is not playing fluently.
You have to run the code that is changing the position in the render() method, other wise it changes only once. Unless if you are changing the position elsewhere. Show the code that changes the position to get a better answer
I have problem with background in libGdx.
I try solve mine problem with this:
"In your create() method, create a new Texture referencing your image.png, and then use your existing SpriteBatch to render it in the render() loop. Immediately after your GL.clear() call, go your batch.draw(backgroundTexture, 0. 0) and make sure you're in OrthographicProjection mode for your camera."
I do this:
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
camera.update();
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(image, 250, 200);
batch.draw(backGroundImage, 0, 0);
batch.end();
"image" is mine normal Texture (it's simple image), "backGround" is ofc. mine background.
I have "backGround" apply in mine create() method. Mine camer is on camera = new OrthographicCamera();.
Here is what I see:
... I need 10 points of reputation to add image :<... Image is to short and cut on lef and right...
What I doing wrong. On this solution a link! And a reference-style link to [a panda][1] Shinzul said something about loop in in render(), maybe this is mine problem but I dont know how to fix this.
Please help.
I think you should draw your backgroung image first.
Besides I think you should look at some tutorials, e.g. https://github.com/libgdx/libgdx/wiki/Spritebatch%2C-Textureregions%2C-and-Sprites. It explains same basic concepts of libgdx.
public static Texture backgroundTexture;
public static Sprite backgroundSprite;
private SpriteBatch spriteBatch;
private void loadTextures() {
backgroundTexture = new Texture("images/background.png");
backgroundSprite =new Sprite(backgroundTexture);
.
.
}
public void renderBackground() {
backgroundSprite.draw(spriteBatch);
}
public void render() {
spriteBatch.begin();
renderBackground(); //In first place!!!!
drawStuff();
drawMoreStuff();
drawMoreMoreStuff();
spriteBatch.end();
}
I found this online resource and helped me get started in the world of libgdx.
I hope I've been helpful.
Simply you can set device hight and width using Gdx, its help me
batch.draw(mTextureBg, 0 , 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
I don't know if this is the best way to do it but it worked for me.
sprite.scale(2);
sprite.setCenter(Gdx.graphics.getWidth()/2, Gdx.graphics.getHeight()/2);
You can change the scale in (int) until it covers the whole screen.