經過幾天的大量研究和測試,我終於能夠實現所顯示的片段着色器是本書(可以說是一本很好的書):http://arcsynthesis.org/gltut/Basics/Tutorial%2002.html。適用於Android的OpenGL ES 2.0 - gl_FragCoord和gl_FragColor
它只是教會如何渲染一個簡單的三角形與使用「gl_FragCoord.y」的片段着色器。
但是在這些工作日裏,我經歷了一些我希望更好地理解他們爲什麼發生的問題。
- 在我的片段着色器,如果我使用的代碼: gl_FragColor = vec4(gl_FragCoord.x/500.0, 0.0, 1.0, 1.0);
三角形渲染。
但如果我使用: gl_FragColor = vec4(gl_FragCoord.x/500, 0.0, 1.0, 1.0);
它不會呈現(我有一個黑色的屏幕,或任何顏色的GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
定義
這導致了一個問題:在GLSL號碼必須有小數?規範 需要注意的是,在代碼更改的唯一東西就是500.0數量爲500
第二 - 我怎樣才能找回屬於Fragmen裏面的變量值t着色器代碼在Toast中顯示它們?讓我解釋一下這個問題。
下面這三個代碼行:
float colorTwo[] = { 1.0f, 1.0f, 1.0f, 0.0f };
int mColorHandleTwo = GLES20.glGetUniformLocation(mProgram, "vColorTwo");
GLES20.glUniform4fv(mColorHandleTwo, 1, colorTwo, 0);
我能夠得到這個 「colorTwo」 陣列,並用它片段着色器代碼中。 在另一方面,我若假設片段着色器代碼內statment,如:
float whatThisNumber = gl_FragCoord.y
我怎樣才能得到這個漂浮在舉杯顯示呢?
下面的代碼實際上是一個我工作:
public class TheShape {
ByteBuffer myByteBuffer;
FloatBuffer positionBufferObject;
int mProgram;
public TheShape() {
float vertexPositions[] = {
0.75f, 0.75f, 0.0f, 1.0f,
0.75f, -0.75f, 0.0f, 1.0f,
-0.75f, -0.75f, 0.0f, 1.0f
};
myByteBuffer = ByteBuffer.allocateDirect(vertexPositions.length * 4);
myByteBuffer.order(ByteOrder.nativeOrder());
positionBufferObject = myByteBuffer.asFloatBuffer();
positionBufferObject.put(vertexPositions);
positionBufferObject.position(0);
String vertexShaderCode =
"attribute vec4 vPosition;" +
"void main() {" +
" gl_Position = vPosition;" +
"}";
String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"uniform vec4 vColorTwo;" +
"void main() {" +
"gl_FragColor = vec4(gl_FragCoord.x/500.0, 0.0, 1.0, 1.0);" +
//ok "gl_FragColor = mix(vColorTwo, vColor, (gl_FragCoord.y)/500.0);" +
//ok "gl_FragColor = vec4((gl_FragCoord.x)/500.0, (gl_FragCoord.y)/500.0, 0.0, 1.0);" +
"}";
int myVertexShader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
GLES20.glShaderSource(myVertexShader, vertexShaderCode);
GLES20.glCompileShader(myVertexShader);
int myFragmentShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
GLES20.glShaderSource(myFragmentShader, fragmentShaderCode);
GLES20.glCompileShader(myFragmentShader);
mProgram = GLES20.glCreateProgram();
GLES20.glAttachShader(mProgram, myVertexShader);
GLES20.glAttachShader(mProgram, myFragmentShader);
GLES20.glLinkProgram(mProgram);
}
public void draw() {
GLES20.glUseProgram(mProgram);
GLES20.glEnableVertexAttribArray(0);
GLES20.glVertexAttribPointer(0, 4, GLES20.GL_FLOAT, false, 0, positionBufferObject);
float color[] = { 0.0f, 0.0f, 0.0f, 1.0f };
int mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
float colorTwo[] = { 1.0f, 1.0f, 1.0f, 0.0f };
int mColorHandleTwo = GLES20.glGetUniformLocation(mProgram, "vColorTwo");
GLES20.glUniform4fv(mColorHandleTwo, 1, colorTwo, 0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
}
}
我希望我在我的問題說清楚。
這與Java實際上沒有任何關係。 GLSL由OpenGL實現(通常是顯示驅動程序)編譯,'gl_FragCoord'是一個浮點3分量向量。如果您將這個向量(x)的單個元素混合起來,您將得到一個浮點標量。當表達式中的一個操作數是fp時,GLSL定義整型類型到浮點型的隱式轉換,所以這不應該成爲問題。我能想到的唯一情況是整數和fp之間的精度差異 - 如果整數大於尾數支持,則在升級到fp期間將發生精度損失。 –
通常,在將整數500轉換爲浮點時,這不是主要問題,但OpenGL ES 2.0提供了三級浮點精度(兩個在片段着色器中是必需的,一個是可選的)。例如,lowp浮點變量只能表示範圍內的值:+/- 2.0。 –