This issue is now fixed. My shader attributes were not bound correctly.
I have got a game, which when ran from the IDE looks like this:
However, when I export it from Eclipse with these settings,
The texturing is completely incorrect. The textures are still loaded, but they are not wrapping correctly onto the object.
The code is exactly the same, as I only just exported it, and I am currently running both windows of the game at the same time(One working fine from the IDE, one looking weird from an exported JAR).
I have also copied all the resources from the IDE directory to the folder with the external JAR. IDE directory:
Directory I run the external JAR from:
Also, I know that the textures are actually loading - They are not wrapping correctly. I know this because:
- If you look at the plane, you can see that it still has elements of the texture - They are just all stretched and messed up.
- Same thing with the Skybox. If you look at that, parts are still there, but again, it's incorrectly wrapped around the OBJ model.
- If I hit the Q key to render the terrain with a DisplayList (Wrapping the terrain texture multiple times), it shows the texture. Can't get a screenshot of this because I can't hit Q and take a screenshot.
I have checked inside the JAR file, and the fragment and the vertex shader are still there. The correct libraries also appear to be there (Besides, if they weren't, the game would not even start).
Update: As I was restarting the game multiple times to check for more information, I noticed that as soon as the display shows (so I can see the incorrectly-textured terrain and plane), the game freezes about 90% of the time. No Stacktrace, just a "This window is not responding and windows is closing it". The game still works perfectly without crashing when I run it in the IDE.
The server for the game exports and runs perfectly. Only the client is the issue.
What about exporting could make the game any different than running it in the IDE, and how can I solve it?
Update: So here is my texture loading code:
loader.loadTexture("PlaneTexture", 1);
//loadTexture() method:
public int loadTexture(String fileName, int mipmap) {
Texture texture = null;
try {
try{
texture = TextureLoader.getTexture("PNG", new FileInputStream("res/" + fileName + ".png")); //TextureLoader is a Slick-Util class.
}catch (Exception e){
e.printStackTrace();
}
if (texture == null){
throw new Exception("Null texture!");
}
//texture = TextureLoader.getTexture("GIF", new FileInputStream("res/" + fileName + ".png"));
if (mipmap > -10){
GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_LINEAR);
GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL14.GL_TEXTURE_LOD_BIAS, mipmap);
}
} catch (Exception e) {
e.printStackTrace();
System.err.println("Tried to load texture " + fileName + ".png , didn't work");
System.exit(1);
return -1;
}
textures.add(texture.getTextureID());
return texture.getTextureID();
}
I now have the texture ID of the texture. I then render the object (in this case the plane) like this:
Plane you = Main.TerrainDemo.shipsID.get(Main.TerrainDemo.UID);
Main.TerrainDemo.shader.start();
TexturedModel texturedModel = TerrainDemo.shipModel; //The plane model
RawModel model = texturedModel.getRawModel();
GL30.glBindVertexArray(model.getVaoID());
GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1);
GL20.glEnableVertexAttribArray(2);
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, TerrainDemo.shipModel.getTexture().getID()); //The ID of the texture.
glDrawElements(GL_TRIANGLES, model.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
And, although I don't think they're important, my vertex and fragment shaders:
//Vertex shader
#version 130
in vec3 position;
in vec2 textureCoords;
in vec3 normal;
out vec2 pass_textureCoords;
out vec3 surfaceNormal;
out vec3 toLightVector;
uniform mat4 transformationMatrix;
uniform vec3 lightPosition;
void main(void){
gl_Position = ftransform();
pass_textureCoords = textureCoords;
surfaceNormal = (transformationMatrix * vec4(normal, 0.0)).xyz;
toLightVector = (vec3(500, 50000, 500)) - (transformationMatrix * vec4(position, 1.0)).xyz;
}
//Fragment shader
#version 130
in vec2 pass_textureCoords;
in vec3 surfaceNormal;
in vec3 toLightVector;
out vec4 out_Color;
uniform sampler2D textureSampler;
uniform vec3 lightColour;
void main(void){
vec3 unitNormal = normalize(surfaceNormal);
vec3 unitLightVector = normalize(toLightVector);
float nDot1 = dot(unitNormal, unitLightVector);
float brightness = max(nDot1, 0.2);
brightness = brightness + 0.5;
vec3 diffuse = brightness * vec3(1, 1, 1);
vec4 textureColor = vec4(diffuse, 1.0) * texture(textureSampler, pass_textureCoords);
if(textureColor.a<1){
discard;
}
out_Color = vec4(textureColor.r, textureColor.g, textureColor.b, 1);
}
Again, I will stress that all of this is working perfectly if the game is running from the IDE. It is just if it runs from an external JAR that the issue occurs.
I will be experimenting with different texture loading techniques and methods (e.g. packing textures into the JAR) and seeing if anything different happens.
Yet another update: So, I sent the game to another person (They also use windows 8), and the game worked perfectly! No texturing errors whatsoever! So now I'm unsure if the problem is with my PC specifically or something else.
For those who wish to try, you can download the game at http://endcraft.net/PlaneGame and see it yourself (Please read the instructions.txt - Also, you'll need a program to decompress .rar files).
I will be getting as many people as I know to give the game a go and see if they have the same issue or if the texturing is correct.
It is completely baffling me that it works fine when I run it from the IDE, but does not work when I export into an external jar, but does work when I export it into an external jar and send it to someone else!
(another) Update: I have sent the game to multiple people, some of them are coming across this crash:
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x1cd6b57f, pid=36828, tid=35556
#
# JRE version: Java(TM) SE Runtime Environment (8.0_31-b13) (build 1.8.0_31-b13)
# Java VM: Java HotSpot(TM) Client VM (25.31-b07 mixed mode windows-x86 )
# Problematic frame:
# C [atioglxx.dll+0xc0b57f]
#
In the log file, I see this:
Stack: [0x011d0000,0x01220000], sp=0x0121f1e8, free space=316k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [atioglxx.dll+0xc0b57f]
C [atioglxx.dll+0xbe8b95]
C [atioglxx.dll+0x641852]
C [lwjgl.dll+0x9a28]
j org.lwjgl.opengl.GL20.glUniformMatrix4(IZLjava/nio/FloatBuffer;)V+33
j TMLoading.ShaderProgram.loadMatrix(ILorg/lwjgl/util/vector/Matrix4f;)V+23j
TMLoading.StaticShader.loadTransformationMatrix(Lorg/lwjgl/util/vector/Matrix4f;) V+6
j Joehot200.Plane.render()V+407
j Joehot200.TerrainDemo.render()V+4045
j Joehot200.TerrainDemo.enterGameLoop()V+356
j Joehot200.TerrainDemo.startGame()V+320
j StartScreenExperiments.Test2.resartTDemo()V+128
j StartScreenExperiments.Test2.main([Ljava/lang/String;)V+27
v ~StubRoutines::call_stub
V [jvm.dll+0x1473e5]
In other words, the entire issue (the texturing and the crashes) are beginning to look a lot like they are related to the shaders (either parsing information to them, or the actual shader code itself).
I have also done more testing, and the texturing works fine without shaders using a DisplayList.
Here is the code up to the glUniformMatrix() call:
//Some unnecessary code has been removed. For example, you do not care about what colour I make the plane depending on what team it is on.
//Plane class. (Referring to a jet plane which is the main object the player controls)
public void render(){
twodcoords = TextDemo.getScreenCoords(sx, sy + 30, sz);
glPushAttrib(GL_ENABLE_BIT);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glPushMatrix();
glTranslatef(sx, sy, sz);
GL30.glBindVertexArray(Main.TerrainDemo.vaoID);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glRotatef(srot, 0f, 1f, 0f);
glRotatef(pitch, -1f, 0f, 0f);
Main.TerrainDemo.shader.start();
glPushMatrix();
glDisable(GL_LIGHTING);
TexturedModel texturedModel = TerrainDemo.shipModel;
RawModel model = texturedModel.getRawModel();
GL30.glBindVertexArray(model.getVaoID());
GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1);
GL20.glEnableVertexAttribArray(2);
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, TerrainDemo.shipModel.getTexture().getID());
org.lwjgl.util.vector.Matrix4f m = Assist.createTransformationMatrix(new Vector3f(sx, sy, sz), new Vector3f(pitch, rot, roll), new Vector3f(5, 5, 5)); //Creates a transformation matrix based on the X, Y, Z, Pitch, yaw, roll, and scale of the plane.
Main.TerrainDemo.shader.loadTransformationMatrix(m);
glDrawElements(GL_TRIANGLES, model.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
GL20.glDisableVertexAttribArray(0);
GL20.glDisableVertexAttribArray(1);
GL20.glDisableVertexAttribArray(2);
GL30.glBindVertexArray(0);
GL30.glBindVertexArray(0);
glPopMatrix();
glPopAttrib();
}
//StaticShader class. This method literally just passes it to the loadMatrix class.
public void loadTransformationMatrix(Matrix4f matrix){
super.loadMatrix(location_transformationMatrix, matrix);
}
//ShaderProgram class.
FloatBuffer buf = BufferUtils.createFloatBuffer(4 * 4);
public void loadMatrix(int location, Matrix4f matrix){
matrix.store(buf);
buf.flip();
GL20.glUniformMatrix4(location, false, buf);
}
Update - So, with one hour left on the Bounty, I thought I'd add a few more details:
- As I probably said somewhere above, the game works for some when exported, but not for others. I've noticed that the game has always worked when ran on java 7, but with me only me and one other tester on java 7, this really isn't conclusive.
- The texturing renders correctly in a DisplayList. The textures are loading. However, they are not being displayed correctly.
- Even if you don't know the problem, trying out the game (ignore the start screen, I need to make a new one) and telling me the results, as well as your OS/Java details, etc, would be really appreciated.
- Yes, the mipmapping is correct. I know someone in the comments mentioned it possibly wasn't, but I've tried setting it stupidly high and I do indeed get a very blurred texture.
- I've already tried "package libraries into external jar". I appreciate the time taken for that answer, but I did say in the comments that I've already tried it.
- The issue may be the fragment shader (as someone suggested in the comments), but I am currently unsure how to test it, nor do I understand why it would work inside the IDE but not outside of it.