这是一个后期处理着色器,所以你的流程应该是这样的:
使用 SpriteBatch 的默认着色器以像素完美分辨率将场景绘制到 FBO。
使用放大着色器将 FBO 的纹理绘制到屏幕的帧缓冲区。如果您修改着色器以匹配 SpriteBatch 使用的属性和制服,则可以使用 SpriteBatch 执行此操作。 (您也可以使用着色器期望的属性名称创建一个简单的网格,但 SpriteBatch 可能是最简单的。)
首先,我们没有使用带有 SpriteBatch 的典型着色器,因此您需要在加载任何内容之前在某处调用 ShaderProgram.pedantic = false;。
现在您需要一个大小合适的 FrameBuffer。它的大小应该使您的精灵完美像素(纹理的一个像素缩放到世界的一个像素)。像这样的:
public void resize (int width, int height){
float ratio = (float)width / (float) height;
int gameWidth = (int)(GAME_HEIGHT / ratio);
boolean needNewFrameBuffer = false;
if (frameBuffer != null && (frameBuffer.getWidth() != gameWidth || frameBuffer.getHeight() != GAME_HEIGHT)){
frameBuffer.dispose();
needNewFrameBuffer = true;
}
if (frameBuffer == null || needNewFrameBuffer)
frameBuffer = new FrameBuffer(Format.RGBA8888, gameWidth, GAME_HEIGHT);
camera.viewportWidth = gameWidth;
camera.viewportHeight = GAME_HEIGHT;
camera.update();
}
然后,您可以将其绘制到帧缓冲区,就好像它是您的屏幕一样。之后,将帧缓冲区的纹理绘制到屏幕上。
public void render (){
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
frameBuffer.begin();
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
batch.setShader(null); //use default shader
batch.begin();
//draw your game
batch.end();
frameBuffer.end();
batch.setShader(upscaleShader);
batch.begin();
upscaleShader.setUniformf("rubyTextureSize", frameBuffer.getWidth(), frameBuffer.getHeight());//this is the uniform in your shader. I assume it's wanting the scene size in pixels
batch.draw(frameBuffer.getColorBufferTexture(), -1, 1, 2, -2); //full screen quad for no projection matrix, with Y flipped as needed for frame buffer textures
batch.end();
}
您还需要对着色器进行一些更改,以便它可以与 OpenGL ES 一起使用,并且因为 SpriteBatch 已连接到特定属性和统一名称:
在您的顶点着色器顶部,添加它以定义您的顶点属性和变量(您的链接着色器不需要这些,因为它依赖于 GL ES 中不可用的内置变量):
attribute vec4 a_position;
attribute vec2 a_texCoord;
varying vec2 v_texCoord[5];
然后在顶点着色器中,将gl_Position这一行改为
gl_Position = a_position; //since we can't rely on built-in variables
出于同样的原因,将所有出现的gl_TexCoord 替换为v_texCoord。
在片段着色器中,要与 OpenGL ES 兼容,您需要声明精度。您还需要声明相同的变量,因此将其添加到顶部:
#ifdef GL_ES
precision mediump float;
#endif
varying vec2 v_texCoord[5];
与顶点着色器一样,将所有出现的gl_TexCoord 替换为v_texCoord。并且还将所有出现的rubyTexture 替换为u_texture,这是SpriteBatch 使用的纹理名称。
我认为这就是一切。我实际上并没有对此进行测试,而且我的内存不足,但希望它能让你接近。