I am having an issue with libgdx where when I load a model in any format the texture is not appearing correctly. I'm not sure what is causing this issue.
Example: In 3ds max or blender it looks like this
but when I put it into a libgdx project it looks like this
My code is based on http://blog.xoppa.com/loading-models-using-libgdx/
And I have tried it with and without the lights with no luck
Code:
//Loading the model
assetManager = new AssetManager();
assetManager.load("data/models/M4A1 SOPMOD/M4A1 SOPMOD.g3db", Model.class);
//..................................................
//Calling to an object and drawing it
public void create()
modelBatch = new ModelBatch();
box = Assets.assetManager.get("data/models/M4A1 SOPMOD/M4A1 SOPMOD.g3db", Model.class);
//box = Assets.getModelByName("M4");
//box = modelBuilder.createBox(1f, 1f, 1f, new Material(ColorAttribute.createDiffuse(Color.WHITE), ColorAttribute.createSpecular(Color.WHITE), FloatAttribute.createShininess(64f)), Usage.Position | Usage.Normal);
boxInstance = new ModelInstance(box);
lights = new Lights();
lights.ambientLight.set(1f, 1f, 1f, 1f);
lights.add(new DirectionalLight().set(1f, 1f, 1f, -1f, -0.8f, -0.2f));
}
public void Update(float deltaTime)
{
dotd.camera.rotateAround(Vector3.Zero, new Vector3(0, 1, 0), deltaTime* 50.0f);
dotd.camera.update();
}
public void Render()
{
modelBatch.begin(dotd.camera);
modelBatch.render(boxInstance, lights);
modelBatch.end();
}
My first guess would be that the texture coordinates need to be flipped, try adding (or removing) the -f command line option of fbx-conv (.e.g fbx-conv -f model.fbx).
You also might want to check your normals. Add the following line to your create method: DefaultShader.defaultCullFace = 0; and don't apply lights. If this renders your model better, you probably need to recalculate the normals in 3ds max or blender. Don't forget to remove the defaultCullFace line afterwards.
Finally, obviously, make sure the correct texture is loaded and don't use high poly models.
Related
I have created a sphere using Texture by calling createSphere() method on modelBuilder using libGDX. As it is 3D, I used Perspective Camera. I am trying to move the sphere on the screen with the mouse. Its working fine, but the sphere had been changing its shape while moving on the screen.
I tried by changing the position and lookAt of the Perspective Camera. Still, shape is changing. Can anyone suggest the solution.
Here is my part of the code:
modelBatch = new ModelBatch();
ModelBuilder modelBuilder = new ModelBuilder();
Texture texture = new Texture(Gdx.files.internal("ball.png"));
Material material = new
Material(TextureAttribute.createDiffuse(texture));
final long attributes = VertexAttributes.Usage.Position |
VertexAttributes.Usage.TextureCoordinates;
sphere = modelBuilder.createSphere(0.5f, 0.5f, 0.5f, 24, 24, material, attributes);
sphereInstance = new ModelInstance(sphere);
perCamera = new PerspectiveCamera(67, Gdx.graphics.getWidth(),
Gdx.graphics.getHeight());
perCamera.position.set(0f, 0f, 3f);
perCamera.lookAt(0f,0f,0f);
perCamera.near = 1f;
perCamera.far = 300f;
perCamera.update();
[Here I have attached screenshot for the reference, in which the regular sphere changes its shape to ellipse as it is moving away from the camera.][1]
I'm trying to learn the 3D side of LibGDX, and I've came to a problem. I want to draw a line from 0, 0, -5 to 0, 0, 5. I've tried a few things to make this work.
First I looked to see if I could create a line as a Model. As far as I can see, I can't do this.
What I then realised is that theoretically I can draw a line using a ShapeRenderer. Here's my code to try to do this.
public class Main implements ApplicationListener {
...
public ShapeRenderer srend;
...
#Override
public void create() {
...
srend = new ShapeRenderer();
srend.setColor(Color.RED);
...
}
#Override
public void render() {
...
srend.begin(ShapeType.Line);
srend.line(0, 0, -5, 0, 0, 5);
srend.end();
...
}
...
}
But for some reason this doesn't appear to work. I use ShapeRenderers a lot, but it's possible that I'm making a mistake initializing or using it, I don't think that's the problem though.
I've only just started using the 3D part of LibGDX, so I assume the problem is around where I'm drawing the actual line.
Model Builder works well for me.
ModelBuilder modelBuilder = new ModelBuilder();
modelBuilder.begin();
MeshPartBuilder builder = modelBuilder.part("line", 1, 3, new Material());
builder.setColor(Color.RED);
builder.line(0.0f, 0.0f, -5.0f, 0.0f, 0.0f, 5.0f);
lineModel = modelBuilder.end();
lineInstance = new ModelInstance(lineModel);
You need to set camera matrix before rendering:
#Override
public void create() {
...
srend = new ShapeRenderer();
srend.setProjectionMatrix(new Matrix4())
srend.setColor(Color.RED);
...
}
I don't know why, but this helps. Matrix4() is just identity matrix. With identity camera matrix right side of the screen has coordinate 1, left -1. So if coordinates inside cube -1..1, you should see them.
In real code (for example, for drawing gizmos in 3d world) you can set matrix from PerspectiveCamera:
shapeRenderer.setProjectionMatrix(camera.combined)
I am trying to add text for debugging purposes in my program. I call the players debugDraw method like so in the main class:
public void create () {
//Initialize essentials
cam = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
cam.setToOrtho(false);
rend = new ShapeRenderer();
rend.setAutoShapeType(true);
batch = new SpriteBatch();
// Initialize Entities
player = new Player(new Vector2(100, 100), new Vector2(100,100));
enemy = new Enemy(new Vector2(100, 100), new Vector2(100,10));
}
#Override
public void render () {
//Update player
player.update();
//Update camera then set matrix of batch
cam.update();
batch.setTransformMatrix(cam.combined);
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
// ShapeRenderer begin
rend.begin();
player.render(rend);
enemy.render(rend);
rend.end();
// ShapeRenderer end
// SpriteBatch begin
batch.begin();
player.renderDebugText(batch);
batch.end();
// SpriteBatch end
}
Here is the entity class which is the parent class to player:
public Entity(Vector2 coords, Vector2 dims){
//Assign constructors
position = coords;
dim = dims;
//For debugging purposes of all entities
debugText = new BitmapFont();
debugText.setColor(Color.WHITE);
}
public void renderDebugText(SpriteBatch batch){
debugText.draw(batch, "Vel.x: " + vel.x, 100, 100);
}
However when I run the program, I just get my normal screen with no text at all. I can't seem to figure out why this isn't working. Any help is extremely appreciated.
Nothing immediately looks wrong with the code you posted, so here's a few ideas;
The default BitmapFont is 15pt, if this is drawn at 15px height then it could be very small if you force your game to a high resolution, like Full-HD. My current project is Full-HD and the font I use looks just about right at 45px, so you could try scaling yours by a factor of 3 or 4. E.g. use this after initialising your font;
bitmapFont.getData().setScale(3);
Your Camera should also have the virtual/viewport dimensions, so if you are forcing a particular resolution then you should pass in your virtual dimensions instead.
As #Tenfour04 has suggested, you should try to avoid multiple instances of the same font, so instead of initialising your font in the Entity class, initialise it in your main game and pass it through the Entity constructor. I can't see how this would fix your issue though as this would be purely for performance.
I made a very simple mistake, but from how much code I posted, it is easily missed. On the line where I put
batch.setTransformMatrix(cam.combined);
it should be replaced with
batch.setProjectionMatrix(cam.combined);
Then all errors go away, sorry, I don't know why it took me so long to figure out. Thanks for all the help!
I get nothing but a black screen when trying to load and render an .obj model using libgdx.
I have tried different models (exporting using blender in .obj format) I've tried loading .g3db files instead of obj files and come up with the same result. Nothing renders onscreen but my glClearColor (and yes I've tried something other than black to see if my model was rendering pure black) I have all the assets loading correctly for an .obj file (skeleton.mtl, skeleton.obj, texture.png) and I'm sure my code is doing something with them because if I remove say, the texture.png, I get an error saying it cannot find the asset. So why do I get NOTHING when rendering? I would like to understand why this is happening. Here is my code:
public void show() {
modelBatch = new ModelBatch();
environment = new Environment();
environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 0.4f, 0.4f, 1f));
environment.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.2f));
cam = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
cam.position.set(1f, 1f, 1f);
cam.lookAt(0,0,0);
cam.near = 0.1f;
cam.far = 300f;
cam.update();
ModelLoader loader = new ObjLoader();
model = loader.loadModel(Gdx.files.internal("models/skeleton.obj"));
instance = new ModelInstance(model);
camController = new CameraInputController(cam);
Gdx.input.setInputProcessor(camController);
ModelLoader loader = new ObjLoader();
model = loader.loadModel(Gdx.files.internal("models/skeleton.obj"));
instance = new ModelInstance(model);
camController = new CameraInputController(cam);
Gdx.input.setInputProcessor(camController);
Then my Render loop:
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
camController.update();
modelBatch.begin(cam);
modelBatch.render(instance, environment);
modelBatch.end();
}
I forgot to clear my Depth buffer.
In my:
public void render(float delta) {
I changed this:
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
to this
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
If you were using GL10 it would go like this:
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
I knew it was something stupid. I also made the changes suggested by the other poster about making sure my Transparency is set above zero in blender and also backing off my camera because the camera was too close, it wasnt rendering anything at that distance also. Thank you.
cam.position.set(1f, 1f, 1f);
cam.lookAt(0,0,0);
cam.near = 0.1f;
Your camera is way to near the origin, so your object may be too big and the camera may be "inside" it, so it wont be rendered.
Also, you probably exported your object with zero opacity:
https://github.com/libgdx/libgdx/wiki/Importing-Blender-models-in-LibGDX#wiki-troubleshooting-missing-textures
Also, it is quite common that the materials from Blender export with opacity set to Zero. If you notice your model is not being rendered. Go to the Material in Blender, and below "Transparency" set its Alpha to the desired one (usually 1, for full opacity).
I'm trying to implement a basic physics engine in Java and I'm using the JOGL bindings so I can visualize the results. I can create and rotate shapes easily enough, but have run into problems whilst manipulating the viewport and whilst moving the shapes.
I don't think a clipping issue - I've tried using the gluPerspective method with a massive range (0.0001f - 10000f) with no success. When I move the camera further away from my objects or move the objects themselves, they disappear.
Tutorials about JOGL are few and far between and many also use different versions of OpenGL, so I turn to the only friend I have left: the wonderful users of stack overflow. :)
Flattery aside, the code follows:
public class JoglEventListener implements GLEventListener, KeyListener, MouseListener, MouseMotionListener {
// keep pointer to associated canvas so we can refresh the screen (equivalent to glutPostRedisplay())
public GLCanvas canvas;
public Particle triforce;
public float x;
// constructor
public JoglEventListener(GLCanvas canvas) {
this.canvas = canvas;
}
#Override
public void display(GLAutoDrawable drawable) {
update();
render(drawable);
}
#Override
public void init(GLAutoDrawable drawable) {
triforce = new Particle();
x = 0;
}
private void update() {
triforce.integrate(0.0001);
x = x + 0.25f;
}
private void render(GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
GLU glu = new GLU();
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glLoadIdentity();
//gl.glFrustum (.5f, -.5f, -.5f * 1080, .5f * 960, 1.f, 500.f);
glu.gluPerspective(0, 1, 0.1f, 100f);
gl.glMatrixMode(GL2.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glHint(GL2.GL_CLIP_VOLUME_CLIPPING_HINT_EXT,GL2.GL_FASTEST);
glu.gluLookAt(0, 0, 1.5, 0, 0, -10, 0, 1, 0);
//gl.glRotatef(90, 0f , 1f , 0f );
//Draw some scale lines
gl.glBegin(GL.GL_LINES);
gl.glColor3f(0.75f, 0.75f, 0.75f);
for (int i = 0; i < 20; i += 1)
{
gl.glVertex3f(-5.0f, 0.0f, i + 0.5f);
gl.glVertex3f(5.0f, 0.0f, i + 0.5f);
}
gl.glEnd();
//gl.glRotatef(x, 1f , 1f , 1f );
gl.glPushMatrix();
gl.glTranslated(triforce.position.x, triforce.position.y, triforce.position.z);
gl.glBegin(GL.GL_TRIANGLE_STRIP);
gl.glColor3f(1f, 0f, 0f);
gl.glVertex3d(0, 0, -2);
gl.glColor3f(0f, 1f, 0f);
gl.glVertex3d(0, 0.25d, -2);
gl.glColor3f(0f, 0f, 1f);
gl.glVertex3d(0.25d, 0, -2);
gl.glColor3f(1f, 1f, 0f);
gl.glVertex3d(0.25d, 0.25d, -2.25d);
gl.glEnd();
gl.glPopMatrix();
gl.glFlush();
}
// (empty overridden methods omitted)
public Particle () {
setMass(200d);
velocity = new Vector3(0d, 30d, 40d);
acceleration = new Vector3(0d, -20d, 0d);
position = new Vector3(0d, 0d, 0d);
damping = 0.99d;
}
public void integrate (double duration) {
if (inverseMass <= 0.0d) {
return;
}
assert (duration > 0.0);
position.addScaledVector(velocity, duration);
Vector3 resultingAcc = new Vector3(acceleration.x, acceleration.y, acceleration.z);
velocity.addScaledVector(resultingAcc, duration);
velocity.multEquals(Math.pow(damping, duration));
//clearAccumulator();
}
public void setMass(double mass)
{
assert(mass != 0);
inverseMass = (1.0d)/mass;
}
Before movement / starting position:
The shape drifts upward and is obscured from the right and top, becoming invisible:
Any help would be greatly appreciated! Thanks!
The massive view range can be a problem. The coordinates of the objects are only so precise, and with a huge view range, things that should be near each other are determined to be at the same point. This can cause an object that should be in front of another to disappear behind it. Try using a smaller view range.
I had the same problem. Objects disappearing, while some stay in the scene. After removing:
gl.glEnable(GL2.GL_CULL_FACE);
everything was working just fine ! Of course this is JOGL code, in C, the command would be without all those objects. Just to make this answer clear for everyone.
In the render function, change the value of last parameter of gluPerspective from 100f to 1000f. It will solve your problem.
gl.gluPerspective(0, 1, 0.1f, 100f);
to
gl.gluPerspective(0, 1, 0.1f, 500f);
And I think in your code you have done a mistake in the above line writing glu.gluperspective
I think it is gl.gluPerspective.
In the end, I was never able to track down the issue, and started again from scratch. I didn't run into any further clipping issues on my new build.
My best guess as to my initial failure is an improperly used glHint or glClear call, or perhaps some problem with the version of JOGL I was referencing.