0
votes

I'm new to OpenGL and today I was trying to compile some shader programs for GPGPU usage of OpenGL in android OS. I have two questions: 1) I only want to program fragment shader, Is it necessary to program the vertex shader too? 2) I face some Errors while compiling my shader source code. My source code is defined as :

final String src = "#version 310 es\n" +
            "uniform sampler2D texUnit;\n" +
            "uniform int sequence;\n" +
            "void main(void)\n" +
            "{\n" +
            "const vec3 DotValue = {0.299f , 0.587f , 0.114f};\n" +
            "vec2 texCoord = gl_TexCoord[0].xy;\n" +
            "vec4 CurrentPixelData  = texture2D(texUnit, texCoord);\n" +
            "float temp = CurrentPixelData.x * DotValue.x + CurrentPixelData.y * DotValue.y + CurrentPixelData.z * DotValue.z;\n" +
            "vec4 result = {temp,temp,temp,CurrentPixelData.w};\n" +
            "gl_FragColor = result;\n" +
            "}\n";

and the code for creating the shader is:

int fragment = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
        GLES20.glShaderSource(fragment,src);
        GLES20.glCompileShader(fragment);



        int[] compiled = new int[1];
        GLES20.glGetShaderiv(fragment, GLES20.GL_COMPILE_STATUS, compiled, 0);	//compile[0] != 0 : compiled successfully
        if (compiled[0] == 0) {
            Log.e(TAG, "Could not compile shader: ");
            Log.e(TAG, GLES20.glGetShaderInfoLog(fragment));
            GLES20.glDeleteShader(fragment);
            fragment = 0;
        } else {
            Log.i(TAG, "Compiled shader with source length " + src.length());
        }

But when i try to debug my application, there are several errors about shader compilation in the logcat:

    0:6: L0001: Expected token ';', found '{'
    0:7: L0002: Undeclared variable 'gl_TexCoord'
    0:8: L0002: No matching function for call to 'texture2D'
    0:9: L0002: Undeclared variable 'CurrentPixelData'
    0:10: L0001: Expected token ';', found '{'
    0:11: L0002: Undeclared variable 'gl_FragColor'

Can anyone help me what is wrong with my code? Thanks in advance.

2

2 Answers

5
votes

You do need both a vertex shader and a fragment shader.

The syntax errors are already highlighted by the shader compilation log you captured. Providing some more detail on them:

  1. You need to use constructor syntax to initialize vectors:

    const vec3 DotValue = vec3(0.299 , 0.587, 0.114);
    
  2. gl_TexCoord is not a built-in variable. You may have seen it in code samples for desktop OpenGL, where it used to exist. But it's deprecated even there, and never was present in OpenGL ES. You need to pass the texture coordinates into the shader yourself.

  3. texture2D() is not a built-in function. The function for sampling a 2D texture used to be named like this in older GLSL version, but is now overloaded for various sampler types under the name texture():

    vec4 CurrentPixelData  = texture(texUnit, texCoord);
    
  4. Looks like just a follow-up error from the previous one.

  5. Same as error 1:

    vec4 result = vec4(temp, temp, temp, CurrentPixelData.w);
    
  6. gl_FragColor used to be a built-in variable in older GLSL versions, but is now deprecated and removed. You need to define your own variable with the qualifier out to define the variable(s) used as shader outputs.

2
votes

You must write a vertex shader. gl_Position must be assigned values to create triangles and then pixels (fragments). If you're using texture mapping, you need to assign a varying variable with the texture coordinate assigned to the vertex. Later, these coordinates are interpolated for each fragment. The most basic vertex shader would be:

    const char* simpleVertexShader=
    "attribute vec4 position;"
    "attribute vec4 inputTextureCoordinate;
    "varying   vec2 textureCoordinate;"
    "void main(){"
    "gl_Position = position;"
    "textureCoordinate = inputTextureCoordinate.xy;"
    "}";

In you're fragment shader you have syntax error in vec3 and vec4 init. It should be done like this:

  "const vec3 DotValue = vec3(0.299 , 0.587 , 0.114);\n"

and

  "vec4 result = vec4(temp,temp,temp,CurrentPixelData.w);\n"

Notice the float literals don't need the 'f' postfix in glsl.

Your fixed code:

  final String src = "#version 310 es\n" +
        "precision   highp float;"
        "uniform sampler2D texUnit;\n" +
    "varying   vec2 textureCoordinate" +
        "void main(void)\n" +
        "{\n" +
        "const vec3 DotValue = vec3(0.299 , 0.587 , 0.114);\n" +
        "vec2 texCoord = textureCoordinate;\n" +
        "vec4 CurrentPixelData  = texture2D(texUnit, texCoord);\n" +
        "float temp = CurrentPixelData.x * DotValue.x + CurrentPixelData.y * DotValue.y + CurrentPixelData.z * DotValue.z;\n" +
        "vec4 result = vec4(temp,temp,temp,CurrentPixelData.w);\n" +
        "gl_FragColor = result;\n" +
        "}\n";

It would be a lot easier for you if you start with a good openGL tutorial.

Good Luck!