1

Java、LWJGL、Slick2D を使用してレイキャスターを作成しています。問題は、このバイト配列から正しく描画する方法がわからないことです。

これが、テクスチャをカラーバッファに入れる方法です。これは機能します。すべての RGB 値は、テクスチャ内の値と同じです。

    public java.awt.Color[] colorBuffer;
for (int y = 0; y < image.getHeight(); y++) {
        for (int x = 0; x < image.getWidth(); x++) {
            c = new java.awt.Color(image.getRGB(x, y));
            colorBuffer[y * Width + x] = c;}}

スクリーンバッファを作成してピクセルを割り当てる方法は次のとおりです。

static byte[] buffer;
static int screenTexture;

public static void main() {
        buffer = new byte[Display.Height * Display.Width];
        screenTexture = GL11.glGenTextures();
        texture = new Sprite(new Vector2f(0, 0), "src/Content/Textures/tex1.bmp");
}

// in the raycasting algorithm:
buffer[y * Display.Width + x] = (byte) texture.colorBuffer[texY * texture.Width + texX].getRed();
                buffer[y * Display.Width + x + 1] = (byte) texture.colorBuffer[texY * texture.Width + texX].getGreen();
                buffer[y * Display.Width + x + 2] = (byte) texture.colorBuffer[texY * texture.Width + texX].getBlue();
                buffer[y * Display.Width + x + 3] = (byte) texture.colorBuffer[texY * texture.Width + texX].getAlpha();

バッファを描画する方法は次のとおりです。

org.newdawn.slick.Color.white.bind();
        ByteBuffer b = BufferUtils.createByteBuffer(buffer.length * 4); // times four due to every pixel having RGBA.
        for (int a = 0; a < buffer.length; a++) {
            b.put(a, buffer[a]);
        }
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, 2);
        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, Display.Width / 4, Display.Height, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, b);

        GL11.glBegin(GL11.GL_QUADS);
        {
            GL11.glTexCoord2f(0, 0);
            GL11.glVertex2f(0, 0);

            GL11.glTexCoord2f(1, 0);
            GL11.glVertex2f(Display.Width, 0);

            GL11.glTexCoord2f(1, 1);
            GL11.glVertex2f(Display.Width, Display.Height);

            GL11.glTexCoord2f(0, 1);
            GL11.glVertex2f(0, Display.Height);
        }
        GL11.glEnd();

ここで、赤、緑、青の 3 本の垂直線であるテクスチャを作成するとします。赤を白に、他を真っ黒にするだけでなく、遠くにあるほどテクスチャにいくつかの色を追加します。

これがどのように見えるかの画像です。ペイント ファイルは元のテクスチャで、右のウィンドウはレイキャスターです。

画像

この問題を解決する方法を知っている人はいますか?

4

1 に答える 1

1

awt.Color オブジェクトの配列を使用しないでください。代わりに、32 ビットで RGB(A) 値を表す ByteArray を使用してください。

ここに私の実装があります:

 /**
 * conversion des Images java en buffer
 * 
 * @param source image java
 * @param x0 gauche
 * @param x1 droite
 * @param y0 haut
 * @param y1 bas
 * @param colormode nombre de canaux à lire dans l'image
 * @return buffer
 */
public static ByteBuffer byteBufferFromImageBuffer(BufferedImage source, int x0, int x1, int y0, int y1, int colormode) {
    ByteBuffer buffer = BufferUtils.createByteBuffer((x1 - x0) * (y1 - y0)
            * colormode);
    switch (colormode) {
    case 1:
        for (int y = y0; y < y1; y++) {
            for (int x = x0; x < x1; x++) {
                int pixel = source.getRGB(x, y);
                buffer.put((byte) (pixel & 0xFF)); // Blue component
            }
        }
        break;

    case 3:
        for (int y = y0; y < y1; y++) {
            for (int x = x0; x < x1; x++) {
                int pixel = source.getRGB(x, y);
                buffer.put((byte) ((pixel >> 16) & 0xFF)); // Red component
                buffer.put((byte) ((pixel >> 8) & 0xFF)); // Green component
                buffer.put((byte) (pixel & 0xFF)); // Blue component
            }
        }
        break;
    case 4:
        for (int y = y0; y < y1; y++)
            for (int x = x0; x < x1; x++)
                buffer.putInt(source.getRGB(x, y));
        break;
    default:
        warn("bad colormode");
        break;
    }

    buffer.flip(); 
    // reste a effectuer les oppérations OGL depuis le thread principal
    return buffer;
            // now you can call buffer2GLTex() from rendering thread.
}

     /**
 * pour LWJGL convertit une bitmap bufferisée en texture. Après cette étape,
 * le buffer peut-être détruit
 * 
 * @param openGL tex id
 * @param w largeur en pixel du buffer
 * @param h hauteur en pixel du buffer
 * @param buffer data
 * @param colormode la texture sera noir et blanc (1), rgb (3) ou rgba(4)
 */
public static void buffer2GLTex(int tex, int w, int h, ByteBuffer buffer, int colormode) {
    glBindTexture(GL_TEXTURE_2D, tex);


    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    int texFiltering = TexLinFilter ? GL_LINEAR : GL_NEAREST;

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texFiltering);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texFiltering);

    // Generate The Texture
    int format = 0;
    switch (colormode) {
    case 1:
        format = GL_LUMINANCE;
        break;
    case 3:
        format = GL_RGB;
        break;
    case 4:
                    // format = GL_RGBA;
        format = GL_BGRA;
        break;

    default:
        err("bad colormode");
        break;
    }
    glTexImage2D(GL_TEXTURE_2D, 0, ColorMode, w, h, 0, format, GL_UNSIGNED_BYTE, buffer);

    glErr(glGetError());
}

これは完璧にはほど遠いですが、私が使っているもので、私にとってはうまくいきます!

それが役に立てば幸い

于 2013-07-09T11:16:14.770 に答える