LibGdx 3D地形网格渲染在OpenGL ES 1.0中工作,但不是2.0

时间:2014-01-05 14:43:36

标签: java opengl-es 3d libgdx

我已经扩展了LibGdx TerrainTest example和此Question,以便它可以渲染一组地形块给定一些高度图。这似乎在GL10中正常使用,但是当我使用modelbatch和默认着色器在GL20上移动代码时,网格不能完全呈现(参见图片 - 在这张图片中我们试图仅渲染一个32x32块)

Not Rendering Fully

这是应用程序的代码:

public class TerrainExperiment extends InputAdapter implements ApplicationListener {

private  PerspectiveCamera camera;
private long lastTime = TimeUtils.nanoTime();
private Terrain terrain;
private ModelBatch modelBatch;
private DefaultShader mockShader;

@Override
public void create () {

    terrain = new Terrain("testTerrain", 0, 0, "body", 32, 32, "137Industries",
            new Flat[]{
                    //new Flat(0, 0, 10, 5, 5, ColorHelper.toHex(Color.MAGENTA), "yeaaah" ),
                    //new Flat(5,5, 5, 7, 7, ColorHelper.toHex(Color.BLACK), "yolo")
            });

    //setup shader for terrain

    if(useGL20){

        //this is default shader, except we turn face culling off
        DefaultShader.Config config = new DefaultShader.Config();
        //turn off lights and culling, just in case
        config.defaultCullFace = 0;
        config.defaultDepthFunc = GL20.GL_LEQUAL;
        config.numPointLights = 0;
        config.numDirectionalLights = 0;

        mockShader = new DefaultShader(terrain.getModelInstance().getRenderable(new Renderable()), config);
        mockShader.init();

        modelBatch = new ModelBatch(new DefaultShaderProvider() {
            @Override
            public Shader getShader(Renderable renderable) {
                return mockShader;
            }

            @Override
            public void dispose() {
                mockShader.dispose();
            }
        });
    }

    camera = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    camera.position.set(-5f, 0, 0);
    camera.lookAt(0, 0, 0);
    camera.near = 0.1f;
    camera.far = 300f;
    camera.update();

}


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

}

@Override
public void render () {

    camera.update();

    if(useGL20){
        GL20 gl = Gdx.graphics.getGL20();
        gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
        gl.glEnable(GL20.GL_DEPTH_TEST);

        //render the terrain model using the model batch
        modelBatch.begin(camera);
        if(terrain != null){
            modelBatch.render(terrain.getModelInstance());
        }
        modelBatch.end();

    }else{
        GL10 gl = Gdx.graphics.getGL10();
        gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
        gl.glEnable(GL10.GL_DEPTH_TEST);
        camera.apply(gl); //for gl10
        //render meshes in the terrain model
        for (Mesh mesh : terrain.getModelInstance().model.meshes) {
            mesh.render(GL10.GL_TRIANGLES);
        }
    }

    handleInput(Gdx.input, Gdx.graphics.getDeltaTime());

    if (TimeUtils.nanoTime() - lastTime > 1000000000) {
        Gdx.app.log("TerrainExperiment", "fps: " + Gdx.graphics.getFramesPerSecond());
        lastTime = TimeUtils.nanoTime();
    }
}

@Override
public void pause() {    }

@Override
public void resume() {    }

@Override
public void dispose() {    }

private void handleInput (Input input, float delta) {
    if (input.isTouched()) {
        // simply modifying speed
        delta = delta + 0.0485f;

        // camera mouse look
        // find vector 90° to me
        Vector3 v90 = camera.direction.cpy();
        Quaternion q = new Quaternion(camera.up, 90);
        q.transform(v90);

        // go to plane x,z
        v90.y = 0;

        // set rotation up/down
        Quaternion qUpDown = new Quaternion(v90, Gdx.input.getDeltaY());

        // set rotation left/right
        Quaternion qLeftRight = new Quaternion(camera.up, -Gdx.input.getDeltaX());

        // apply the rotations
        qUpDown.transform(camera.direction);
        qLeftRight.transform(camera.direction);

    }

    if (input.isKeyPressed(Keys.W)) {
        Vector3 forward = new Vector3().set(camera.direction).scl(delta);
        camera.position.add(forward);
    }
    if (input.isKeyPressed(Keys.S)) {
        Vector3 backward = new Vector3().set(camera.direction).scl(delta);
        camera.position.sub(backward);
    }

    if (input.isKeyPressed(Keys.A)) {
        Vector3 left = new Vector3().set(camera.direction.cpy().crs(camera.up).nor()).scl(delta);
        camera.position.sub(left);
    }
    if (input.isKeyPressed(Keys.D)) {
        Vector3 right = new Vector3().set(camera.direction.cpy().crs(camera.up).nor()).scl(delta);
        camera.position.add(right);
    }
}

private static final boolean useGL20 = true; //change this to use GL10

public static void main(String[] args) {

    LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration();
    cfg.title = "BrowserThreeD";
    cfg.useGL20 = useGL20;
    cfg.width = 640;
    cfg.height = 480;
    new LwjglApplication(new TerrainExperiment(), cfg);

}

}

我用来制作地形块顶点和索引的代码是直接从我上面提到的SO question复制的。您可以在应用程序代码中看到我试图关闭面部剔除。我只能假设它必须是一个缠绕或重复的顶点问题,但我看不出它会吸引那么多的块?

如果这是相关的,这就是我从地形块网格中创建libgdx模型的方法:

Model result = new Model();

    int chunkNum = 0;
    for (TerrainChunk chunk : chunks) {

        Material material = heightMap.getMaterial();

        MeshPart meshPart = new MeshPart();
        meshPart.id = "terrainChunk" + chunkNum;
        meshPart.indexOffset = 0;
        meshPart.numVertices = chunk.getMesh().getNumVertices();
        meshPart.primitiveType = GL20.GL_TRIANGLES;
        meshPart.mesh = chunk.getMesh();

        NodePart nodePart = new NodePart();
        nodePart.material = material;
        nodePart.meshPart = meshPart;

        Node node = new Node();
        node.id = "terrainNode"+chunkNum;
        node.parts.add(nodePart);

        result.meshes.add(chunk.getMesh());
        result.materials.add(material);
        result.nodes.add(node);
        result.meshParts.add(meshPart);
        result.manageDisposable(chunk.getMesh());

        chunkNum++;
    }

发生了什么事?如果需要,我可以发布完整工作源的链接。

1 个答案:

答案 0 :(得分:4)

假设您的网格已编入索引,请使用:

meshPart.numVertices = chunk.getMesh().getNumIndices();

MeshPart#numVertices是要渲染的顶点总数,而不是网格中顶点的数量。另见:http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g3d/model/MeshPart.html