Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 导出Eclipse项目会导致不正确的纹理和崩溃,_Java_Eclipse_Opengl_Glsl_Lwjgl - Fatal编程技术网

Java 导出Eclipse项目会导致不正确的纹理和崩溃,

Java 导出Eclipse项目会导致不正确的纹理和崩溃,,java,eclipse,opengl,glsl,lwjgl,Java,Eclipse,Opengl,Glsl,Lwjgl,此问题现已修复。我的着色器属性未正确绑定。 我有一个游戏,从IDE运行时如下所示: Plane you = Main.TerrainDemo.shipsID.get(Main.TerrainDemo.UID); Main.TerrainDemo.shader.start(); TexturedModel texturedModel = TerrainDemo.shipModel; //The plane model RawModel model = texturedMod

此问题现已修复。我的着色器属性未正确绑定。

我有一个游戏,从IDE运行时如下所示:

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);

但是,当我使用这些设置从Eclipse导出它时

纹理完全不正确。纹理仍被加载,但它们没有正确地包装到对象上

代码完全相同,因为我只是刚刚导出了它,而且我目前正在同时运行游戏的两个窗口(一个在IDE中运行良好,另一个在导出的JAR中看起来很奇怪)

我还将IDE目录中的所有资源复制到带有外部JAR的文件夹中。IDE目录:

运行外部JAR的目录:

此外,我知道纹理实际上正在加载-它们没有正确包装。我知道这一点是因为:

  • 如果你看这个平面,你可以看到它仍然有纹理的元素——它们只是被拉伸和弄乱了
  • Skybox也是这样。如果你看,零件仍然在那里,但是再一次,它被错误地包装在OBJ模型上
  • 如果我按Q键以使用显示列表渲染地形(多次环绕地形纹理),它将显示纹理。我无法截屏,因为我无法点击Q并截屏
我已经检查了JAR文件的内部,片段和顶点着色器仍然存在。正确的库似乎也在那里(此外,如果没有,游戏甚至不会启动)。

更新: 当我多次重新启动游戏以查看更多信息时,我注意到一旦屏幕显示(以便我可以看到纹理不正确的地形和平面),游戏90%的时间都会冻结。没有Stacktrace,只有一个“此窗口没有响应,windows正在关闭它”。 当我在IDE中运行游戏时,它仍然可以完美地运行而不会崩溃

游戏服务器导出并运行良好。只有客户才是问题所在

如果导出可以使游戏与在IDE中运行游戏有所不同,那么如何解决呢

更新: 下面是我的纹理加载代码:

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();
}
我现在有了纹理的纹理ID。然后,我按如下方式渲染对象(在本例中为平面):

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);
尽管我认为它们并不重要,但我的顶点和片段着色器:

//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);

}
在日志文件中,我看到以下内容:

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]
换句话说,整个问题(纹理和崩溃)开始看起来很像是与着色器相关的问题(或者是对它们的解析信息,或者是实际的着色器代码本身)

我还做了更多的测试,没有使用显示列表的着色器,纹理效果很好

以下是glUniformMatrix()调用的代码:

更新-所以,赏金还有一个小时,我想我应该补充一些细节:

  • 正如我可能在上面的某个地方所说的,游戏在导出时对某些人有效,但对其他人无效。我注意到,当在Java7上运行时,这个游戏总是有效的,但是对于我和另外一名测试人员来说,这并不是决定性的
  • 纹理在显示列表中正确渲染纹理正在加载。但是,它们没有正确显示
  • 即使您不知道问题所在,也非常感谢您尝试游戏(忽略开始屏幕,我需要制作一个新屏幕),并告诉我结果,以及您的OS/Java详细信息等
  • 是的,映射是正确的。我知道有人在评论中提到它可能不是,但我试着把它设置得很高,我确实得到了一个非常模糊的纹理
  • 我已经尝试过“将库打包到外部jar中”。我很感激花了这么多时间来回答这个问题,但我在评论中说我已经试过了
  • 问题可能是片段着色器(如有人在评论中所建议的),但我目前不确定如何测试它,也不理解为什么它在IDE内部工作,而不是在IDE外部工作

    • 我无法测试这一点,所以我不确定这是否有帮助,但OpenGL的一些实现没有在VAOs中保存元素缓冲区。因此,尝试在调用glpaurements之前绑定元素缓冲区,例如

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

      如果不这样做,则可能会对所有绘图调用使用最后绑定的缓冲区。可能不是答案,但测试一下也无妨。我还注意到,您使用的是旧版本的Slick,因为您仍然有Slick util,它不是最新版本的一部分,因此您也可以尝试更新它。

      因此,请尝试此操作,而不是提取所需的库,而改为尝试使用Package选项,因为我个人认为在查找那些库文件或链接某些文件时会出现问题,所以只需运行包即可


      作为一项测试,使用“将所需库复制到子文件夹”选项导出时会发生什么情况?不同之处在于,您正在破坏正在使用的库,并将它们捣碎到一个胖罐子中。@Gimby我将尝试提供相关代码。问题在于,在大约6000行代码中,决定什么是相关的。你可能是对的,而且纹理可能没有正确加载(如果我的特定方法有问题怎么办),因此我将围绕纹理加载代码进行一些测试。我建议切换到将它们打包到jar中,并将它们作为类路径资源加载;这使得无论您在何处以及如何运行游戏,都几乎不可能失败。胡乱猜测:看起来您的mipmap失败了,但您的纹理加载良好。这就解释了你发布的正确和不正确图片中出现颗粒状结果的原因。因此,如果纹理很好,但mipmapping不好,那么纹理的颗粒度将由非常大或未定义的texcoords产生。只有当您的数据是wro时,这才可能
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, someBuffer);
      glDrawElements(GL_TRIANGLES, model.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);