2013-12-19 2 views
0

왜 LWJGL을 사용하여 투명한 텍스처를 만들 수 없습니까? .PNG 이미지가 텍스처에 이상한 얼룩이 생기기 때문에 .gif 이미지를 사용하고 있습니다. 내가 찾은 다른 답변을 시도했지만 문제가 해결되지 않았습니다. 나는 OpenGL에서 가장 위대한 아니지만 나는 그것을 알아 내려고 많은 노력을 보냈습니다.LWJGL 투명성이 작동하지 않습니까?


texure.java

public class Sprite { 

/** The texture that stores the image for this sprite */ 
private Texture texture; 

/** The width in pixels of this sprite */ 
private int   width; 

/** The height in pixels of this sprite */ 
private int   height; 

/** 
* Create a new sprite from a specified image. 
* 
* @param loader the texture loader to use 
* @param ref A reference to the image on which this sprite should be based 
*/ 
public Sprite(TextureLoader loader, String ref) { 
try { 
     texture = loader.getTexture(ref); 
    width = texture.getImageWidth(); 
    height = texture.getImageHeight(); 
} catch (IOException ioe) { 
    ioe.printStackTrace(); 
    System.exit(-1); 
} 
} 

/** 
* Get the width of this sprite in pixels 
* 
* @return The width of this sprite in pixels 
*/ 
public int getWidth() { 
    return texture.getImageWidth(); 
} 

/** 
* Get the height of this sprite in pixels 
* 
* @return The height of this sprite in pixels 
*/ 
public int getHeight() { 
    return texture.getImageHeight(); 
} 

/** 
* Draw the sprite at the specified location 
* 
* @param x The x location at which to draw this sprite 
* @param y The y location at which to draw this sprite 
*/ 
public void draw(int x, int y) { 
    // store the current model matrix 

    glPushMatrix(); 

    // bind to the appropriate texture for this sprite 
    texture.bind(); 

    // translate to the right location and prepare to draw 
    glTranslatef(x, y, 0); 

    // draw a quad textured to match the sprite 
    glBegin(GL_QUADS); 
    { 
     glTexCoord2f(0, 0); 
     glVertex2f(0, 0); 

     glTexCoord2f(0, texture.getHeight()); 
     glVertex2f(0, height); 

     glTexCoord2f(texture.getWidth(), texture.getHeight()); 
     glVertex2f(width, height); 

     glTexCoord2f(texture.getWidth(), 0); 
     glVertex2f(width, 0); 
    } 
    glEnd(); 

    // restore the model view matrix to prevent contamination 
    glPopMatrix(); 
} 
public void draw(int x, int y,int rotate) { 
    // store the current model matrix 
    glPushMatrix(); 

    // bind to the appropriate texture for this sprite 
    texture.bind(); 

    // translate to the right location and prepare to draw 
    //glTranslatef(x, y, 0); 
    glTranslatef(x+getWidth()/2, y+getHeight()/2, 0); // M1 - 2nd translation 
    glRotatef(rotate, 0.0f, 0.0f, 1.0f);     // M2 
    glTranslatef(-getWidth()/2, -getHeight()/2, 0); // M3 - 1st translation 
    // draw a quad textured to match the sprite 

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

     glTexCoord2f(0, texture.getHeight()); 
     glVertex2f(0, height); 

     glTexCoord2f(texture.getWidth(), texture.getHeight()); 
     glVertex2f(width, height); 

     glTexCoord2f(texture.getWidth(), 0); 
     glVertex2f(width, 0); 
    } 
    glEnd(); 

    // restore the model view matrix to prevent contamination 
    glPopMatrix(); 
} 

texture.java

public class Texture { 

/** The GL target type */ 
private int  target; 

/** The GL texture ID */ 
private int  textureID; 

/** The height of the image */ 
private int  height; 

/** The width of the image */ 
private int  width; 

/** The width of the texture */ 
private int  texWidth; 

/** The height of the texture */ 
private int  texHeight; 

/** The ratio of the width of the image to the texture */ 
private float widthRatio; 

/** The ratio of the height of the image to the texture */ 
private float heightRatio; 

/** 
* Create a new texture 
* 
* @param target The GL target 
* @param textureID The GL texture ID 
*/ 
public Texture(int target, int textureID) { 
    this.target = target; 
    this.textureID = textureID; 
} 

/** 
* Bind the specified GL context to a texture 
*/ 
public void bind() { 
    glBindTexture(target, textureID); 
} 

/** 
* Set the height of the image 
* 
* @param height The height of the image 
*/ 
public void setHeight(int height) { 
    this.height = height; 
    setHeight(); 
} 

/** 
* Set the width of the image 
* 
* @param width The width of the image 
*/ 
public void setWidth(int width) { 
    this.width = width; 
    setWidth(); 
} 

/** 
* Get the height of the original image 
* 
* @return The height of the original image 
*/ 
public int getImageHeight() { 
    return height; 
} 

/** 
* Get the width of the original image 
* 
* @return The width of the original image 
*/ 
public int getImageWidth() { 
    return width; 
} 

/** 
* Get the height of the physical texture 
* 
* @return The height of physical texture 
*/ 
public float getHeight() { 
    return heightRatio; 
} 

/** 
* Get the width of the physical texture 
* 
* @return The width of physical texture 
*/ 
public float getWidth() { 
    return widthRatio; 
} 

/** 
* Set the height of this texture 
* 
* @param texHeight The height of the texture 
*/ 
public void setTextureHeight(int texHeight) { 
    this.texHeight = texHeight; 
    setHeight(); 
} 

/** 
* Set the width of this texture 
* 
* @param texWidth The width of the texture 
*/ 
public void setTextureWidth(int texWidth) { 
    this.texWidth = texWidth; 
    setWidth(); 
} 

/** 
* Set the height of the texture. This will update the 
* ratio also. 
*/ 
private void setHeight() { 
    if (texHeight != 0) { 
     heightRatio = ((float) height)/texHeight; 
    } 
} 

/** 
* Set the width of the texture. This will update the 
* ratio also. 
*/ 
private void setWidth() { 
    if (texWidth != 0) { 
     widthRatio = ((float) width)/texWidth; 
    } 
} 

textureLoader.java

public class TextureLoader { 
/** The table of textures that have been loaded in this loader */ 
private HashMap<String, Texture> table = new HashMap<String, Texture>(); 

/** The colour model including alpha for the GL image */ 
private ColorModel glAlphaColorModel; 

/** The colour model for the GL image */ 
private ColorModel glColorModel; 

/** Scratch buffer for texture ID's */ 
private IntBuffer textureIDBuffer = BufferUtils.createIntBuffer(1); 

/** 
* Create a new texture loader based on the game panel 
*/ 
public TextureLoader() { 
    glAlphaColorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), 
             new int[] {8,8,8,8}, 
             true, 
             false, 
             ComponentColorModel.TRANSLUCENT, 
             DataBuffer.TYPE_BYTE); 

    glColorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), 
             new int[] {8,8,8,0}, 
             false, 
             false, 
             ComponentColorModel.OPAQUE, 
             DataBuffer.TYPE_BYTE); 
} 

/** 
* Create a new texture ID 
* 
* @return A new texture ID 
*/ 
private int createTextureID() { 
    glGenTextures(textureIDBuffer); 
    return textureIDBuffer.get(0); 
} 

/** 
* Load a texture 
* 
* @param resourceName The location of the resource to load 
* @return The loaded texture 
* @throws IOException Indicates a failure to access the resource 
*/ 
public Texture getTexture(String resourceName) throws IOException { 
    Texture tex = table.get(resourceName); 

    if (tex != null) { 
     return tex; 
    } 

    tex = getTexture(resourceName, 
        GL_TEXTURE_2D, // target 
        GL_RGBA,  // dst pixel format 
        GL_LINEAR, // min filter (unused) 
        GL_LINEAR); 

    table.put(resourceName,tex); 

    return tex; 
} 

/** 
* Load a texture into OpenGL from a image reference on 
* disk. 
* 
* @param resourceName The location of the resource to load 
* @param target The GL target to load the texture against 
* @param dstPixelFormat The pixel format of the screen 
* @param minFilter The minimising filter 
* @param magFilter The magnification filter 
* @return The loaded texture 
* @throws IOException Indicates a failure to access the resource 
*/ 
public Texture getTexture(String resourceName, 
          int target, 
          int dstPixelFormat, 
          int minFilter, 
          int magFilter) throws IOException { 
    int srcPixelFormat; 

    // create the texture ID for this texture 
    int textureID = createTextureID(); 
    Texture texture = new Texture(target,textureID); 

    // bind this texture 
    glBindTexture(target, textureID); 

    BufferedImage bufferedImage = loadImage(resourceName); 
    texture.setWidth(bufferedImage.getWidth()); 
    texture.setHeight(bufferedImage.getHeight()); 

    if (bufferedImage.getColorModel().hasAlpha()) { 
     srcPixelFormat = GL_RGBA; 
    } else { 
     srcPixelFormat = GL_RGB; 
    } 

    // convert that image into a byte buffer of texture data 
    ByteBuffer textureBuffer = convertImageData(bufferedImage,texture); 

    if (target == GL_TEXTURE_2D) { 
     glTexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilter); 
     glTexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilter); 
    } 

    // produce a texture from the byte buffer 
    glTexImage2D(target, 
        0, 
        dstPixelFormat, 
        get2Fold(bufferedImage.getWidth()), 
        get2Fold(bufferedImage.getHeight()), 
        0, 
        srcPixelFormat, 
        GL_UNSIGNED_BYTE, 
        textureBuffer); 

    return texture; 
} 

/** 
* Get the closest greater power of 2 to the fold number 
* 
* @param fold The target number 
* @return The power of 2 
*/ 
private static int get2Fold(int fold) { 
    int ret = 2; 
    while (ret < fold) { 
     ret *= 2; 
    } 
    return ret; 
} 

/** 
* Convert the buffered image to a texture 
* 
* @param bufferedImage The image to convert to a texture 
* @param texture The texture to store the data into 
* @return A buffer containing the data 
*/ 
private ByteBuffer convertImageData(BufferedImage bufferedImage,Texture texture) { 
    ByteBuffer imageBuffer; 
    WritableRaster raster; 
    BufferedImage texImage; 

    int texWidth = 2; 
    int texHeight = 2; 

    // find the closest power of 2 for the width and height 
    // of the produced texture 
    while (texWidth < bufferedImage.getWidth()) { 
     texWidth *= 2; 
    } 
    while (texHeight < bufferedImage.getHeight()) { 
     texHeight *= 2; 
    } 

    texture.setTextureHeight(texHeight); 
    texture.setTextureWidth(texWidth); 

    // create a raster that can be used by OpenGL as a source 
    // for a texture 
    if (bufferedImage.getColorModel().hasAlpha()) { 
     raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,texWidth,texHeight,4,null); 
     texImage = new BufferedImage(glAlphaColorModel,raster,false,new Hashtable()); 
    } else { 
     raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,texWidth,texHeight,3,null); 
     texImage = new BufferedImage(glColorModel,raster,false,new Hashtable()); 
    } 

    // copy the source image into the produced image 
    Graphics g = texImage.getGraphics(); 
    g.setColor(new Color(0f,0f,0f,0f)); 
    g.fillRect(0,0,texWidth,texHeight); 
    g.drawImage(bufferedImage,0,0,null); 

    // build a byte buffer from the temporary image 
    // that be used by OpenGL to produce a texture. 
    byte[] data = ((DataBufferByte) texImage.getRaster().getDataBuffer()).getData(); 

    imageBuffer = ByteBuffer.allocateDirect(data.length); 
    imageBuffer.order(ByteOrder.nativeOrder()); 
    imageBuffer.put(data, 0, data.length); 
    imageBuffer.flip(); 

    return imageBuffer; 
} 

/** 
* Load a given resource as a buffered image 
* 
* @param ref The location of the resource to load 
* @return The loaded buffered image 
* @throws IOException Indicates a failure to find a resource 
*/ 
private BufferedImage loadImage(String ref) throws IOException { 
    URL url = TextureLoader.class.getClassLoader().getResource(ref); 

    if (url == null) { 
     throw new IOException("Cannot find: " + ref); 
    } 

    // due to an issue with ImageIO and mixed signed code 
    // we are now using good oldfashioned ImageIcon to load 
    // images and the paint it on top of a new BufferedImage 
    Image img = new ImageIcon(url).getImage(); 
    BufferedImage bufferedImage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB); 
    Graphics g = bufferedImage.getGraphics(); 
    g.drawImage(img, 0, 0, null); 
    g.dispose(); 

    return bufferedImage; 
} 
} 
012,351 당신이 초기화 한 후 6,
+1

glEnable (GL_BLEND)을 호출 했습니까? 및 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); – Ryxuma

+0

OpenGL stuf를 초기화하거나 항목을 그리기 전에 그렇게할까요? –

+0

OpenGL – Ryxuma

답변

1

나는 당신은 모든이를 사용하지 않아도이

혼합의 표준 형식을 가능하게 할 것이다 OpenGL을 호출 가독성

에 대한 답변으로

glEnable(GL_BLEND); 
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 

을이를 놓을 게요 렌더링을 처음 시작할 때 한 번만 호출하십시오.

+0

1 초에 나를 이길 감사합니다 D –

+0

@ GraysonBriggs 하 아무 문제 :) – Ryxuma

관련 문제