Java tutorial
/* * Copyright (C) 2013 Clemens-Alexander Brust IT-Dienstleistungen * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package de.ikosa.mars.viewer.glviewer.engine; import de.ikosa.mars.ruleset.TerrainType; import de.ikosa.mars.util.ML; import org.lwjgl.BufferUtils; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL13; import java.nio.ByteBuffer; import java.nio.ShortBuffer; public class GLTexture { private String name; private int textureId; public GLTexture(String name, int textureId) { this.name = name; this.textureId = textureId; } public int getTextureId() { return textureId; } public String getName() { return name; } public void use(int textureUnit) { if (textureUnit >= 0) { GL13.glActiveTexture(GL13.GL_TEXTURE0 + textureUnit); GL11.glBindTexture(GL11.GL_TEXTURE_2D, getTextureId()); } } public int getSizeX() { use(0); return GL11.glGetTexLevelParameteri(GL11.GL_TEXTURE_2D, 0, GL11.GL_TEXTURE_WIDTH); } public int getSizeY() { use(0); return GL11.glGetTexLevelParameteri(GL11.GL_TEXTURE_2D, 0, GL11.GL_TEXTURE_HEIGHT); } public float[][] toHeightMap(int samplesX, int samplesY) { float[][] height = new float[samplesX][samplesY]; ML.d(String.format("Loading texture for height map \"%s\"...", getName())); // check size int texSizeX = getSizeX(); int texSizeY = getSizeY(); if (texSizeX != samplesX | texSizeY != samplesY) ML.f(String.format("Texture size doesn't match height map size! (%d x %d) vs. (%d x %d)", texSizeX, texSizeY, samplesX, samplesY)); // create buffer ShortBuffer byteBuffer = BufferUtils.createShortBuffer(texSizeX * texSizeY); // and go GL11.glGetTexImage(GL11.GL_TEXTURE_2D, 0, GL11.GL_RED, GL11.GL_UNSIGNED_SHORT, byteBuffer); int error = GL11.glGetError(); if (error != GL11.GL_NO_ERROR) ML.f(String.format("Cannot load height map from texture (GL error %x)", error)); // read samples for (int x = 0; x < texSizeX; x++) for (int y = 0; y < texSizeY; y++) { short sValue = byteBuffer.get((samplesX * y + x)); int value = fromShort(sValue); height[x][y] = value / 65535.0f; } return height; } public TerrainType[][] toTerrainMap(int samplesX, int samplesY) { TerrainType[][] height = new TerrainType[samplesX][samplesY]; ML.d(String.format("Loading texture for terrain map \"%s\"...", getName())); // check size int texSizeX = getSizeX(); int texSizeY = getSizeY(); if (texSizeX != samplesX | texSizeY != samplesY) ML.f(String.format("Texture size doesn't match terrain map size! (%d x %d) vs. (%d x %d)", texSizeX, texSizeY, samplesX, samplesY)); // create buffer ByteBuffer byteBuffer = BufferUtils.createByteBuffer(texSizeX * texSizeY * 4); // and go GL11.glGetTexImage(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, byteBuffer); int error = GL11.glGetError(); if (error != GL11.GL_NO_ERROR) ML.f(String.format("Cannot load terrain map from texture (GL error %x)", error)); // read samples for (int x = 0; x < texSizeX; x++) for (int y = 0; y < texSizeY; y++) { float r = fromByte(byteBuffer.get(4 * (samplesX * y + x))) / 255.0f; float g = fromByte(byteBuffer.get(4 * (samplesX * y + x) + 1)) / 255.0f; float b = fromByte(byteBuffer.get(4 * (samplesX * y + x) + 2)) / 255.0f; height[x][y] = TerrainType.fromColor(r, g, b); } return height; } private int fromByte(byte b) { return (b >= 0) ? b : ((int) b) + 256; } private int fromShort(short s) { return (s >= 0) ? s : ((int) s) + 65536; } }