net.voidGameDev.world.surface.WorldSurfaceRender.java Source code

Java tutorial

Introduction

Here is the source code for net.voidGameDev.world.surface.WorldSurfaceRender.java

Source

package net.voidGameDev.world.surface;

import static org.lwjgl.opengl.GL11.GL_COMPILE;
import static org.lwjgl.opengl.GL11.GL_LINEAR;
import static org.lwjgl.opengl.GL11.GL_RGB;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MIN_FILTER;
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE;
import static org.lwjgl.opengl.GL11.glBegin;
import static org.lwjgl.opengl.GL11.glBindTexture;
import static org.lwjgl.opengl.GL11.glEnd;
import static org.lwjgl.opengl.GL11.glEndList;
import static org.lwjgl.opengl.GL11.glGenLists;
import static org.lwjgl.opengl.GL11.glGenTextures;
import static org.lwjgl.opengl.GL11.glNewList;
import static org.lwjgl.opengl.GL11.glTexImage2D;
import static org.lwjgl.opengl.GL11.glTexParameteri;
import static org.lwjgl.opengl.GL11.glVertex3f;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;

import javax.imageio.ImageIO;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;

/**
 * @author lclc98 Lesser GNU Public License v3
 *         (http://www.gnu.org/licenses/lgpl.html)
 */
public class WorldSurfaceRender {
    /**
     * The display list that will contain the height-map's vertex data.
     */
    public static int heightmapDisplayList;

    /**
     * The points of the height. The first dimension represents the
     * z-coordinate. The second dimension represents the x-coordinate. The float
     * value represents the height.
     */
    private static float[][] data;

    public static int loadTexture(String path) {
        try {
            BufferedImage image = ImageIO.read(new File(path));
            int[] pixels = new int[image.getWidth() * image.getHeight()];
            image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth());

            ByteBuffer buffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * 4);

            for (int y = 0; y < image.getHeight(); y++) {
                for (int x = 0; x < image.getWidth(); x++) {
                    int pixel = pixels[y * image.getWidth() + x];
                    buffer.put((byte) ((pixel >> 16) & 0xFF));
                    buffer.put((byte) ((pixel >> 8) & 0xFF));
                    buffer.put((byte) (pixel & 0xFF));
                    buffer.put((byte) ((pixel >> 24) & 0xFF));
                }
            }

            buffer.flip();

            int textureID = glGenTextures(); // Generate texture ID
            glBindTexture(GL_TEXTURE_2D, textureID); // Bind texture ID

            // Setup texture scaling filtering
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

            // Send texel data to OpenGL
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.getWidth(), image.getHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE,
                    buffer);

            // Return the texture ID so we can bind it later again
            return textureID;
        } catch (IOException e) {
            e.printStackTrace();
            return 0;
        }

    }

    public void setUpHeightmap(String heightMap, String texture) {
        try {
            // Load the heightmap-image from its resource file
            BufferedImage heightmapImage = ImageIO.read(getClass().getResource(heightMap));
            // Initialise the data array, which holds the heights of the
            // heightmap-vertices, with the correct dimensions
            data = new float[heightmapImage.getWidth()][heightmapImage.getHeight()];
            // Lazily initialise the convenience class for extracting the
            // separate red, green, blue, or alpha channels
            // an int in the default RGB color model and default sRGB
            // colourspace.
            Color colour;
            // Iterate over the pixels in the image on the x-axis
            for (int z = 0; z < data.length; z++) {
                // Iterate over the pixels in the image on the y-axis
                for (int x = 0; x < data[z].length; x++) {
                    // Retrieve the colour at the current x-location and
                    // y-location in the image
                    colour = new Color(heightmapImage.getRGB(x, z));
                    // Store the value of the red channel as the height of a
                    // heightmap-vertex in 'data'. The choice for
                    // the red channel is arbitrary, since the heightmap-image
                    // itself only has white, gray, and black.
                    data[z][x] = colour.getRed();
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

        // Generate a display list handle for the display list that will store
        // the heightmap vertex data
        heightmapDisplayList = glGenLists(32);
        // version 3 and higher.
        GL11.glEnable(GL_TEXTURE_2D);
        int z = 0;
        int x = 0;
        glBindTexture(GL_TEXTURE_2D, loadTexture(texture));
        for (int i = 0; i < 32; i++) {
            glNewList(heightmapDisplayList + i, GL_COMPILE);
            // Iterate over the 'strips' of heightmap data.
            outerLoop: for (; z < data.length - 1; z++) {
                // Render a quad strip for each 'strip'.
                glBegin(GL11.GL_QUAD_STRIP);
                for (; x < data[z].length; x++) {
                    // Take a vertex from the current strip
                    GL11.glTexCoord2d(x, z);
                    glVertex3f(x, data[x][z], z);
                    // Take a vertex from the next strip
                    glVertex3f(x, data[x][z + 1], z + 1);
                    if ((x + 1) % 32 == 0 && (z + 1) % 32 == 0) {
                        glEnd();
                        glEndList();
                        System.out.println(x + ":" + z);
                        break outerLoop;
                    } else {
                        System.out.println((x + 1) % 32);
                    }
                }
            }
        }
        System.out.println("DOne");
    }

    public float getHeight(int x, int z) {
        return data[z][x];
    }

}