I’m using Slick2D’s ShaderProgram for shader-based drawing in my game. Some players report that after 3-10 minutes, the game inevitably crashes hard during what appears to be a setUniform4f operation that’s happened thousands of times before:
[error occurred during error reporting (printing native stack), id 0xc0000005]
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
J org.lwjgl.opengl.ARBShaderObjects.nglUniform4fARB(IFFFFJ)V
J com.zarkonnen.airships.Appearance.draw(Lcom/zarkonnen/catengine/Draw;DDDDILcom/zarkonnen/catengine/util/Clr;Z)V
Why might this happen? Is it a transient problem, or maybe a driver issue? I’m confused that this happens not when the shader is bound, or when textures are set, but at the point of this utterly mundane operation of setting a 4f value. I’m in fact pretty lost here, as I can’t even repro this on any of my own machines.
This is the culprit function in its entirety:
public void draw(Draw d, double x, double y, double w, double h, int ms, Clr tint, boolean flipped) {
if (shaderLoadFailed) {
drawFallback(d, x, y, w, h, ms, tint, flipped);
return;
}
if (tex == null) {
tex = loadTex(SPRITESHEET);
if (tex == null) {
shaderLoadFailed = true;
}
}
if (sp == null) {
try {
sp = ShaderProgram.loadProgram(
AGame.getGameDirectoryPath("data/passthrough.vert"),
AGame.getGameDirectoryPath("data/frag.frag"));
} catch (Exception e) {
e.printStackTrace();
shaderLoadFailed = true;
}
}
if (shaderLoadFailed) { return; }
sp.bind();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL11.GL_TEXTURE_2D, tex.getTextureID());
sp.setUniform1i("tex", 0);
if (tint == null) {
sp.setUniform4f("tint", 1.0f, 1.0f, 1.0f, 1.0f);
} else {
sp.setUniform4f("tint", tint.r / 255.0f, tint.g / 255.0f, tint.b / 255.0f, 1.0f);
}
Img img = frames.get((ms / interval) % frames.size());
glBegin(GL_QUADS);
if (flipped ^ isFlipped) {
glTexCoord2d(img.srcX, img.srcY);
glVertex2d(x + w, y);
glTexCoord2d(img.srcX, img.srcY + img.srcHeight);
glVertex2d(x + w, y + h);
glTexCoord2d(img.srcX + img.srcWidth, img.srcY + img.srcHeight);
glVertex2d(x, y + h);
glTexCoord2d(img.srcX + img.srcWidth, img.srcY);
glVertex2d(x, y);
} else {
glTexCoord2d(img.srcX, img.srcY);
glVertex2d(x, y);
glTexCoord2d(img.srcX, img.srcY + img.srcHeight);
glVertex2d(x, y + h);
glTexCoord2d(img.srcX + img.srcWidth, img.srcY + img.srcHeight);
glVertex2d(x + w, y + h);
glTexCoord2d(img.srcX + img.srcWidth, img.srcY);
glVertex2d(x + w, y);
}
glEnd();
sp.unbind();
TextureImpl.bindNone();
}
And the shaders FWIW:
passthrough.vert
void main() {
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
frag.frag
uniform sampler2D tex;
uniform vec4 tint;
void main(void) {
gl_FragColor = texture2D(tex, floor(gl_TexCoord[0].st) / 1024.0) * tint;
}
As you can see, there’s very little to them.