Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Alpha test for textures not working [Solved]  (Read 2782 times)

0 Members and 1 Guest are viewing this topic.

axus

  • Newbie
  • *
  • Posts: 5
    • View Profile
Alpha test for textures not working [Solved]
« on: November 15, 2010, 08:21:19 am »
I fixed this, the solution was to add "ilDisable(IL_BLIT_BLEND)".  Apparently the ilBlit function would combine alpha channels by default, instead of overwriting them.

Any other advice for cleaning up my code is welcome, though :)

=========
I haven't used OpenGL before this week, I'm probably making an obvious mistake.

I'm using DevIL to load a PNG file with alpha channel, blit a piece of the file to another texture, and use that texture to draw 6 faces of a cube.

It starts off black (I think transparent), but as I blit other textures a lot by holding down the arrow key, I'll see the textures with random transparent parts.  The scary thing is, if I free the DevIL image after loading to openGL with glTexImage2D, it will stay transparent.  I think it's only corrupted memory that is letting me see anything!

Here's the complete code...
Code: [Select]

//SFML test app

//SFML
#include <SFML/System.hpp>
#include <SFML/Window.hpp>

//DevIL
#include <IL/il.h>
#include <IL/ilu.h>

//STL
#include <iostream>
#include <string>

using std::cout;
using std::cerr;
using std::endl;
using std::string;

const string imageFilename("terrain.png");

//openGL image
GLuint image;
size_t texmap_X = 1;
size_t texmap_Y = 3;
const size_t texmap_SIZE = 16;
//Start

//draw cube faces
void drawCubes() {
   
    //Draw cube
    glBegin(GL_QUADS);
   
    //x: A = -50, B = 50
    //y: C = -50, D = 50
    //z: E = -50, F = 50
    //A
    glTexCoord2i(0,0); glVertex3i( -16, -16, -16);  //Lower left
    glTexCoord2i(1,0); glVertex3i( -16, -16,  16);  //Lower right
    glTexCoord2i(1,1); glVertex3i( -16,  16,  16);  //Top right
    glTexCoord2i(0,1); glVertex3i( -16,  16, -16);  //Top left

    //B
    glTexCoord2i(0,0); glVertex3i(  16, -16,  16);  //Lower left:  BCF
    glTexCoord2i(1,0); glVertex3i(  16, -16, -16);  //Lower right: BCE
    glTexCoord2i(1,1); glVertex3i(  16,  16, -16);  //Top right:   BDE
    glTexCoord2i(0,1); glVertex3i(  16,  16,  16);  //Top left:    BDF
   
    //C
    glTexCoord2i(0,0); glVertex3i( -16, -16, -16);  //Lower left:  ACE
    glTexCoord2i(1,0); glVertex3i(  16, -16, -16);  //Lower right: BCE
    glTexCoord2i(1,1); glVertex3i(  16, -16,  16);  //Top right:   BCF
    glTexCoord2i(0,1); glVertex3i( -16, -16,  16);  //Top left:    ACF
   
    //D
    glTexCoord2i(0,0); glVertex3i( -16,  16,  16);  //Lower left:  ADF
    glTexCoord2i(1,0); glVertex3i(  16,  16,  16);  //Lower right: BDF
    glTexCoord2i(1,1); glVertex3i(  16,  16, -16);  //Top right:   BDE
    glTexCoord2i(0,1); glVertex3i( -16,  16, -16);  //Top left:    ADE
   
    //E
    glTexCoord2i(0,0); glVertex3i(  16, -16, -16);  //Lower left:  BCE
    glTexCoord2i(1,0); glVertex3i( -16, -16, -16);  //Lower right: ACE
    glTexCoord2i(1,1); glVertex3i( -16,  16, -16);  //Top right:   ADE
    glTexCoord2i(0,1); glVertex3i(  16,  16, -16);  //Top left:    BDE
   
    //F
    glTexCoord2i(0,0); glVertex3i( -16, -16,  16);  //Lower left:  ACF
    glTexCoord2i(1,0); glVertex3i(  16, -16,  16);  //Lower right: BCF
    glTexCoord2i(1,1); glVertex3i(  16,  16,  16);  //Top right:   BDF
    glTexCoord2i(0,1); glVertex3i( -16,  16,  16);  //Top left:    ADF

    glEnd();
}


//Blit from texture map to current OpenGL texture
ILuint blitTexture( ILuint texmap, ILuint SrcX, ILuint SrcY, ILuint Width, ILuint Height) {
    //Take out a specific block from the texture grid (Blit)
    ILuint il_blocktex;
    ilGenImages(1, &il_blocktex);
    ilBindImage(il_blocktex);
    ilTexImage( Width, Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL);

    //Blit the rectangle from texmap to il_blocktex
    ilBlit( texmap, 0, 0, 0, SrcX, SrcY, 0, Width, Height, 1);

    glBindTexture(GL_TEXTURE_2D, image);
   
    //Set zoom filters
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);  //GL_LINEAR?
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    //Copy current DevIL image to OpenGL image
    glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP),
        ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), 0,
        ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData());

    //ilDeleteImages(1, &il_blocktex);  //free memory used by DevIL
    return il_blocktex;
}


//Set up buffer, perspective, blah blah blah
void startOpenGL() {
    //OPENGL setup in SFML
    //Set color and depth clear value
    glClearDepth(1.0f);
    glClearColor(0.f, 0.f, 0.f, 1.f);

    // Enable Z-buffer read and write
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);

    //Enable texture mapping
    glViewport(0, 0, 800, 600);
    glEnable(GL_TEXTURE_2D);
   
    //Transparency in textures
    glEnable(GL_ALPHA_TEST);
    glAlphaFunc(GL_GREATER, 0.5f);

    // Setup perspective projection
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(90.f, 1.f, 1.f, 500.f);

    //Move camera
    glMatrixMode(GL_MODELVIEW);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glLoadIdentity();

    //Create OpenGL texture
    glGenTextures(1, &image);
}


//Load the image file
ILuint loadImageFile() {
    ILuint il_texmap;
    ilGenImages(1, &il_texmap);
    ilBindImage(il_texmap);

    if (ilLoad(IL_PNG, imageFilename.c_str())) {
     
        //Convert image to RGBA
        if (!ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE)) {
            cerr << "Error converting " << imageFilename << endl;
            ILenum ilErrorCode = 0;
            while ( (ilErrorCode = ilGetError()) != IL_NO_ERROR) {
                cerr << "Error code " << ilErrorCode << endl;
            }
            return 0;
        }
   
    } else {
        cerr << "Error loading " << imageFilename << endl;
        ILenum ilErrorCode = 0;
        while ( (ilErrorCode = ilGetError()) != IL_NO_ERROR) {
            cerr << "Error code " << ilErrorCode << endl;
        }
        return 0;
    }

    return il_texmap;
}

int main()
{
    //Compare devIL DLL version to header version
    if (ilGetInteger(IL_VERSION_NUM) < IL_VERSION) {
        cerr << "devIL wrong DLL version" << endl;
        return 1;
    }
 
    //SFML variables
    sf::Clock Clock;
    sf::WindowSettings Settings;
    Settings.DepthBits = 24;
    Settings.StencilBits = 8;
    Settings.AntialiasingLevel = 2;

    //Create the program window, with settings
    sf::Window App(sf::VideoMode(800, 600, 32),
        "SFML OpenGL", sf::Style::Close, Settings);

    //Initialize OpenGL
    startOpenGL();

    //Start DevIL
    ilInit();

    //Load terrain image map
    ILuint il_texmap = loadImageFile();
    if (il_texmap == 0) {
        return 0;   //error, exit program
    }
   
    //Pick a texture
    blitTexture( il_texmap, texmap_X * texmap_SIZE, texmap_Y * texmap_SIZE,
        texmap_SIZE, texmap_SIZE);

    //Event loop    
    sf::Event Event;
    bool Running = true;
    while (Running && App.IsOpened()) {
     
        //Set window
        App.SetActive();

        //Clear window
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
       
        //Move camera
        glTranslatef(0, -30, -100);    

        //Rotate camera
        glRotatef(Clock.GetElapsedTime() * 2, 1, 0, 0);    //yaw
        glRotatef(Clock.GetElapsedTime() * 30, 0, 1, 0);    //Rotate about Y axis
        //glRotatef(Clock.GetElapsedTime() * 90, 0, 0, 1);    //roll

        drawCubes();
       
        //Display the rendered frame
        App.Display();

        //Check events  
        while (App.GetEvent(Event))
        {
            switch( Event.Type) {
                case sf::Event::Resized:
                    glViewport(0,0, Event.Size.Width, Event.Size.Height);
                    break;
                case sf::Event::KeyPressed:
                    switch ( Event.Key.Code) {
                        case sf::Key::Escape:
                            Running = false;
                            break;
                        case sf::Key::Up:
                            texmap_Y = (texmap_Y - 1) % 16;
                            blitTexture( il_texmap, texmap_X * texmap_SIZE,
                                texmap_Y * texmap_SIZE, texmap_SIZE, texmap_SIZE);
                            break;
                        case sf::Key::Down:
                            texmap_Y = (texmap_Y + 1) % 16;
                            blitTexture( il_texmap, texmap_X * texmap_SIZE,
                                texmap_Y * texmap_SIZE, texmap_SIZE, texmap_SIZE);
                            break;
                        case sf::Key::Left:
                            texmap_X = (texmap_X - 1) % 16;
                            blitTexture( il_texmap, texmap_X * texmap_SIZE,
                                texmap_Y * texmap_SIZE, texmap_SIZE, texmap_SIZE);
                            break;
                        case sf::Key::Right:
                            texmap_X = (texmap_X + 1) % 16;
                            blitTexture( il_texmap, texmap_X * texmap_SIZE,
                                texmap_Y * texmap_SIZE, texmap_SIZE, texmap_SIZE);
                            break;
                        default:
                            break;
                    }
                    break;
                default:
                    break;
            }
        }
    }
   
    return 0;
   
}


How I compile:
Code: [Select]

g++ -Wall -O3  -I/c/dev/axus/include -o build/main.o -c src/main.cpp
g++ build/main.o -Wall -O3 -Wl,--enable-auto-import -L/c/dev/axus/lib -lopengl32 -lglu32 -lDevIL -lILU -lsfml-system -lsfml-window -lwsock32 -o testsfml.exe

axus

  • Newbie
  • *
  • Posts: 5
    • View Profile
I think OpenGL is working fine
« Reply #1 on: November 15, 2010, 07:03:18 pm »
I put some debugging in my code to dump the raw bytes of the image after I load it.  I can see that the Alpha channel starts off at 0, and as I keep blitting images eventually I'll get some FF in there.  It corresponds to what's being displayed.

So, I believe it's an issue with how I'm blitting or how I'm loading the PNG file.  More investigation to follow :)