14

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:

enter image description here

However, when I export it from Eclipse with these settings,

enter image description here

The texturing is completely incorrect. The textures are still loaded, but they are not wrapping correctly onto the object.

enter image description here

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: enter image description here

Directory I run the external JAR from: enter image description here

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). enter image description here

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.
Joehot200
  • 1,070
  • 15
  • 44
  • 1
    As a test, what happens when you export with the "copy required libraries into a sub-folder" option? The difference is that you're wrecking up the libraries in use and have them mashed into one fat jar. – Gimby Aug 26 '15 at 09:35
  • 1
    @Gimby Good idea. Unfortunately, Exactly the same thing happens. The game starts up, shows incorrect textures, and crashes. – Joehot200 Aug 26 '15 at 09:41
  • so the fat jarring is ruled out as a culprit at least. Where are the textures after exporting the project? Are they inside the jar and loaded from the classpath? – Gimby Aug 26 '15 at 09:53
  • The textures are in the "res" folder that you can see. I load textures like `loader.loadTexture("colours", 2));` And the `loadTexture` method I add the res/file.png `texture = TextureLoader.getTexture("PNG", new FileInputStream("res/" + fileName + ".png"));` – Joehot200 Aug 26 '15 at 10:07
  • My gut tells me that the textures are in fact not loaded properly and that you're just seeing random garbage that looks like the texture you're expecting, but with what has been provided now there is no way for me to back that up. Can it be that nasty case of the error handling of the code not being as good as it can be, that the loading of resources is blowing up but you don't see it and the game just keeps chugging on regardless? (see without code to look at, you get this kind of finger pointing) – Gimby Aug 26 '15 at 15:15
  • 2
    @Gimby I will *try* to provide the relevant code. The problem is just deciding what's relevant out of about ~6000 lines of code. You may be correct and that the texture may not be loading correctly (What if my specific method has an issue with it)?, so I will do some testing around the texture loading code. – Joehot200 Aug 26 '15 at 20:27
  • 2
    I advise to switch to packaging them in the jar and loading them as a classpath resource; that makes it practically impossible to fail regardless of where and how you run the game. – Gimby Aug 27 '15 at 08:04
  • @Gimby I have been and will continue to do some more experimentation (e.g. as you say, put them in a classpath resource) on any technique that could make the textures load correctly. I have provided everything that I believe to be the relevant code in the question, but please tell me if I have missed anything. – Joehot200 Aug 28 '15 at 09:25
  • I'm a bit rusty with low level OpenGL/LWJGL code (I prefer the higher level LibGDX), but shouldn't you bind the texture before those mipmapping calls? – Gimby Aug 28 '15 at 11:03
  • 2
    Wild conjecture: it looks like your mipmap is failing, but your textures are loading fine. This explains the grainy result in both the correct AND incorrect pictures you posted. So if the textures are fine, but mipmapping is not, the graininess would result from really large or undefined texcoords. This is only possible if your data is wrong (it cant be because models look good) or your shaders are. Your vertshader is fine though, otherwise we'd see no models. I'm guessing your fragment shader isnt loading or compiling, and OGL has chosen fixed pipeline frag. Could you check for errors please? – Henk De Boer Aug 29 '15 at 09:58
  • @Joehot200: make absolutely sure that the jar does **not** contain the `opengl32.dll`. Using a private copy of that one will screw up everything. – derhass Aug 29 '15 at 12:04
  • @derhass I load the natives from an external folder, like this: https://gyazo.com/f733c781943fecc2bd28fa36c101e4cc - Is that incorrect? – Joehot200 Aug 29 '15 at 12:49
  • @Joehot200: that shouldn't be an issue. – derhass Aug 29 '15 at 12:54
  • @HenkDeBoer You were right. I have updated my question with more information from testers, which quite clearly is pointing at a shader problem. I've provided my code for parsing information into the shaders in the hope that somebody may know what the issue is. – Joehot200 Aug 30 '15 at 10:35
  • glUniformMatrix4 may result in a crash if called from the swing thread, I don't know if that's happening though because your code is quite a mess. I'm also having difficulties getting to the shader compilation part, as the game hangs on your heightmap load code. I can however confirm that neither of the two fragment shaders are being displayed on the screen. – Henk De Boer Sep 01 '15 at 13:51
  • I don't like telling you this, but it may just be exactly what you need to hear: I think you're in over your head, try making a simpler game. That doesn't solve the problem you have, and it certainly isnt a contribution to this thread, but you are learning bad code practice from continuing like this. The game is 3D and multiplayer. That's a challenge even for a veteran. As far as I can say from the code, you are not a veteran. Neither am I, else I might've solved your problem. If you insist, I suggest getting the entire logfile from your testers to see wich thread is failing exactly. – Henk De Boer Sep 01 '15 at 14:30
  • The last comment probably makes me sound like a very unfriendly person, but what I say comes from experience, and is in your benefit. – Henk De Boer Sep 01 '15 at 14:34
  • @HenkDeBoer You're probably right - I will probably have to solve this on my own. More to the point, I'll probably need to learn some more OpenGL. However, I'll point out that I've been programming in OpenGL for 4 years now. A lot of the code was written when I was 11 or 12. I'm not trying to say that you're incorrect, but what I am trying to say is that if you look at my more recent code (to be honest, almost all of the recent work has been on the server), it's much tidier and more efficient. The main reason, however, is that I simply would not have the motivation to work on another game. – Joehot200 Sep 01 '15 at 20:22
  • @HenkDeBoer By the way, I noticed you made an account - How did the game run for you? – Joehot200 Sep 01 '15 at 20:30
  • I could make it to the point where I had an upside down plane hanging above the heightmap, and NPC's were flying around. But I couldn't move, and the textures were wrong just like you have them. I tried to run it via eclipse but was unable to do so, after fixing several issues I ran into an issue with your UDP controller and gave up. – Henk De Boer Sep 02 '15 at 08:31
  • Not intended as an advertisement: Since you're still in the advanced-learning phase I highly suggest you sign up to java-gaming.org where many Java game developers hang out and swap tricks (and was the birthplace of the almighty Minecraft too). At this point in your development cycle you're more looking for support, not factual answers. – Gimby Sep 02 '15 at 15:35
  • 3
    Is there a different JRE in play when you are running the game externally? Check that the eclipse launch configuration is using the same JRE that you are picking up when running externally. This doesn't solve your problem, but at least if you can replicate the broken behaviour in eclipse you can start working towards a solution quicker. – Malcolm Smith Sep 02 '15 at 20:30
  • @MalcolmSmith My PC has Java 8, but unfortunately Eclipse will only let me run in java 7. I'll do some testing (and ask my testers for their java versions) and see if it has anything to do with the issue. – Joehot200 Sep 04 '15 at 10:55

2 Answers2

1

I can't test this, so I'm not sure if this will help, but some implementations of OpenGL don't save element buffers in VAOs. So try binding the element buffer before the call to glDrawElements, e.g.

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, someBuffer);
glDrawElements(GL_TRIANGLES, model.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);

If you don't do this, you may be using the last bound buffer for all draw calls. Probably not the answer, but it couldn't hurt to test it. I also noticed that you are using an older version of Slick, as you still have the slick-util, which is not part of the latest release, so you could also try updating that.

  • What is the different between `GL_ELEMENT_ARRAY_BUFFER` and `GL_ARRAY_BUFFER`? Would I bind something differently to the array buffer? – Joehot200 Sep 02 '15 at 07:42
  • @Joehot200 `GL_ELEMENT_ARRAY_BUFFER` is used to specify the order in which vertices are rendered, `GL_ARRAY_BUFFER` specifies the vertex data. If you're loading the models from .obj files, the indices for drawing come after the f: – TimoPasanen Sep 02 '15 at 08:01
  • This is where I'm going to sound stupid, but which buffer would I be supplying to give it the order of the vertex data? I currently create a vertex buffer, an index buffer, and a face buffer (of course texturecoords too). Is there something I've missed? – Joehot200 Sep 02 '15 at 08:06
  • If you don't understand the concept, I suggest you read this tutorial. http://ogldev.atspace.co.uk/www/tutorial10/tutorial10.html It's for regular OpenGL, not LWJGL, but the gl prefixed methods are the same. And if you're not using `GL_ELEMENT_ARRAY_BUFFER`, you should use glDrawArrays instead of glDrawElements. – TimoPasanen Sep 02 '15 at 08:07
  • You bind the index buffer to `GL_ELEMENT_ARRAY_BUFFER` – TimoPasanen Sep 02 '15 at 08:08
1

So try this instead of Extracting the required libraries try Package option instead, Because i personally believe there is an issue while finding those library files or linking some file then simply run the package.

Option

Omi Harjani
  • 737
  • 1
  • 8
  • 20