Sepidar's picture

Data Visualization

Hi,

I am writing a visualization program that shows scalar data. Since simple coloring methods were not good for me, with a little googling, I found this article. Article it self suggests these steps:

Quote:

Imagine a set of 50 data values to map colors onto:

  1. Create a 1D 64 entry texture map (you're limited to creating textures whose dimensions are powers-of-2)
  2. Load the first 50 entries of the texture with the color values corresponding to the first 50 data values.
  3. Choose a texture transformation matrix that maps the data values to the S values that index the corresponding texels. This will work if the data values can be mapped with a linear or perspective transformation to the appropriate texture coordinates. If your implementation supports a lookup table associated with texture filtering, such as GL_TEXTURE_COLOR_TABLE_SGI, you can use the glColorTableSGI() command to create an arbitrary non-linear mapping between data value and texture coordinate. If you don't have this support, you can create a lookup table in the application.
  4. If you don't want to interpolate between data values, use GL_NEAREST for GL_TEXTURE_MIN_FILTER, and GL_TEXTURE_MAG_FILTER, and use the same texture coordinates over all the vertices of the primitive you want to color. Remember that OpenGL indexs a texel by truncating the texture coordinate scaled by the texture size. This is written into the specification, so you can always look up the exact texel you want.
  5. If you do want to interpolate colors between data values, use GL_LINEAR for GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER, and choose the correct data values at the sample points, letting texture filtering do the color interpolation for you. Since OpenGL texture mapping is perspective correct, you don't have to worry about perspective projection coloring artifacts.

While I am not so expert in openGL/TK, can any one give me some clues which functions should I use to implement these steps?

Thank you in advance.


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

Unfortunately, this resource is around a decade out of date. The texture matrix trick will work but I don't think modern cards support SGI_texture_color_table anymore.

The article pretty much refers to the following functions (check their documentation tooltips in your IDE). You might also wish to check the texture example in the Example Browser.

GL.GenTexture() // Generate texture
GL.BindTexture() // Bind texture
GL.TexParameter() // Set texture parameters, like min/max filters
GL.TexImage2D() // Upload texture data
GL.MatrixMode() and GL.LoadMatrix() // Specify texture matrix
GL.Sgi.ColorTable(); // Upload color map

Can you give a little more information on what you are trying to achieve? There might be a better way to achieve that.

Sepidar's picture

Thank you for your answer.

Actually I am visualizing some data. These data are at corners of a triangulated domain. To do so, I started by drawing triangles and assigning colors to edges of them, which comes from interpolation of hue based on value of edges. But because OpenGL internally interpolates color in ARGB mode (not hue mode), the result of what I done is noisy as it can be seen in top of attached image. In bottom of the image, there is another visualization of the same data using Tecplot. As it can be seen 1-there is no noise in visualization and 2-the shown data are not continuous.

I persist that noises exist because of interpolation. I tested coloring with two colors (instead of coloring based on hue) and noisy thing went away.

free image hosting

Sepidar's picture

Hi,

Fortunately I found this very food article about contouring in openGL. This is my code in openTK:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using OpenTK.Graphics.OpenGL;
 
namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        bool loaded = false;
        int texture;
 
        void CreateTextureObject()
        {
            byte[,] Texture8 = new byte[,]
            {
                { 000, 000, 255 },   
                { 000, 255, 255 },   
                { 000, 255, 000 },   
                { 255, 255, 000 },   
                { 255, 000, 000 }   
            };
 
            GL.Enable(EnableCap.Texture1D);
 
            // Set pixel storage mode 
            GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
 
            // Generate a texture name
            texture = GL.GenTexture();
 
            // Create a texture object
            GL.BindTexture(TextureTarget.ProxyTexture1D, texture);
            GL.TexParameter(TextureTarget.Texture1D, TextureParameterName.TextureMagFilter, (int)All.Nearest);
            GL.TexParameter(TextureTarget.Texture1D, TextureParameterName.TextureMinFilter, (int)All.Nearest);
            GL.TexImage1D(TextureTarget.Texture1D, 0, PixelInternalFormat.Three, /*with*/5, 0, PixelFormat.Rgb, PixelType.UnsignedByte, Texture8);
        }
 
        public Form1()
        {
            InitializeComponent();
        }
 
        private void glControl1_Load(object sender, EventArgs e)
        {
            loaded = true;
            GL.ClearColor(Color.SkyBlue);
            SetupViewport();
            CreateTextureObject();
        }
 
        private void SetupViewport()
        {
            int w = glControl1.Width;
            int h = glControl1.Height;
            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadIdentity();
            GL.Ortho(0, w, 0, h, -1, 1); // Bottom-left corner pixel has coordinate (0, 0)
            GL.Viewport(0, 0, w, h); // Use all of the glControl painting area
        }
 
        private void glControl1_Paint(object sender, PaintEventArgs e)
        {
            if (!loaded)
                return;
 
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
 
            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadIdentity();
 
            GL.BindTexture(TextureTarget.ProxyTexture1D, texture);
            GL.Begin(BeginMode.Triangles);
            GL.TexCoord1(0.0);
            GL.Vertex2(10, 10);
            GL.TexCoord1(0.5);
            GL.Vertex2(200, 10);
            GL.TexCoord1(1.0);
            GL.Vertex2(10, 200);
            GL.End();
 
            glControl1.SwapBuffers();
        }
    }
}