我想用LibGDX製作復古風格的小遊戲,我想讓玩家選擇幾個字符的顏色,所以我想了想加載png索引圖像,然後以編程方式更新調色板...我錯過了多少錯誤^^用OpenGL着色器模擬調色板互換(在LibGDX中)
看來,顏色托盤是過去的東西,而且似乎最好的選擇來實現類似的結果是通過使用着色器。
這裏是一個圖像解釋什麼,我想現在:
我的本意是用2個圖像。其中之一,pixel_guy.png
是一個只有6種顏色(這些顏色是它的原始調色板)的PNG圖像。另一個圖像colortable.png
將是一個6x6像素的png,它包含6個顏色的6個調色板(每行是不同的調色板)。來自第一行像素colortable.png
的顏色將與pixel_guy.png
中使用的顏色相匹配,這將是第一個/原始調色板,其他行將是第2到第6個調色板。我嘗試實現的是使用colortable的第一個調色板索引pixelguy顏色,然後通過向着色器發送一個數字(從2到6)來更改調色板。
經過一番研究,我發現了一個post in gamedev stackexchange,顯然這是我在找的東西,所以我試着去測試它。
我創建了頂點和片段着色器,並加載了我的紋理(我想要交換的調色板和包含多個調色板的紋理),但輸出是意外的白色圖像。
我的頂點着色器:
attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;
uniform mat4 u_projTrans;
varying vec4 v_color;
varying vec2 v_texCoords;
void main() {
v_color = a_color;
v_texCoords = a_texCoord0;
gl_Position = u_projTrans * a_position;
}
我的片段着色器:
// Fragment shader
// Thanks to Zack The Human https://gamedev.stackexchange.com/questions/43294/creating-a-retro-style-palette-swapping-effect-in-opengl/
uniform sampler2D texture; // Texture to which we'll apply our shader? (should its name be u_texture?)
uniform sampler2D colorTable; // Color table with 6x6 pixels (6 palettes of 6 colors each)
uniform float paletteIndex; // Index that tells the shader which palette to use (passed here from Java)
void main()
{
vec2 pos = gl_TexCoord[0].xy;
vec4 color = texture2D(texture, pos);
vec2 index = vec2(color.r + paletteIndex, 0);
vec4 indexedColor = texture2D(colorTable, index);
gl_FragColor = indexedColor;
}
我用來使紋理結合和通過調色板號碼到着色器中的代碼:
package com.test.shaderstest;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
public class ShadersTestMain extends ApplicationAdapter {
SpriteBatch batch;
Texture imgPixelGuy;
Texture colorTable;
private ShaderProgram shader;
private String shaderVertIndexPalette, shaderFragIndexPalette;
@Override
public void create() {
batch = new SpriteBatch();
imgPixelGuy = new Texture("pixel_guy.png"); // Texture to which we'll apply our shader
colorTable = new Texture("colortable.png"); // Color table with 6x6 pixels (6 palettes of 6 colors each)
shaderVertIndexPalette = Gdx.files.internal("shaders/indexpalette.vert").readString();
shaderFragIndexPalette = Gdx.files.internal("shaders/indexpalette.frag").readString();
ShaderProgram.pedantic = false; // important since we aren't using some uniforms and attributes that SpriteBatch expects
shader = new ShaderProgram(shaderVertIndexPalette, shaderFragIndexPalette);
if(!shader.isCompiled()) {
System.out.println("Problem compiling shader :(");
}
else{
batch.setShader(shader);
System.out.println("Shader applied :)");
}
shader.begin();
shader.setUniformi("colorTable", 1); // Set an uniform called "colorTable" with index 1
shader.setUniformf("paletteIndex", 2.0f); // Set a float uniform called "paletteIndex" with a value 2.0f, to select the 2nd palette
shader.end();
colorTable.bind(1); // We bind the texture colorTable to the uniform with index 1 called "colorTable"
}
@Override
public void render() {
Gdx.gl.glClearColor(0.3f, 0.3f, 0.3f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(imgPixelGuy, 0, 0); // Draw the image with the shader applied
batch.end();
}
}
我不知道這是否是將float值傳遞給片段統一的正確方法。不知道如何使用我嘗試使用的代碼片段。
編輯:我試圖通過TenFour04建議的修改和他們的工作完美:)
這裏是預處理精靈
我已經更新了更改的存儲庫, (Java代碼here,片段着色器here),如果有人有興趣,可以在這裏下載:https://bitbucket.org/hcito/libgdxshadertest
編輯2:我剛剛添加到版本庫TenFour04建議的最後優化(將調色板索引傳遞給調用sprite.setColor()方法的R通道中的每個精靈),並且它再次運行完美:)
爲什麼這會降低選票? – Tenfour04 2014-10-01 12:20:14
不知道:/我知道我的英語不太好,而且我有點笨拙,但我真的很想在這裏盡我所能^^ U非常感謝你幫助我,Tenfour :)(順便說一下,我需要5點聲望upvote你的答案^^ U) – hcito 2014-10-01 18:34:45