2013-06-15 6 views
1

Я создаю raycaster, используя java, LWJGL и Slick2D. Проблема в том, что я не могу понять, как правильно рисовать из этого байтового массива.рисунок из массива байтов в java LWJGL

Вот как я поместил свою текстуру в colorbuffer. Это работает. Все значения 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;}} 

теперь вот как я создаю мой screenbuffer и назначить пикселей на него:

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 вертикальные линии: красный, зеленый и синий. Это сделает красное одно белое, а другие - черным, а также добавит несколько цветов к текстуре, дальше вдалеке.

Вот изображение того, как оно выглядит. Файл краски - это оригинальная текстура, а правое - это raycaster.

image

Кто-нибудь знает, как решить эту проблему?

+0

полностью связанно между собой, что эта точка зрения в вашем нижнем левом углу, который позволяет перемещаться classmembers? – arynaq

ответ

0

Вы не можете использовать массив объектов awt.Color. Вместо этого используйте ByteArray, которые представляют значения RGB (A) на 32 бита.

Вот моя реализация:

/** 
* 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()); 
} 

Это далеко от совершенства, но это то, что я использую, она отлично работает для меня!

Надеется, что это помогает

Смежные вопросы