Dies ist ein Post-Processing-Shader, so dass Ihre Strömung so gehen sollte:
Zeichnen Sie Ihre Szene mit einem FBO in Pixel mit perfekter Auflösung Spritebatch-Standard Shader.
Zeichnen Sie die FBO-Textur mit dem Upscaling-Shader auf den Bildpuffer des Bildschirms. Sie können dies mit SpriteBatch tun, wenn Sie den Shader so ändern, dass er den Attributen und Uniformen entspricht, die SpriteBatch verwendet. (Sie können alternativ ein einfaches Gitter mit den Attributnamen erstellen, die der Shader erwartet, aber Spritebatch ist wahrscheinlich am einfachsten.)
Zunächst einmal sind wir ein typisches Shader mit Spritebatch nicht verwenden, so dass Sie ShaderProgram.pedantic = false;
anrufen müssen Irgendwo bevor man etwas lädt.
Jetzt benötigen Sie einen FrameBuffer in der richtigen Größe. Es sollte so dimensioniert sein, dass Ihre Sprites pixelgenau sind (ein Pixel der Textur skaliert zu einem Pixel der Welt). So etwas wie das:
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();
}
Dann können Sie auf den Bildspeicher zeichnen, als ob es Ihr Bildschirm ist. Danach zeichnen Sie die Textur des Bildspeichers auf den Bildschirm.
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();
}
Es gibt auch einige Änderungen, die Sie benötigen, um Ihre Shader zu machen, damit es mit OpenGL ES funktionieren wird, und weil Spritebatch für spezifisches Attribut und einheitliche Namen verdrahtet:
An der Spitze des Vertex-Shader fügen sie diese Ihre Vertex-Attribute und varyings (die verknüpften Shader muss nicht, weil es auf integrierte Variablen ist verlassen, die in GL eS nicht verfügbar sind) zu definieren:
attribute vec4 a_position;
attribute vec2 a_texCoord;
varying vec2 v_texCoord[5];
Dann in der Vertex-Shader, Ändern Sie die gl_Position
Zeile zu
gl_Position = a_position; //since we can't rely on built-in variables
und ersetzen alle Vorkommen von gl_TexCoord
mit v_texCoord
aus dem gleichen Grund.
Im Fragment-Shader müssen Sie, um mit OpenGL ES kompatibel zu sein, die Genauigkeit deklarieren. Sie müssen auch die gleiche Variation, so fügen Sie diese nach oben erklären:
#ifdef GL_ES
precision mediump float;
#endif
varying vec2 v_texCoord[5];
Wie bei den Vertex-Shader, ersetzen Sie alle Vorkommen von gl_TexCoord
mit v_texCoord
. Und ersetzen Sie auch alle Vorkommen von rubyTexture
durch u_texture
, das ist der Texturname, den SpriteBatch verwendet.
Ich denke, das ist alles. Ich habe das nicht wirklich getestet und ich gehe aus dem Gedächtnis, aber hoffentlich kommt es dir nahe.
Wie zeichnest du damit? Haben Sie ein Mesh erstellt oder verwenden Sie SpriteBatch? Ich nehme an, Sie verwenden die Textur von einem FrameBuffer? – Tenfour04
Ich benutze 'batch.setShader (shaderProgram);' in meiner render() Methode, so dass die Shader auf den SpriteBatch angewendet werden, dann zeichne ich alle meine Texturen – ryanrio95