Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 6 of 6

Thread: Volume rendering, alpha blending problem

  1. #1
    Junior Member Newbie
    Join Date
    Aug 2014
    Posts
    4

    Volume rendering, alpha blending problem

    First of all, I'm newbie OpenGL developer. I found tutorial about Volume Rendering (google: getting started with volume rendering) and tried to implement my own renderer. I got to the point when I can draw all slices at once with alpha testing, which gives me more or less such result as in tutorial. Now, I want to move step forward and apply alpha blending, but after that there is no change (and even if there is, it doesn't look such nice as in tutorial). Here is my rendering code:

    Code :
    glClear(GL_COLOR_BUFFER_BIT  | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_TEXTURE_2D);
     
    for (int i = 0; i < z; ++i)
    {
        glBindTexture(GL_TEXTURE_2D, texturesObjects[i]);
     
        glBegin(GL_QUADS);
     
        glTexCoord2f(0.0f, 0.0f);
        glVertex3f(-1.0, -1.0, 2 * i / z - 1);
        glTexCoord2f(1.0f, 0.0f);
        glVertex3f(1.0, -1.0, 2 * i / z - 1);
        glTexCoord2f(1.0f, 1.0f);
        glVertex3f(1.0, 1.0, 2 * i / z - 1);
        glTexCoord2f(0.0f, 1.0f);
        glVertex3f(-1.0, 1.0, 2 * i / z - 1);
     
        glEnd();
        glBindTexture(GL_TEXTURE_2D, 0);
    }
     
    glutSwapBuffers();

    where z is number of slices. Texture generation code looks like that:
    Code :
    GLuint* loadXZslices(const VR::DataAccessor& accessor, int& x, int& y, int& z)
    {
    x = accessor.getX();
    y = accessor.getY();
    z = accessor.getZ();
     
    GLuint* texturesObjects = new GLuint[accessor.getZ()];
     
    for (size_t i = 0; i < accessor.getZ(); ++i)
    {
        char* luminanceBuffer = accessor.getXYslice(i);
        char* rgbaBuffer = new char[accessor.getX() * accessor.getY() * 4];
     
        for (size_t j = 0; j < accessor.getX() * accessor.getY(); ++j)
        {
            rgbaBuffer[j * 4] = luminanceBuffer[j];
            rgbaBuffer[j * 4 + 1] = luminanceBuffer[j];
            rgbaBuffer[j * 4 + 2] = luminanceBuffer[j];
            rgbaBuffer[j * 4 + 3] = 255;
     
            if (luminanceBuffer[j] < 20)
            {
                rgbaBuffer[j * 4 + 3] = 0;
            }
        }
     
        glActiveTexture(GL_TEXTURE0);
        glGenTextures(1, &texturesObjects[i]);
        glBindTexture(GL_TEXTURE_2D, texturesObjects[i]);
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, accessor.getX(), accessor.getY(), 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)rgbaBuffer);
     
        delete[] luminanceBuffer;
        delete[] rgbaBuffer;
    }
     
    return texturesObjects;
    }

    DataAccessor is of course class that gives access to raw texture data.

    Did I forget about setting something in my window or is there something wrong with my code? Help me, I'm desperate! :P

  2. #2
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,397
    Quote Originally Posted by ananananda View Post
    Code cpp:
            ...
            rgbaBuffer[j * 4] = luminanceBuffer[j];
            rgbaBuffer[j * 4 + 1] = luminanceBuffer[j];
            rgbaBuffer[j * 4 + 2] = luminanceBuffer[j];
            rgbaBuffer[j * 4 + 3] = 255;
     
        ...
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
        ...
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, accessor.getX(), accessor.getY(), 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)rgbaBuffer);

    Did I forget about setting something in my window or is there something wrong with my code?
    Quick-scanning your code, it looks like your fragment alpha is going to be determined by the alpha of the texture, which is always set to 100% opaque (255).

    Did I miss something?

  3. #3
    Junior Member Newbie
    Join Date
    Aug 2014
    Posts
    4
    Hmm, you are right. It seems to be a problem, but this idea comes from tutorial. It means that it is impossible to achive such effect with this code = there is a bug in tutorial. But some comment there claims, that with 3D texture it works, how is it possible?

  4. #4
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,397
    Quote Originally Posted by ananananda View Post
    Hmm, you are right. It seems to be a problem, but this idea comes from tutorial. It means that it is impossible to achive such effect with this code = there is a bug in tutorial. But some comment there claims, that with 3D texture it works, how is it possible?
    Not having seen the full source, it's possible they are obtaining translucency from somewhere else at a higher level. But from what you quoted (including blend equation), we're not seeing that here.

    Also, there are a number of different ways to do "volume rendering". Which one is this?

  5. #5
    Junior Member Newbie
    Join Date
    Aug 2014
    Posts
    4
    it is texture based volume rendering. I figured it out, there was a bug in tutorial. When I changed rgbaBuffer[j * 4 + 3] = 255; to rgbaBuffer[j * 4 + 3] = luminanceBuffer[j]; it started to looked like it should

  6. #6
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,397
    Quote Originally Posted by ananananda View Post
    it is texture based volume rendering.
    No, I mean which technique: maximum intensity projection, multiplanar reformatting, 3D shaded surface (marching cubes/tetrahedra), segmentation, etc. I think you're just talking about rendering all the slices with a constant translucency so you can see into the volume to some degree.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •