Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 3 123 LastLast
Results 1 to 10 of 21

Thread: blending

  1. #1
    Intern Contributor
    Join Date
    Dec 2007
    Posts
    62

    blending

    Hi! i have a problem with blending.. my code should blend a valume made of 3 "slices" and read the blended value.. From what I’ve read, the function GL_ONE_MINUS_SRC_ALPHA should calculate the blended value(for 3 "slices" like in my code), resolving this expression:
    ((µ1*α1)*(1-α2)+ µ2*α2)*(1-α3)+(µ3*α3)

    where µ1 is the value of the first "slice" and α1 is the alpha value of the first slice ( and so on...)

    so.. the result is 2 ( that is a reasonable result). but the result of the program is always half of the expected value. f.e. with 3 slices and the values µ1=1,µ2=2,µ3=3 the result is 1 (instead of 2), if the result should be 40, the program give 20 and so on.. so i think that the program is correct because it is wrong in a "correct way". maybe there's something that i don't know about the method, or maybe i'm not considerating all.. please help!!!!!!!!





    #include <cstdio>
    #include <cstdlib>
    using namespace std;

    #include <gl\glew.h>
    #include <gl\glut.h>
    #include <gl\gl.h>
    #include <gl\glu.h>

    #include <windows.h>

    //trasforms alpha from double to char and from 0 and 255
    char DoubleToChar(double alpha){
    return (char)(alpha*255.0);
    }

    int main(int argc, char **argv) {

    //Volume values: it represents a 1x1x3 volume ( 3 slices along z)
    unsigned char Volumevalues[12]={1,0,0,1,2,0,0,0,3,0,0,0};
    Volumevalues [3]=DoubleToChar(1.0);
    Volumevalues [7]=DoubleToChar(1.0/2.0);
    Volumevalues [11]=DoubleToChar(1.0/3.0);
    unsigned char result [16]; //array for the result

    //initialize glut
    glutInit (&argc, argv);
    glutCreateWindow("radiographic simulation");
    glewInit();

    // create the texture
    GLuint tex;
    glGenTextures (1, &tex);
    glBindTexture(GL_TEXTURE_3D,tex);

    // sets texture’s parameters
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);

    //allocate the texture
    glTexImage3D(GL_TEXTURE_3D,0,GL_RGBA,1,1,4,0,GL_RG BA,GL_UNSIGNED_BYTE, Volumevalues);

    //viewport transform for 1:1 pixel=texel=data mapping
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0,1,0.0,1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glViewport(0,0,1,1);



    glPushMatrix();

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

    float a= ((float)0.5)/3.0;
    float b =((float)1.5)/3.0;
    float c= ((float)2.5)/3.0;

    glBegin(GL_QUADS);
    glTexCoord3f(0.0,0.0,a); glVertex2f(0,0);
    glTexCoord3f(0.0,1.0,a); glVertex2f(0,1);
    glTexCoord3f(1.0,1.0,a); glVertex2f(1,1);
    glTexCoord3f(1.0,0.0,a); glVertex2f(1,0);

    glTexCoord3f(0.0,0.0,b); glVertex2f(0,0);
    glTexCoord3f(0.0,1.0,b); glVertex2f(0,1);
    glTexCoord3f(1.0,1.0,b); glVertex2f(1,1);
    glTexCoord3f(1.0,0.0,b); glVertex2f(1,0);

    glTexCoord3f(0.0,0.0,c); glVertex2f(0,0);
    glTexCoord3f(0.0,1.0,c); glVertex2f(0,1);
    glTexCoord3f(1.0,1.0,c); glVertex2f(1,1);
    glTexCoord3f(1.0,0.0,c); glVertex2f(1,0);

    glEnd();
    glPopMatrix();

    glutSwapBuffers();

    //reads datas from the frame buffer and write them into the array result
    glReadBuffer(GL_FRONT);
    glReadPixels(0,0,1,1,GL_RGBA,GL_BYTE,result);

    // print out results
    printf("Data before roundtrip:\n");
    for (int i=0; i<16; i++)
    printf("%d\n", Volumevalues [i]);
    printf("Data after roundtrip:\n");
    for (int i=0; i<4; i++)
    printf("%d\n",result[i]);

    getchar();


    return 0;

    }

  2. #2
    Advanced Member Frequent Contributor
    Join Date
    Apr 2004
    Posts
    999

    Re: blending

    Are you taking numerical inaccuracies into account?

    e.g. in the first pass, if you have a value of 2 (range 0...255) with an alpha of 0.15, the resulting value is 0.30 which is rounded down to 0 when writing to a 32bpp RGBA framebuffer.

    If you want to avoid this, use a for-loop in a fragment shader to iterate over the different slices.

    N.

  3. #3
    Senior Member OpenGL Guru
    Join Date
    Mar 2001
    Posts
    3,768

    Re: blending

    From what I’ve read, the function GL_ONE_MINUS_SRC_ALPHA should calculate the blended value(for 3 "slices" like in my code), resolving this expression:
    ((µ1*α1)*(1-α2)+ µ2*α2)*(1-α3)+(µ3*α3)
    In order for your equation to be correct, you must ensure that the destination color before doing any rendering is (0, 0, 0, 0). Otherwise, you should use a separate blending equation for the first pass.

    And put your code in [ code ] tags.

  4. #4
    Intern Contributor
    Join Date
    Dec 2007
    Posts
    62

    Re: blending

    for Nico: alpha values are trasformed into the range 0-255 (the first fuction in the code), so using a char and not a float ,why there should be numerical inaccuracies? and.. what do you mean with your solution? isn't it enough blend the slices like i do?

    for Korval: i tryed to clear the color buffer, but the result is the same..

    suggestions???(i am repetitive but, i remind you that the program works.. in a "correct" wrong way, and the strange thing is that in the result, alpha value is 127 ( i don't mind because i need only the color values..) that is half of 255 (half like the color value), maybe there's a relation..

  5. #5
    Advanced Member Frequent Contributor
    Join Date
    Apr 2004
    Posts
    999

    Re: blending

    I don't know how to be any clearer than in my previous post. Suppose you want to calculate the sum of 3 values in the range 0-255. The range of this sum is 0-3*255 and you are writing the result to a pixel with a range of 0-255 so it's impossible to get the full resolution of your result, hence the inaccuracies.

    PS. If you just want to calculate the mean of three values (sum divided by count) you can use.

    Code :
    glClearColor(0.0,0.0,0.0,0.0);
    glClear(GL_COLOR_BUFFER_BIT);
    glBlendColor(1.0/count,1.0/count,1.0/count,1.0/count);
    glBlendEquation(GL_CONSTANT_COLOR,GL_ONE);
    glEnable(GL_BLEND);

    N.

  6. #6
    Super Moderator OpenGL Guru
    Join Date
    Feb 2000
    Location
    Montreal, Canada
    Posts
    4,421

    Re: blending

    I'll ask the more obvious question. Why use GL at all?
    You aren't doing graphics. You are doing math and it's something that could be done in a few clock cycles on the CPU.
    ------------------------------
    Sig: http://glhlib.sourceforge.net
    an open source GLU replacement library. Much more modern than GLU.
    float matrix[16], inverse_matrix[16];
    glhLoadIdentityf2(matrix);
    glhTranslatef2(matrix, 0.0, 0.0, 5.0);
    glhRotateAboutXf2(matrix, angleInRadians);
    glhScalef2(matrix, 1.0, 1.0, -1.0);
    glhQuickInvertMatrixf2(matrix, inverse_matrix);
    glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
    glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);

  7. #7
    Advanced Member Frequent Contributor
    Join Date
    Apr 2004
    Posts
    999

    Re: blending

    IIRC he's trying to simulate radiography...

  8. #8
    Intern Contributor
    Join Date
    Dec 2007
    Posts
    62

    Re: blending

    for Nico:
    1- so i don't need to use one_minus_src_alpha?
    2- the program gives me an error.. to many arguments in glBlendequation; i searched and the parameters you wrote aren't accepted by the function, It must be GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT, GL_MIN, GL_MAX, GL_ALPHA_MIN_SGIX, or GL_ALPHA_MAX_SGIX.
    are you sure that the name is correct?

  9. #9
    Super Moderator OpenGL Lord
    Join Date
    Dec 2003
    Location
    Grenoble - France
    Posts
    5,655

    Re: blending

    2- it is glBlendFunc, and you need the GL_ARB_imaging extension use GL_CONSTANT_COLOR

  10. #10
    Intern Contributor
    Join Date
    Dec 2007
    Posts
    62

    Re: blending

    I checked with a program if my pc supports that extension, and the answer is yes. I've changed the code into this:


    Code :
    #include <cstdio>
    #include <cstdlib>
    using namespace std; 
     
    #include <gl\glew.h>
    #include <gl\glut.h>
    #include <gl\gl.h>
    #include <gl\glu.h>
     
    #include <windows.h>
     
    //trasforms alpha from double to char and from 0 and 255 
    char DoubleToChar(double alpha){
    return (char)(alpha*255.0);
    }
     
    int main(int argc, char **argv) {
     
    //Volume values: it represents a 1x1x3 volume ( 3 slices along z)
    unsigned char Volumevalues[12]={1,0,0,1,2,0,0,0,3,0,0,0};
    Volumevalues [3]=DoubleToChar(1.0);
    Volumevalues [7]=DoubleToChar(1.0/2.0);
    Volumevalues [11]=DoubleToChar(1.0/3.0);
    unsigned char result [12]; //array for the result
     
    //initialize glut
    glutInit (&amp;argc, argv);
    glutCreateWindow("radiographic simulation"); 
    glewInit();
     
    // create the texture
    GLuint tex;
    glGenTextures (1, &amp;tex);
    glBindTexture(GL_TEXTURE_3D,tex); 
     
    // sets texture’s parameters 
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
     
    //allocate the texture
    glTexImage3D(GL_TEXTURE_3D,0,GL_RGBA,1,1,4,0,GL_RGBA,GL_UNSIGNED_BYTE, Volumevalues); 
     
    //viewport transform for 1:1 pixel=texel=data mapping
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0,1,0.0,1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glViewport(0,0,1,1);
     
     
    glClearColor(0.0,0.0,0.0,0.0);
    glClear(GL_COLOR_BUFFER_BIT);
    glBlendColor(1.0/3,1.0/3,1.0/3,1.0/3);
    glBlendEquation(GL_CONSTANT_COLOR);
    glEnable(GL_BLEND);
     
    glPushMatrix();
     
    glEnable(GL_TEXTURE_3D);
     
     
    float a= ((float)0.5)/3.0;
    float b =((float)1.5)/3.0;
    float c= ((float)2.5)/3.0;
     
    glBegin(GL_QUADS);
    glTexCoord3f(0.0,0.0,a); glVertex2f(0,0);
    glTexCoord3f(0.0,1.0,a); glVertex2f(0,1);
    glTexCoord3f(1.0,1.0,a); glVertex2f(1,1);
    glTexCoord3f(1.0,0.0,a); glVertex2f(1,0);
     
    glTexCoord3f(0.0,0.0,b); glVertex2f(0,0);
    glTexCoord3f(0.0,1.0,b); glVertex2f(0,1);
    glTexCoord3f(1.0,1.0,b); glVertex2f(1,1);
    glTexCoord3f(1.0,0.0,b); glVertex2f(1,0);
     
    glTexCoord3f(0.0,0.0,c); glVertex2f(0,0);
    glTexCoord3f(0.0,1.0,c); glVertex2f(0,1);
    glTexCoord3f(1.0,1.0,c); glVertex2f(1,1);
    glTexCoord3f(1.0,0.0,c); glVertex2f(1,0);
     
    glEnd(); 
    glPopMatrix();
     
     
    //reads datas from the frame buffer and write them into the array result
    glReadBuffer(GL_FRONT);
    glReadPixels(0,0,1,1,GL_RGBA,GL_BYTE,result);
     
    // print out results
    printf("Data before roundtrip:\n");
    for (int i=0; i<16; i++)
    printf("%d\n", Volumevalues [i]);
    printf("Data after roundtrip:\n");
    for (int i=0; i<4; i++)
    printf("%d\n",result[i]);
     
    getchar();
     
     
    return 0;
     
    }

    but the result is always the same.. 1! not 2! where is the error? i have missed something??

Posting Permissions

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