Reputation: 798
I am unable to successfully run a shader, and I seem to be missing some step to make it all work. I end up with the error of:
Exception in thread "main" org.lwjgl.opengl.OpenGLException: Invalid operation (1282)
at org.lwjgl.opengl.Util.checkGLError(Util.java:59)
at org.lwjgl.opengl.GL20.glUniform1i(GL20.java:374)
at sprites.Sprite.draw(Sprite.java:256)
at gui.Game.drawFrame(Game.java:238)
at gui.Game.gameLoop(Game.java:205)
at gui.Game.startGame(Game.java:244)
at tests.simple.SimpleShader.main(SimpleShader.java:36)
My initialization begins with:
int frag = FilterLoader.createShader("/tests/resources/shaders/grayscale.frag", GL20.GL_FRAGMENT_SHADER);
and the createShader method looks like the following:
int shader = GL20.glCreateShader(type);
if(shader == 0)
return 0;
StringBuilder code = new StringBuilder("");
String line;
try
{
String path = FilterLoader.class.getResource(filename).getPath();
BufferedReader reader = new BufferedReader(new FileReader(path));
while((line = reader.readLine()) != null)
{
code.append(line + "\n");
}
}
catch(Exception e)
{
e.printStackTrace();
System.err.println("Error reading in " + type + " shader");
return 0;
}
GL20.glShaderSource(shader, code);
GL20.glCompileShader(shader);
return shader;
I then attach the shader to the specific Sprite with:
two.addFragmentShader(frag); //two is a Sprite
which is just simply:
fragmentShader = fragment_shader;
GL20.glAttachShader(shader, fragment_shader);
GL20.glLinkProgram(shader);
The int shader has been previously initialized in the Sprites constructor with:
shader = GL20.glCreateProgram();
This was a previous problem, but no longer obviously. Now I get to where the actual error occured, in the Sprites (two in this case) draw method, which looks like so:
if(true)
{
GL20.glUseProgram(shader);
}
glPushMatrix();
glActiveTexture(GL13.GL_TEXTURE0);
imageData.getTexture().bind();
//The line below is where the error occurs.
GL20.glUniform1i(fragmentShader, GL13.GL_TEXTURE0);
int tx = (int)location.x;
int ty = (int)location.y;
glTranslatef(tx, ty, location.layer);
float texture_X = ((float)which_column/(float)columns);
float texture_Y = ((float)which_row/(float)rows);
float texture_XplusWidth = ((float)(which_column+wide)/(float)columns);
float texture_YplusHeight = ((float)(which_row+tall)/(float)rows);
glBegin(GL_QUADS);
{
GL11.glTexCoord2f(texture_X, texture_Y);
glVertex2f(0, 0);
GL11.glTexCoord2f(texture_X, texture_YplusHeight);
glVertex2f(0, getHeight());
GL11.glTexCoord2f(texture_XplusWidth, texture_YplusHeight);
glVertex2f(getWidth(), getHeight());
GL11.glTexCoord2f(texture_XplusWidth, texture_Y);
glVertex2f(getWidth(), 0);
}
glEnd();
GL20.glUseProgram(0);
glPopMatrix();
And the error occurs at this line:
GL20.glUniform1i(fragmentShader, GL13.GL_TEXTURE0);
And for reference my shader:
// simple fragment shader
uniform sampler2D texture;
void main()
{
vec4 color, texel;
color = gl_Color;
texel = texture2DRect(texture, gl_TexCoord[0].xy);
color *= texel;
float gray = dot(color.rgb, vec3(0.299, 0.587, 0.144));
gl_FragColor = vec4(gray, gray, gray, color.a);
}
I've gone through the tutorials, read about the error, and I can't figure out what step I have missed.
Upvotes: 2
Views: 7949
Reputation: 56417
GL20.glUniform1i(fragmentShader, GL13.GL_TEXTURE0);
This is wrong. The first parameter of glUniform1i
is the uniform location, which you can get with glGetUniformLocation
.
The second parameter is an integer, but for texture sampler, you need to pass the texture unit number (0, 1, 2, etc), and bind the texture to that texture unit, for example:
glUseProgram(program);
int loc = glGetUniformLocation(program, "texture");
glUniform1i(loc, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texId);
Then it should work.
Upvotes: 7