LWJGL и загрузка текстуры - похоже, для создания нового объекта в каждом кадре
Итак, я только начал с LWJGL и пытаюсь создать простую 2D-игру на платформе. Проблема, с которой я сейчас спорю, заключается в загрузке текстур. Проблема в том, что все работает очень аккуратно, пока я сохраняю все методы, связанные с загрузкой текстуры, в классе основного метода.
Как только я перевожу его в отдельный класс TextureHandler
это не будет работать, только если я добавлю loadTexture()
метод в drawTexture()
метод. Проблема в том, что он продолжает создавать новые объекты в каждом кадре, насколько я могу судить. У меня есть Google в течение нескольких часов, но я не могу на всю жизнь найти решение.
Основной класс:
public class Main {
String playerPath = "res/PlayerNeutral.png";
public void render() {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
}
public void initGL() {
try {
Display.setDisplayMode(new DisplayMode(800, 600));
Display.create();
Display.setVSyncEnabled(true);
}
catch (LWJGLException e) {
e.printStackTrace();
System.exit(0);
}
// Initiating OpenGL
GL11.glViewport(0, 0, 800, 600);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
// Enables the Alpha Blending
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glOrtho(0, 800, 0, 600, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
}
public void start() {
initGL();
TextureHandler.loadTexture(Player.playerText, playerPath);
while (!Display.isCloseRequested()) {
render();
TextureHandler.drawTexture(Player.playerText, playerPath);
Display.update();
}
Display.destroy();
}
public static void main(String[] args) {
Main test = new Main();
test.start();
}
Класс TextureHandler:
public class TextureHandler {
public static void textRelease(Texture text){
text.release();
}
public static void loadTexture(Texture texture, String path){
try {
texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream(path));
System.out.println("Texture loaded: "+texture);
System.out.println(">> Image width: "+texture.getImageWidth());
System.out.println(">> Image height: "+texture.getImageHeight());
System.out.println(">> Texture width: "+texture.getTextureWidth());
System.out.println(">> Texture height: "+texture.getTextureHeight());
System.out.println(">> Texture ID: "+texture.getTextureID());
TextureImpl.unbind();
}
catch (IOException e) {
e.printStackTrace();
}
}
public static void drawTexture(Texture texture, String path) {
try {
texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream(path));
System.out.println("Texture loaded: "+texture);
System.out.println(">> Image width: "+texture.getImageWidth());
System.out.println(">> Image height: "+texture.getImageHeight());
System.out.println(">> Texture width: "+texture.getTextureWidth());
System.out.println(">> Texture height: "+texture.getTextureHeight());
System.out.println(">> Texture ID: "+texture.getTextureID());
} catch (IOException e) {
e.printStackTrace();
}
Color.white.bind();
texture.bind();
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0, 1);
GL11.glVertex2f(100, 100);
GL11.glTexCoord2f(1, 1);
GL11.glVertex2f(100+texture.getTextureWidth(), 100);
GL11.glTexCoord2f(1, 0);
GL11.glVertex2f(100+texture.getTextureWidth(), 100+texture.getTextureHeight());
GL11.glTexCoord2f(0, 0);
GL11.glVertex2f(100, 100 + texture.getTextureHeight());
GL11.glEnd();
texture.release();
}
}
Класс игрока:
public class Player {
private int x;//x pos on screen
private int y;//y pos on screen
public static Texture playerText;
// method for moving the player object around
public void move() {
if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT))
x++;
if (Keyboard.isKeyDown(Keyboard.KEY_LEFT))
x--;
if (Keyboard.isKeyDown(Keyboard.KEY_UP))
y++;
if (Keyboard.isKeyDown(Keyboard.KEY_DOWN))
y--;
}
}
1 ответ
Это потому, что в вашем drawTexture()
Метод вы делаете следующее.
try {
texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream(path));
System.out.println("Texture loaded: "+texture);
System.out.println(">> Image width: "+texture.getImageWidth());
System.out.println(">> Image height: "+texture.getImageHeight());
System.out.println(">> Texture width: "+texture.getTextureWidth());
System.out.println(">> Texture height: "+texture.getTextureHeight());
System.out.println(">> Texture ID: "+texture.getTextureID());
} catch (IOException e) {
e.printStackTrace();
}
Просто удалите приведенный выше код из вашего drawTexture()
метод.
Текстура все еще загружается, потому что вы уже сделали это один раз, позвонив loadTexture()
метод, прежде чем войти в ваш цикл рендеринга.
редактировать
Я уверен, что уже пробовал это. Я действительно хочу вспомнить, я вставил это туда, потому что без этого не получилось бы, "быстрое решение", если хотите.
Как вы сказали, что я только что понял. Ваш loadTexture()
метод далеко Это, вероятно, потому что вы не знаете, что не можете сделать что-то подобное.
Ссылки передаются по значению в Java. Это означает, что когда вы передаете переменную через метод, переменная становится локальной переменной метода. Таким образом, изменение переменной внутри метода не изменит исходную переменную.
пример
Надеюсь, вы поймете следующий пример. Если вы хотите присвоить что-то новое переменной, вы не можете сделать это, используя переменную, переданную через метод. Вы должны вернуть его, а затем назначить его.
public class PassingVariables {
public static void main(String[] args) {
String s = "Hello World!";
System.out.println(s); // Prints | Hello World!
test1(s);
System.out.println(s); // Prints | Hello World!
s = test2(s);
System.out.println(s); // Prints | Testing...
s = test3(s);
System.out.println(s); // Prints | Hello World!
}
private static String test1(String s) {
System.out.println(s); // Prints | Hello World!
s = "Testing...";
System.out.println(s); // Prints | Testing...
}
private static String test2(String s) {
System.out.println(s); // Prints | Hello World!
return "Testing...";
}
private static String test3(String s) {
System.out.println(s); // Prints | Testing...
return "Hello World!";
}
}
Новый код
Вот ваш код, в котором я изменил некоторые вещи, поэтому он будет работать, когда мы учтем вышеизложенное.
public static Texture loadTexture(String path) {
Texture texture = null;
try {
texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream(path));
/* Removed all your println to spare some lines in the answer */
TextureImpl.unbind();
}
catch (IOException e) {
e.printStackTrace();
}
return texture;
}
public static void drawTexture(Texture texture) {
Color.white.bind();
texture.bind();
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0, 1);
GL11.glVertex2f(100, 100);
GL11.glTexCoord2f(1, 1);
GL11.glVertex2f(100+texture.getTextureWidth(), 100);
GL11.glTexCoord2f(1, 0);
GL11.glVertex2f(100+texture.getTextureWidth(), 100+texture.getTextureHeight());
GL11.glTexCoord2f(0, 0);
GL11.glVertex2f(100, 100 + texture.getTextureHeight());
GL11.glEnd();
/*
* I don't recognize the release() method, but if it deletes the texture
* then remove if. If it simply unbinds the texture then keep it. If it
* does remove it, then change it to something like unbind(), if such
* method exist.
*/
texture.release();
}
public void start() {
initGL();
Player.playerText = TextureHandler.loadTexture(playerPath);
while (!Display.isCloseRequested()) {
render();
TextureHandler.drawTexture(Player.playerText, playerPath);
Display.update();
}
Display.destroy();
}