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 对象的数组。请改用 ByteArray,它表示 32 位上的 RGB(A) 值。

这是我的实现:

 /**
 * 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 回答