适用于Android的OpenGL ES 2.0 - gl_FragCoord和gl_FragColor

时间:2022-09-10 21:53:57

After a few day with a lot of researching and tests I finally was able to implement the Fragment Shader that is shown is this book (an excellent book, may I say): http://arcsynthesis.org/gltut/Basics/Tutorial%2002.html.

经过几天的大量研究和测试后,我终于能够实现这本书中出现的片段着色器(这是一本很好的书,我可以说):http://arcsynthesis.org/gltut/Basics/Tutorial% 2002.html。

It just teaches how to render a simple triangle with a Fragment Shader that uses "gl_FragCoord.y".

它只是教导如何使用片段着色器渲染一个使用“gl_FragCoord.y”的简单三角形。

In these working days however I went throught some issues that I would like to understand a little better why them happened.

在这些工作日里,我遇到了一些问题,我想更好地了解它们为什么会发生。

1st - In my fragment shader, if I use the code: gl_FragColor = vec4(gl_FragCoord.x/500.0, 0.0, 1.0, 1.0); the triangles is rendered.

1st - 在我的片段着色器中,如果我使用代码:gl_FragColor = vec4(gl_FragCoord.x / 500.0,0.0,1.0,1.0);渲染三角形。

But If I use: gl_FragColor = vec4(gl_FragCoord.x/500, 0.0, 1.0, 1.0); it's not rendered (I got a black screen, or whatever the color is defined in the GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);.

但如果我使用:gl_FragColor = vec4(gl_FragCoord.x / 500,0.0,1.0,1.0);它没有渲染(我有一个黑屏,或GLES20.glClearColor中定义的任何颜色(0.0f,0.0f,0.0f,1.0f);.

That's lead to the question: In GLSL numbers have to have decimal specification? Note that the only thing that changed in the code was the 500.0 number to 500.

这就引出了一个问题:在GLSL中,数字必须有十进制规格吗?请注意,代码中唯一更改的是500.0到500。

2nd - How can I retrieve the variable values that are inside the Fragment Shader Code to display them for example in a Toast? Let me explain that question.

第2步 - 如何检索片段着色器代码中的变量值以显示它们,例如在Toast中?让我解释一下这个问题。

With these three code lines below:

使用以下三个代码行:

float colorTwo[] = { 1.0f, 1.0f, 1.0f, 0.0f };

float colorTwo [] = {1.0f,1.0f,1.0f,0.0f};

int mColorHandleTwo = GLES20.glGetUniformLocation(mProgram, "vColorTwo");

int mColorHandleTwo = GLES20.glGetUniformLocation(mProgram,“vColorTwo”);

GLES20.glUniform4fv(mColorHandleTwo, 1, colorTwo, 0);

GLES20.glUniform4fv(mColorHandleTwo,1,colorTwo,0);

I'm able to get this "colorTwo" array and used it inside the Fragment Shader Code. In the other hand, If I have let's say a statment inside the Fragment Shader Code like:

我能够获得这个“colorTwo”数组并在Fragment Shader Code中使用它。另一方面,如果我让片段着色器代码中的一个声明如下:

float whatThisNumber = gl_FragCoord.y

float whatThisNumber = gl_FragCoord.y

How can I get this float and display it in a Toast?

我如何获得这个浮动并在Toast中显示它?

The code below is actually the one I'm working on:

下面的代码实际上就是我正在研究的代码:

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

    }

}

I hope I was clear on my questions.

我希望我的问题清楚。

2 个解决方案

#1


2  

  1. In glsl language there is no automatic conversion from integer to float number, so the line of code gl_FragColor = vec4(gl_FragCoord.x/500, 0.0, 1.0, 1.0); cause a compiler error.
  2. 在glsl语言中没有从整数到浮点数的自动转换,因此代码行gl_FragColor = vec4(gl_FragCoord.x / 500,0.0,1.0,1.0);导致编译器错误。

  3. You can not get the value of a shader variable from java code (or c++ code). The java code is executed from CPU, the shader is executed from GPU.
  4. 您无法从java代码(或c ++代码)获取着色器变量的值。 java代码从CPU执行,着色器从GPU执行。

Hope it helps.

希望能帮助到你。

#2


0  

Your first question is about how java works and not related to OpenGL as such.

您的第一个问题是关于java如何工作而与OpenGL无关。

If you divide an integer by an integer, you get an integer. So my guess is that gl_FragCoord.x/500 results in a value such as 0.3 that then rounds to zero.

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

If you divide an integer by a float (or double), you get a float (or double). Hence when you divide by 500.0, you get the non-zero floating point result you expect. You could also achieve the same thing by using 500f. Either way, you let the compiler know you are working with a floating point value, which is clearly important here.

如果用float(或double)除整数,则得到一个float(或double)。因此,当您除以500.0时,您将获得预期的非零浮点结果。您也可以使用500f实现相同的目标。无论哪种方式,您都让编译器知道您正在使用浮点值,这在此非常重要。

As for your second question, I don't believe you can although I'm happy to be corrected by someone else.

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

#1


2  

  1. In glsl language there is no automatic conversion from integer to float number, so the line of code gl_FragColor = vec4(gl_FragCoord.x/500, 0.0, 1.0, 1.0); cause a compiler error.
  2. 在glsl语言中没有从整数到浮点数的自动转换,因此代码行gl_FragColor = vec4(gl_FragCoord.x / 500,0.0,1.0,1.0);导致编译器错误。

  3. You can not get the value of a shader variable from java code (or c++ code). The java code is executed from CPU, the shader is executed from GPU.
  4. 您无法从java代码(或c ++代码)获取着色器变量的值。 java代码从CPU执行,着色器从GPU执行。

Hope it helps.

希望能帮助到你。

#2


0  

Your first question is about how java works and not related to OpenGL as such.

您的第一个问题是关于java如何工作而与OpenGL无关。

If you divide an integer by an integer, you get an integer. So my guess is that gl_FragCoord.x/500 results in a value such as 0.3 that then rounds to zero.

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

If you divide an integer by a float (or double), you get a float (or double). Hence when you divide by 500.0, you get the non-zero floating point result you expect. You could also achieve the same thing by using 500f. Either way, you let the compiler know you are working with a floating point value, which is clearly important here.

如果用float(或double)除整数,则得到一个float(或double)。因此,当您除以500.0时,您将获得预期的非零浮点结果。您也可以使用500f实现相同的目标。无论哪种方式,您都让编译器知道您正在使用浮点值,这在此非常重要。

As for your second question, I don't believe you can although I'm happy to be corrected by someone else.

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