为什么 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);
// [...]
我很难理解为什么 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);
// [...]