【问题标题】:libgdx: How do i get the result of an orthographic camera through another orthographic camera?libgdx:如何通过另一个正交相机获得正交相机的结果?
【发布时间】:2021-07-30 10:16:31
【问题描述】:

我想在我的舞台上安装一个电视屏幕。我有一个包含电视屏幕和其他一些东西(一些精灵)的主场景,以及与我想在电视中渲染的内容相对应的场景。

所以我想通过 OrthographicCamera 渲染电视场景,然后将结果放入类似精灵的东西中,然后可以通过主正交相机渲染,该怎么做?

我知道可以在多个视口中使用多个摄像头,但这些都是直接渲染在我电脑屏幕的像素上的。

任何建议将不胜感激

【问题讨论】:

  • 这是 3D 还是 2D?
  • 我只使用 2D 功能

标签: libgdx


【解决方案1】:

这可以通过从屏幕摄像头的角度将场景渲染到FrameBuffer,然后从FrameBuffer 获取TextureRegion 并将其渲染到屏幕,然后再次渲染场景来实现。

例如:

在上面的例子中,青色矩形显示了场景内摄像机所看到的内容,并将其渲染为灰色框,可以独立移动场景摄像机和主摄像机。

通过从FrameBuffer 中创建和获取TextureRegion

screenFrameBuffer = new FrameBuffer(Pixmap.Format.RGBA8888, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(),true);
screenTexture = new TextureRegion(screenFrameBuffer.getColorBufferTexture());
screenTexture.flip(false, true);

通过调用screenFrameBuffer.begin(),可以进行所有渲染调用以仅影响screenFrameBuffer,在调用screenFrameBuffer.end() 之后,下一次绘制调用将再次影响实际的屏幕/窗口。

所以在render 方法中,您可以先将场景绘制到FrameBuffer

screenFrameBuffer.begin();
renderScene(screenCamera, Color.DARK_GRAY);
screenFrameBuffer.end();

然后再画一遍,后面跟着“screen”作为精灵:

renderScene(sceneCamera, Color.BLACK);

batch.setProjectionMatrix(sceneCamera.combined);
batch.begin();
batch.draw(screenTexture, -sceneCamera.viewportWidth / 2.0f,-sceneCamera.viewportHeight / 2.0f,0,0,screenCamera.viewportWidth,screenCamera.viewportHeight,1.0f, 1.0f, 0.0f);
batch.end();

以上gif的完整源代码为:

package com.bornander.sandbox;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.*;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.glutils.FrameBuffer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.RandomXS128;
import com.badlogic.gdx.math.Vector2;

public class MyGdxGame implements ApplicationListener {

    public static class Ball {
        public Vector2 position = new Vector2();
        public Vector2 velocity = new Vector2();
        public float size = 1.0f;
        public Color color = new Color();

        public void render(ShapeRenderer shapeRenderer) {
            shapeRenderer.setColor(color);
            shapeRenderer.circle(position.x, position.y, size, 16);
        }

        public void update() {
            position.x += velocity.x * Gdx.graphics.getDeltaTime();
            position.y += velocity.y * Gdx.graphics.getDeltaTime();
        }
    }

    static RandomXS128 rnd = new RandomXS128();

    OrthographicCamera sceneCamera;
    OrthographicCamera screenCamera;
    ShapeRenderer shapeRenderer;
    SpriteBatch batch;

    FrameBuffer screenFrameBuffer;
    TextureRegion screenTexture;
    Ball[] balls;

    private static float rnd(float min, float max) {
        return min + rnd.nextFloat() * (max - min);
    }

    @Override
    public void create() {
        float aspectRatio = (float) Gdx.graphics.getWidth() / (float)Gdx.graphics.getHeight();
        sceneCamera = new OrthographicCamera(100.0f, 100.0f / aspectRatio);
        screenCamera = new OrthographicCamera(32.0f, 32.0f / aspectRatio);

        batch = new SpriteBatch();

        screenFrameBuffer = new FrameBuffer(Pixmap.Format.RGBA8888, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(),true);
        screenTexture = new TextureRegion(screenFrameBuffer.getColorBufferTexture());
        screenTexture.flip(false, true);
        shapeRenderer = new ShapeRenderer();

        balls = new Ball[128];
        for(int i = 0; i < balls.length; ++i) {
            balls[i] = new Ball();
            balls[i].position.set(0, 0);
            balls[i].velocity.set(rnd(-4, 4), rnd(-4, 4));
            balls[i].size = rnd(1, 1);
            balls[i].color.set(rnd(0.5f, 1.0f), rnd(0.5f, 1.0f), rnd(0.5f, 1.0f), 1.0f);
        }
    }

    private void renderScene(Camera camera, Color background) {
        camera.update();
        Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        Gdx.gl.glClearColor(background.r, background.g, background.b, background.a);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
        shapeRenderer.setProjectionMatrix(camera.combined);
        shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
        for(int i = 0; i < balls.length; ++i) {
            balls[i].render(shapeRenderer);
        }
        shapeRenderer.end();

    }

    @Override
    public void render() {
        float cs = 8.0f;
        for(int i = 0; i < balls.length; ++i)
            balls[i].update();

        if (Gdx.input.isKeyPressed(Input.Keys.LEFT))
            sceneCamera.position.x -= cs * Gdx.graphics.getDeltaTime();
        if (Gdx.input.isKeyPressed(Input.Keys.RIGHT))
            sceneCamera.position.x += cs * Gdx.graphics.getDeltaTime();
        if (Gdx.input.isKeyPressed(Input.Keys.UP))
            sceneCamera.position.y -= cs * Gdx.graphics.getDeltaTime();
        if (Gdx.input.isKeyPressed(Input.Keys.DOWN))
            sceneCamera.position.y += cs * Gdx.graphics.getDeltaTime();

        if (Gdx.input.isKeyPressed(Input.Keys.A))
            screenCamera.position.x -= cs * Gdx.graphics.getDeltaTime();
        if (Gdx.input.isKeyPressed(Input.Keys.D))
            screenCamera.position.x += cs * Gdx.graphics.getDeltaTime();
        if (Gdx.input.isKeyPressed(Input.Keys.W))
            screenCamera.position.y -= cs * Gdx.graphics.getDeltaTime();
        if (Gdx.input.isKeyPressed(Input.Keys.S))
            screenCamera.position.y += cs * Gdx.graphics.getDeltaTime();

        // Render to framebuffer, clear the background to DARK_GRAY
        screenFrameBuffer.begin();
        renderScene(screenCamera, Color.DARK_GRAY);
        screenFrameBuffer.end();

        // Render to window/screen, clear backgroun to BLACK
        renderScene(sceneCamera, Color.BLACK);

        // Draw the framebuffer's texture as a sprite using a normal SpriteBatch
        batch.setProjectionMatrix(sceneCamera.combined);
        batch.begin();
        batch.draw(screenTexture, -sceneCamera.viewportWidth / 2.0f,-sceneCamera.viewportHeight / 2.0f,0,0,screenCamera.viewportWidth,screenCamera.viewportHeight,1.0f, 1.0f, 0.0f);
        batch.end();

        // This just draws the outline of what the screen camera looks at
        shapeRenderer.setProjectionMatrix(sceneCamera.combined);
        shapeRenderer.begin(ShapeRenderer.ShapeType.Line);
        shapeRenderer.setColor(Color.CYAN);
        shapeRenderer.rect(
                screenCamera.position.x - screenCamera.viewportWidth / 2.0f,
                screenCamera.position.y - screenCamera.viewportHeight / 2.0f,
                screenCamera.viewportWidth,
                screenCamera.viewportHeight

        );
        shapeRenderer.end();
    }

    @Override
    public void dispose() {
    }

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

    @Override
    public void pause() {
    }

    @Override
    public void resume() {
    }
}

【讨论】:

    猜你喜欢
    • 2019-10-07
    • 1970-01-01
    • 2014-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多