无法在 libgdx 内关灯

Can't turn light off in libgdx

使用下面的代码,如果我把灯关掉,蓝色框就会变成黑色。

不过实体好像没什么效果,还是五颜六色的。代码有什么问题?请帮忙谢谢。

package com.louxiu.game;

/**
 * Created by louxiu on 2/22/16.
 */

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL30;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.graphics.g3d.*;
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
import com.badlogic.gdx.graphics.g3d.attributes.TextureAttribute;
import com.badlogic.gdx.graphics.g3d.loader.ObjLoader;
import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder;
import com.badlogic.gdx.math.Vector3;

public class TestApp implements ApplicationListener {
    private PerspectiveCamera camera;
    private ModelBatch modelBatch;
    private Model box;
    private ModelInstance boxInstance;
    public Model entityModel;
    public ModelInstance entityInstance;
    private Environment environment;

    @Override
    public void create() {
        // Create camera sized to screens width/height with Field of View of 75 degrees
        camera = new PerspectiveCamera(
                75,
                Gdx.graphics.getWidth(),
                Gdx.graphics.getHeight());

        // Move the camera 3 units back along the z-axis and look at the origin
        camera.position.set(0f, 0f, 3f);
        camera.lookAt(0f, 0f, 0f);

        // Near and Far (plane) repesent the minimum and maximum ranges of the camera in, um, units
        camera.near = 0.1f;
        camera.far = 300.0f;

        // A ModelBatch is like a SpriteBatch, just for models.  Use it to batch up geometry for OpenGL
        modelBatch = new ModelBatch();

        // A ModelBuilder can be used to build meshes by hand
        ModelBuilder modelBuilder = new ModelBuilder();

        // It also has the handy ability to make certain premade shapes, like a Cube
        // We pass in a ColorAttribute, making our cubes diffuse ( aka, color ) red.
        // And let openGL know we are interested in the Position and Normal channels
        box = modelBuilder.createBox(2f, 2f, 2f,
                new Material(ColorAttribute.createDiffuse(Color.BLUE)),
                Usage.Position | Usage.Normal
        );

        // A entityModel holds all of the information about an, um, entityModel, such as vertex data and texture info
        // However, you need an entityInstance to actually render it.  The entityInstance contains all the
        // positioning information ( and more ).  Remember Model==heavy ModelInstance==Light
        boxInstance = new ModelInstance(box, 0, 0, 0);

        String entity = "creeper/creeper";
        ObjLoader loader = new ObjLoader();
        entityModel = loader.loadModel(Gdx.files.internal(entity + ".obj"), new ObjLoader.ObjLoaderParameters(true));
        entityInstance = new ModelInstance(entityModel, 0, 0, 0);
        Texture texture = new Texture(Gdx.files.internal(entity + ".png"));
        entityInstance.materials.get(0).set(TextureAttribute.createDiffuse(texture));

        // Finally we want some light, or we wont see our color.  The environment gets passed in during
        // the rendering process.  Create one, then create an Ambient ( non-positioned, non-directional ) light.
        environment = new Environment();
        // environment.add(new DirectionalLight().set(1f, 1f, 1f, -1f, -0.8f, -0.2f));
        // environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.8f, 0.8f, 0.8f, 1.0f));
    }

    @Override
    public void dispose() {
        modelBatch.dispose();
        box.dispose();
    }

    @Override
    public void render() {
        // You've seen all this before, just be sure to clear the GL_DEPTH_BUFFER_BIT when working in 3D
        Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT | GL30.GL_DEPTH_BUFFER_BIT);

        // For some flavor, lets spin our camera around the Y axis by 1 degree each time render is called
        camera.rotateAround(Vector3.Zero, new Vector3(0, 1, 0), 1f);
        // When you change the camera details, you need to call update();
        // Also note, you need to call update() at least once.
        camera.update();

        // Like spriteBatch, just with models!  pass in the box Instance and the environment
        modelBatch.begin(camera);
        modelBatch.render(boxInstance, environment);
        // modelBatch.render(entityInstance, environment);
        modelBatch.end();
    }

    @Override
    public void resize(int width, int height) {
    }

    @Override
    public void pause() {
    }

    @Override
    public void resume() {
    }

您的波前模型可能没有法线,这是照明工作所必需的。

检查日志,应该有一条错误消息告诉您您不应该完全使用 ObjLoader。而是使用 G3dModelLoader 甚至更好:使用 AssetManagerg3djg3db 文件格式。

将您的模型从您的建模应用程序导出到例如FBX 文件格式并使用 fbx-conv 转换它。不要使用 fbx-conv 将您的 .obj 文件转换为 .g3dx 文件,那是行不通的。

顺便说一句,虽然不相关,但您可能需要考虑:

您的相机 far/near 比率非常高,您通常不应使用低于 1near 值。

与您的评论不同,ModelBatch is not used to batch geometry and not that comparable to SpriteBatch

ObjLoader 有一个接受 booleanloadModel 方法,因此您不必为此创建 ObjLoaderParameters(尽管如前所述,您不应该总共使用 ObjLoader)。

您正在创建一个 Texture,但没有在不再需要时妥善处理它。这将导致潜在的资源泄漏。

每帧都创建一个新的 Vector3 会给 GC 带来压力,并会导致 hick-ups。只需使用 Vector3.Y 而不是 new Vector3(0, 1, 0) 来解决这个问题。