Экспорт проекта Eclipse вызывает неправильное текстурирование и сбои,
Теперь эта проблема исправлена. Мои атрибуты шейдера не были правильно связаны.
У меня есть игра, которая при запуске из IDE выглядит так:
![введите описание изображения здесь]()
Однако, когда я экспортирую его из Eclipse с этими настройками,
![введите описание изображения здесь]()
Текстурирование полностью неверно. Текстуры все еще загружаются, но они не корректно обертываются на объект.
![введите описание изображения здесь]()
Код точно такой же, как я только что экспортировал его, и в настоящее время я запускаю оба окна игры одновременно (один работает отлично от IDE, один выглядит странно из экспортированного JAR).
Я также скопировал все ресурсы из каталога IDE в папку с внешним JAR. Каталог IDE:
![введите описание изображения здесь]()
Directory Я запускаю внешний JAR из:
![введите описание изображения здесь]()
Кроме того, я знаю, что текстуры фактически загружаются - они не обертываются правильно. Я знаю это потому, что:
- Если вы посмотрите на самолет, вы увидите, что он все еще имеет элементы текстуры - они просто растянуты и перепутаны.
- То же самое с Skybox. Если вы посмотрите на это, части все еще там, но опять же, это неверно обернуто вокруг модели OBJ.
- Если я нажал клавишу Q, чтобы отобразить рельеф с помощью DisplayList (многократное обтекание текстуры ландшафта), он показывает текстуру. Невозможно получить снимок экрана, потому что я не могу нажать Q и сделать снимок экрана.
Я проверил внутри JAR файла, и фрагмент и вершинный шейдер все еще существуют. Правильные библиотеки также присутствуют (кроме того, если они не были, игра даже не началась).
![введите описание изображения здесь]()
Обновление:
Поскольку я повторно запускал игру несколько раз, чтобы проверить дополнительную информацию, я заметил, что, как только на дисплее отобразится (чтобы я мог видеть неправильно текстурированную местность и плоскость), игра замерзает примерно в 90% случаев. Нет Stacktrace, просто "Это окно не отвечает, а окна закрывают его".
Игра по-прежнему отлично работает без сбоев, когда я запускаю ее в среде 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();
}
Теперь у меня есть ИД текстуры текстуры. Затем я представляю объект (в данном случае плоскость) следующим образом:
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);
}
Опять же, я подчеркну, что все это прекрасно работает, если игра запущена из среды IDE. Это просто, если он запускается из внешнего JAR, что проблема возникает.
Я буду экспериментировать с различными методами и методами текстурной загрузки (например, упаковывать текстуры в JAR) и видеть, происходит ли что-то другое.
Еще одно обновление:
Итак, я отправил игру другому человеку (они также используют окна 8), и игра отлично работала! Никаких ошибок текстурирования! Итак, теперь я не уверен, что проблема связана с моим ПК или что-то еще.
Для тех, кто хочет попробовать, вы можете скачать игру http://endcraft.net/PlaneGame и посмотреть ее самостоятельно (пожалуйста, прочтите инструкцию. - Кроме того, вам понадобится программа для распаковки файлов .rar).
Я получаю столько людей, сколько знаю, чтобы дать игре ход и посмотреть, есть ли у них одна и та же проблема или правильность текстурирования.
Меня полностью озадачивает, что он отлично работает, когда я запускаю его из среды IDE, но не работает, когда я экспортирую во внешнюю банку, но работает, когда я экспортирую его во внешнюю банку и отправляю ее кому-то еще!
(другое) Обновление:
Я отправил игру нескольким людям, некоторые из них сталкиваются с этим сбоем:
# 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]
#
В файле журнала я вижу следующее:
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]
Другими словами, вся проблема (текстурирование и сбои) начинает сильно напоминать, что они связаны с шейдерами (либо разбору информации для них, либо самому собственно шейдерному коду).
Я также провел больше тестирования, и текстурирование отлично работает без шейдеров с помощью DisplayList.
Вот код до вызова glUniformMatrix():
//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);
}
Обновление. Итак, с часом, оставшимся на Bounty, я подумал, что добавлю еще несколько деталей:
- Как я, наверное, сказал где-то выше, игра работает для некоторых при экспорте, но не для других. Я заметил, что игра всегда срабатывала при запуске java 7, но со мной только я и еще один тестер на java 7, это действительно не убедительно.
- Текстурирование корректно отображается в DisplayList. Текстуры загружаются. Однако они отображаются неправильно.
- Даже если вы не знаете проблему, попробуйте игру (проигнорируйте начальный экран, мне нужно сделать новый) и сообщите мне результаты, а также данные о вашей ОС /Java и т.д. действительно оценили.
- Да, mipmapping верен. Я знаю, что кто-то в комментариях упоминал, что, возможно, это не так, но я попытался установить его глупо высоким, и я действительно получаю очень размытую текстуру.
- Я уже пробовал "библиотеки пакетов во внешнюю банку". Я ценю время, затраченное на этот ответ, но я сказал в комментариях, что я уже пробовал.
- Проблема может быть фрагментарным шейдером (как кто-то предложил в комментариях), но в настоящее время я не уверен, что , как, чтобы проверить его, и не понимаю, почему он будет работать внутри IDE, но не снаружи из этого.
Ответы
Ответ 1
Я не могу проверить это, поэтому я не уверен, поможет ли это, но некоторые реализации OpenGL не сохраняют буферы элементов в VAO. Поэтому попробуйте привязать буфер элемента до вызова glDrawElements, например.
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, someBuffer);
glDrawElements(GL_TRIANGLES, model.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
Если вы этого не сделаете, вы можете использовать последний связанный буфер для всех вызовов рисования. Наверное, не ответ, но это не помешало проверить его. Я также заметил, что вы используете более старую версию Slick, поскольку у вас все еще есть утилита slick-util, которая не является частью последней версии, поэтому вы также можете попробовать ее обновить.
Ответ 2
Итак, попробуйте это вместо того, чтобы извлекать необходимые библиотеки, попробуйте вариант "Пакет", потому что я лично считаю, что есть проблема при поиске этих файлов библиотек или связывании некоторого файла, а затем просто запускайте пакет.
![Вариант]()