经过几天的大量研究和测试后,我终于能够实现这本书中出现的片段着色器(这是一本很好的书,我可以说):http://arcsynthesis.org/gltut/Basics/Tutorial%2002.html。
它只讲授如何使用片段着色器渲染一个使用“gl_FragCoord.y”的简单三角形。
在这些工作日里,我遇到了一些我想更好理解的问题。
1st - 在我的片段着色器中,如果我使用代码:
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。
第二 - 如何检索片段着色器代码中的变量值以显示它们,例如在Toast中?让我解释一下这个问题。
以下三个代码行:
float colorTwo[] = { 1.0f, 1.0f, 1.0f, 0.0f };
int mColorHandleTwo = GLES20.glGetUniformLocation(mProgram, "vColorTwo");
GLES20.glUniform4fv(mColorHandleTwo, 1, colorTwo, 0);
我能够获得这个“colorTwo”数组并在Fragment Shader Code中使用它。 另一方面,如果我让片段着色器代码中的一个声明如下:
float whatThisNumber = gl_FragCoord.y
如何获得此浮动并将其显示在Toast中?
下面的代码实际上是我正在处理的代码:
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);
}
}
我希望我的问题清楚。
答案 0 :(得分:2)
gl_FragColor = vec4(gl_FragCoord.x/500, 0.0, 1.0, 1.0);
会导致编译器错误。希望它有所帮助。
答案 1 :(得分:0)
你的第一个问题是关于java如何工作而不是与OpenGL无关。
如果将整数除以整数,则得到一个整数。所以我的猜测是gl_FragCoord.x / 500会产生一个0.3等值然后舍入为零。
如果用float(或double)除整数,则得到一个float(或double)。因此,当您除以500.0时,您将获得预期的非零浮点结果。您也可以使用500f实现相同的目标。无论哪种方式,您都让编译器知道您正在使用浮点值,这在这里显然非常重要。
关于你的第二个问题,我不相信你可以,虽然我很高兴被其他人纠正。