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 2 12 LastLast
Results 1 to 10 of 12

Thread: Rainbow color band and color palettes in OpenGL?

  1. #1
    Intern Contributor
    Join Date
    Jun 2009
    Posts
    85

    Rainbow color band and color palettes in OpenGL?

    Hi

    How to manage different colour palettes in OpenGL? Basically I want to display a set of 2d points and points must be colored based on the depth value at that particular point. The depth value may range from -ve to +ve say -25m to 3000m. So how do I color these set of points using rainbow colorband?

    Thanks

  2. #2
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,098
    A point will display with the currently selected colour. So you have to do the mapping in your code to change the currently selected colour prior to rendering the point.

    Your logic could look like this
    Code :
    void setColour(float p_height)
    {
      if (p_Height < 0) glColor3f(1.0f,0.0f,0.0f);
      else  if (p_Height < 10) glColor3f(0.0f, 1.0f, 0.0f);
      else glColor3f(0.0f,0.0f,1.0f);
    }
     
    // main code
      glBegin(..
      setColour(vertex_1_Depth);
      glVertex2f(vertex_1_X,vertex_1_Y);
      setColour(vertex_2_Depth);
      glVertex2f(vertex_2_X,vertex_2Y);
    ...
      glEnd();

    The number of colours in your range is up to you.

    If you are familar with shaders you could use a 1D texture and look up the colour with a texture lookup. This would be easier then the method above.

  3. #3
    Intern Contributor
    Join Date
    Jun 2009
    Posts
    85
    Hi tonyo_au,

    Exactly that's the word. Lookup table. I don't want to hard code it every time. The logic you mentioned, I did used once, but for testing and it works fine for small number of points. So if number of points are more, then iterating all points and checking for height is time consuming isn't it? Presently I am working with VBOs. Based on the input array, the range must be automatically selected and the color palette should be used, the one which user selects. I googled up in regards to this, and I got this article (though it is quite old)

    http://web.agelid.com/protect/utile/...dex%20Mode.htm

    It suites my requirement. But wondering how to go ahead with this. Any idea or clue?

    As far as shaders are concerned, I tried a small example on shaders. I got the compilation error. vertex and fragment gets loaded but do not gets compiled. Is it that my system doesn't support shading programming. I am working with OpenGL 2.0. I am not sure whats going wrong. Any comments on this?

    Thanks

  4. #4
    Intern Contributor
    Join Date
    Jun 2009
    Posts
    85
    Should I go ahead with color index mode to solve my problem or is there much better way to do it.?

    Thanks

  5. #5
    Senior Member OpenGL Pro
    Join Date
    Jan 2007
    Posts
    1,136
    Color index mode is highly unlikely to be supported well or even hardware accelerated. Could you elaborate some more about what errors you got when you tried shaders? I ask because the classic approach to this would be to encode a palette in a 1D texture and fetch the colour from it in a vertex shader.

  6. #6
    Intern Contributor
    Join Date
    Jun 2009
    Posts
    85
    Hi mhagain,

    The sample shader program which I tested was having some problem. I got another example which displays an ellipse using shaders. IT works fine. Now I am experimenting on shader programming. Can you direct me towards a material, or link or article which helps me to understand how to encode a palette in a 1D texture and fetch color from it?

    Thanks

    Regards

  7. #7
    Intern Contributor
    Join Date
    Jun 2009
    Posts
    85
    Hi,

    How to 1D texture and look up the colour with a texture lookup.??

    Thanks

  8. #8
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,098
    Sorry to take so long to get back, I got a bit distracted with other things.
    Take a look at this on reading textures using shaders
    http://www.opengl.org/sdk/docs/tutor.../texturing.php

  9. #9
    Intern Contributor
    Join Date
    Jun 2009
    Posts
    85
    Hi,

    I went through various links and tried to implement them. The examples mentioned here, also executes well. I went through the teapot example mentioned in The Redbook here on the online version. The redbook example when executed seperately works fine. But instead on teapot if I plot some points, it doesn't produce appropriate result. Though this is very old one and doesn't use shaders. After reading some more literature, I was able to write my own shaders(of course with help of other examples)

    This is my Vertex Shader
    Code :
    attribute vec3 coord2d;attribute float v_color;
    varying vec3 f_color;
    uniform sampler1D texture_id;
     
     
    void main(void) {
    gl_Position = vec4(coord2d.x, coord2d.y, 0.0, 1.0);
    vec4 col = texture1D(texture_id, v_color);
    f_color = vec3(col.x, col.y, col.z);
    }

    And, this is my fragment shader
    Code :
    varying vec3 f_color;
     
    void main(void) {
    gl_FragColor = vec4(f_color.x, f_color.y, f_color.z, 1.0);
    }

    Required VBO variables
    Code :
    GLint attribute_coord2d, attrib_v_color;GLuint vbo_triangle, vbo_triangle_colors, attr_Utexture_id;
     
     
    GLfloat *triangle_vertices = NULL;
     
     
    GLfloat *triangle_colors= NULL;

    Here's the code which executes in Init function
    Code :
        virtual void OnInit()    {
     
     
            FILE *fp = fopen("test.pts", "r");
            if(!fp){
                std::cout << "Unable to open file" << std::endl;
                return;
            }
     
     
            char buffer[256];
            char str[256];
            static const int max = 100;
     
     
            if(!fgets(buffer, sizeof(buffer), fp)) return;
            str[0]='\0';
            sscanf(buffer, "%s", str);
     
     
            // Create system memory buffer    
            sscanf(buffer, "%d", &nPoints);
     
     
            triangle_vertices = new GLfloat[nPoints*3];
            triangle_colors = new GLfloat[nPoints];
     
     
            size_t i_ind = 0, v_ind = 0;
            float _xval, _yval, _zval;
            float min_x, min_y;
            float max_x, max_y;
     
            while(i_ind < nPoints)
            {
                if(!fgets(buffer, sizeof(buffer), fp))
                    break;
     
     
                std::cout << (i_ind/nPoints)*100 << "%\r";
                sscanf(buffer, "%f%f%f", &_xval, &_yval, &_zval);
                if(i_ind == 0)
                {
                    min_x = max_x = _xval;
                    min_y = max_y = _yval;            
                }
                else
                {
                    if (_xval < min_x)
                        min_x = _xval;
                    if (_xval > max_x)
                        max_x = _xval;
                    if (_yval < min_y)
                        min_y = _yval;
                    if (_yval > max_y)                
                        max_y = _yval;
                }
                triangle_vertices[v_ind++] = _xval;
                triangle_vertices[v_ind++] = _yval;
                triangle_vertices[v_ind++] = _zval;
     
     
                triangle_colors[i_ind++] = _zval;
     
     
            }
            fclose(fp);
     
     
     
     
            glClearColor(0.5f, 0.5f, 0.5f, 0.0f);
            glEnable(GL_DEPTH_TEST);
            glShadeModel(GL_FLAT);
     
     
            shader = SM.loadfromFile("vertexshader.txt","fragmentshader.txt"); // load (and compile, link) from file
            if (shader==0) 
                std::cout << "Error Loading, compiling or linking shader\n";
     
     
            const char *uniAttr="texture_id";
            attr_Utexture_id = shader->GetUniformLocation(uniAttr);
            if(attr_Utexture_id == -1)
            {
                std::cout << "Could not bind texture sampler" << std::endl;
                return;
            }
     
     
            /* lookup texture */
            glGenTextures(1, &attr_Utexture_id); /* GL_TEXTURE0 */
            glBindTexture(GL_TEXTURE_1D,attr_Utexture_id);
            glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glEnable(GL_TEXTURE_1D);
            unsigned char colors[3*32];
     
            colors[0] = 255; colors[1] = 0; colors[2] = 0; /* red */
            colors[3] = 0; colors[4] = 0; colors[5] = 255; /* green */
            //colors[6] = 0; colors[7] = 0; colors[8] = 255; /* blue */
     
     
     
            glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 6, 0, GL_RGB, GL_UNSIGNED_BYTE, colors);
     
            glGenBuffers(1, &vbo_triangle);
            glBindBuffer(GL_ARRAY_BUFFER, vbo_triangle);
            glBufferData(GL_ARRAY_BUFFER, nPoints*3*sizeof(GLfloat), triangle_vertices, GL_STATIC_DRAW);
     
     
            glGenBuffers(1, &vbo_triangle_colors);
            glBindBuffer(GL_ARRAY_BUFFER, vbo_triangle_colors);
            glBufferData(GL_ARRAY_BUFFER, nPoints*sizeof(GLfloat), triangle_colors, GL_STATIC_DRAW);
            glBindBuffer(GL_ARRAY_BUFFER, 0);
     
            const char* attribute_name="coord2d";
            attribute_coord2d = shader->GetAttribLocation(attribute_name);
            if(attribute_coord2d == -1){
                std::cout << "Could not bind attribute " << attribute_name << std::endl;
                return;
            }
     
     
            attribute_name="v_color";
            attrib_v_color = shader->GetAttribLocation(attribute_name);
            if(attrib_v_color == -1){
                std::cout << "Could not bind attribute " << attribute_name << std::endl;
                return;
            }
        }


    And display function looks like this
    Code :
    virtual void OnRender(void)    {
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     
          if (shader) shader->begin();
          //glutSolidSphere(1.0,32,32);
     
     
          glActiveTexture(GL_TEXTURE0 );
          glBindTexture(GL_TEXTURE_1D,attr_Utexture_id);
          //glEnable(GL_TEXTURE_2D);
          //glDisable(GL_TEXTURE_1D);
     
          glEnableVertexAttribArray(attribute_coord2d);
          glBindBuffer(GL_ARRAY_BUFFER, vbo_triangle);
          glVertexAttribPointer(
              attribute_coord2d,
              3, GL_FLOAT, GL_FALSE, 0, 0);
     
     
          glEnableVertexAttribArray(attrib_v_color);      
          glBindBuffer(GL_ARRAY_BUFFER, vbo_triangle_colors);
          glVertexAttribPointer(
              attrib_v_color, // attribute
              1, // number of elements per vertex, here (r,g,b)
              GL_FLOAT, // the type of each element
              GL_FALSE, // make our values as-is
              0, // no extra data between each position
              0 // offset of first element
              );
     
     
          glPointSize(8);
          glDrawArrays(GL_POINTS, 0, nPoints);
     
     
          glDisableVertexAttribArray(attrib_v_color);
          glDisableVertexAttribArray(attribute_coord2d);
     
     
     
          if (shader) shader->end();
     
     
          glutSwapBuffers();
     
     
            //Repaint();
        }

    So basically what I am doing here is reading set of xyz points and plotting them. Sample xyz points is shown below

    Code :
    13
    0.1 0.0    8
    0.5 -0.2   25
    -0.2 0.4   3346
    -0.1 0.3   500
    0.4 0.5    3244
    0.8 -0.5   3212
    0.8 -0.9   60
    -0.2 -0.5  3166
    -0.3 0.8   -20
    -0.6 0.4   -500
    0.3 0.8    3173
    -0.8 -0.3  2456     
    0.1 0.7    3214

    Which this set up I do get colored points. But, 4 points are of same color and remaining points are of same color. My question here is,

    1) Is Texture 1D lookup construction what I have done is correct?
    2) If so, then how is the range of colors will be computed? For example, in the above test file, the range is -500 to 3346. This range how should be supplied so that the color map should take place only for values falling within this range.?

    I'm sure that I am missing something somewhere. But where I am not able to locate. Some one please help me out.

    Thanks

    Regards
    Rakesh Patil
    Last edited by rakeshthp; 10-18-2012 at 05:39 AM. Reason: Typing mistake

  10. #10
    Intern Contributor
    Join Date
    Jun 2009
    Posts
    85
    Can someone suggest something on this?

    Thanks

Posting Permissions

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