3

经过几天的大量研究和测试,我终于能够实现这本书所示的片段着色器(我可以说是一本很棒的书):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”数组并在片段着色器代码中使用它。另一方面,如果我在片段着色器代码中说一个语句,例如:

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);

    }

}

我希望我的问题很清楚。

4

2 回答 2

2
  1. 在 glsl 语言中,没有从整数到浮点数的自动转换,因此这行代码gl_FragColor = vec4(gl_FragCoord.x/500, 0.0, 1.0, 1.0); 会导致编译器错误。
  2. 您无法从 java 代码(或 c++ 代码)中获取着色器变量的值。Java 代码从 CPU 执行,着色器从 GPU 执行。

希望能帮助到你。

于 2014-09-26T20:14:56.697 回答
0

您的第一个问题是关于 java 的工作原理,与 OpenGL 本身无关。

如果你用一个整数除以一个整数,你会得到一个整数。所以我的猜测是 gl_FragCoord.x/500 会产生一个诸如 0.3 的值,然后四舍五入为零。

如果将整数除以浮点数(或双精度),则得到浮点数(或双精度)。因此,当您除以 500.0 时,您会得到您期望的非零浮点结果。你也可以通过使用 500f 来达到同样的效果。无论哪种方式,您都让编译器知道您正在使用浮点值,这在这里显然很重要。

至于你的第二个问题,我不相信你可以,虽然我很高兴被别人纠正。

于 2013-11-03T14:55:34.957 回答