为什么 GLES30.glUniformMatrix4fv 使得 GL_INVALID_OPERATION?

Why does GLES30.glUniformMatrix4fv makes GL_INVALID_OPERATION?

我很难理解为什么 GLES30.glUniform4fv returns 我 GL_INVALID_OPERATION 我查找了其他可能的问题,但我没有在我的代码中看到它们。

这是我的代码:

abstract ShaderProgram,我在这里调用 glUniform4fv:

package com.example.myapplication;

import android.opengl.GLES30;
import android.opengl.Matrix;
import android.util.Log;

import com.example.myapplication.vectors.Matrix4f;
import com.example.myapplication.vectors.Vector3f;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

public abstract class ShaderProgram {

    public int programID;
    public int vertexShader;
    public int fragmentShader;

    private static FloatBuffer matrixBuffer = ByteBuffer.allocateDirect(16*4).order(ByteOrder.nativeOrder()).asFloatBuffer();

    ShaderProgram(String vertCode, String fragCode){
        vertexShader = loadShader(GLES30.GL_VERTEX_SHADER, vertCode);
        fragmentShader = loadShader(GLES30.GL_FRAGMENT_SHADER,fragCode);
        programID = GLES30.glCreateProgram();
        GLES30.glAttachShader(programID,vertexShader);
        GLES30.glAttachShader(programID,fragmentShader);

        bindAttributes();

        GLES30.glLinkProgram(programID);
        GLES30.glValidateProgram(programID);

        start();
        getAllUniforms();
        stop();
    }

    abstract void bindAttributes();

    void bindAttribute(int vbo, String attribute){
        GLES30.glBindAttribLocation(programID,vbo,attribute);
    }

    private int loadShader(int type, String code){
        int shader = GLES30.glCreateShader(type);

        GLES30.glShaderSource(shader,code);
        GLES30.glCompileShader(shader);
        final int[] compileStatus = new int[1];
        GLES30.glGetShaderiv(shader, GLES30.GL_COMPILE_STATUS, compileStatus, 0);
        if(compileStatus[0] == 0){
            System.err.println("Could not compile shader type " + type);
            //frag = 35632
            //vert = 35633
            System.err.println("[HERE ->]" + GLES30.glGetShaderInfoLog(shader));
            Log.e("Shader Source", GLES30.glGetShaderSource(shader));
            GLES30.glDeleteShader(shader);
            shader = 0;
            System.exit(-1);
        }
        return shader;
    }

    abstract void getAllUniforms();

    public int getUniformLocation(String uniform){
        return GLES30.glGetUniformLocation(programID,uniform);
    }

    public void loadUniformFloat(int location, float value){
        GLES30.glUniform1f(location,value);
    }

    public void loadUniformVector(int location, Vector3f vector){
        GLES30.glUniform3f(location,vector.x,vector.y,vector.z);
    }

    public void loadUniformBoolean(int location, boolean bool){
        if(bool){
            GLES30.glUniform1i(location,1);
        }else{
            GLES30.glUniform1i(location,0);
        }
    }

    public void loadUniformMatix(int location, Matrix4f matrix){
        GLES30.glUniformMatrix4fv(location,1,false,matrix.mat,0); //[<-HERE]
        if(GLES30.glGetError() == GLES30.GL_INVALID_OPERATION) {
            Log.e("GLES Error2", "INVALID OPERATION");
        }
    }

    public void start(){
        GLES30.glUseProgram(programID);
    }

    public void stop(){
        GLES30.glUseProgram(0);
    }
}

ShaderProgram、StaticShader的实现:

package com.example.myapplication;

import android.opengl.GLES30;
import android.util.Log;

import com.example.myapplication.vectors.Matrix4f;

public class StaticShader extends ShaderProgram{

    public int positionIn;
    public int UV;

    public int TRANSFORMATION_MATRIX;

    StaticShader(String VERTCODE, String FRAGCODE){
        super(VERTCODE, FRAGCODE);
    }

    @Override
    public void bindAttributes(){
        super.bindAttribute(0,"position");
        super.bindAttribute(1,"i_UV");
    }

    public void getAllUniforms(){
        TRANSFORMATION_MATRIX = super.getUniformLocation("transformationMatrix");
        if(TRANSFORMATION_MATRIX == -1){
            Log.e("Shader", "transformationMatrix was not found");
        }
    }

    public void loadTRansformationMatrix(Matrix4f matrix){
        super.loadUniformMatix(TRANSFORMATION_MATRIX,matrix);
    }
}

StaticShader实例化:

//loader.loadAssetText(); just extracts the shader code from a file
shader = new StaticShader(loader.loadAssetText("Shaders/Static.vertex"),loader.loadAssetText("Shaders/Static.fragment"));
//maths.createTransformationMatrix(Vector3f translation, Vector3f rotation, Vector3f scale); creates a transformation matrix that, in this case, only results in an identity matrix
shader.loadTRansformationMatrix(maths.createTransformationMatrix(new Vector3f(0.0f,0.0f,0.0f),new Vector3f(0.0f,0.0f,0.0f),new Vector3f(1.0f,1.0f,1.0f)));

这是我的着色器:

//Static.vertex
#version 300 es

in highp vec4 position;
in highp vec2 i_UV;

out highp vec2 UV;
out highp vec4 color;

uniform mat4 transformationMatrix;

void main(){
    UV = i_UV;
    color = position;

    vec4 finalPos = transformationMatrix * position;
    gl_Position = position;
}
//Static.fragment
#version 300 es

out highp vec4 Fragment;
in highp vec4 color;
in highp vec2 UV;

uniform sampler2D textureSampler;

void main(){
    Fragment = texture(textureSampler,UV);
}

glUniform* 在当前安装的着色器程序的默认统一块中设置一个统一变量。如果没有当前程序对象,则产生GL_INVALID_OPERATION错误。

因此您必须安装着色器程序才能设置制服:

// install program
GLES30.glUseProgram(programID);

// set uniforms
GLES30.glUniformMatrix4fv(location, 1, false, matrix.mat, 0);
// [...]