Thread: glDrawArrays()

  1. #1
    Registered User
    Join Date
    Jul 2007
    Location
    Kansas, USA
    Posts
    12

    glDrawArrays()

    Hello, everyone.
    I'm using OpenGL to draw some weather radar data to the screen, and the glDrawArrays() function is producing some strange results. What it is supposed to do is draw triangle strips with x and y as the longitude and latitude of the point and z as proportional to the value returned from the radar. The polygons are then textured to make the color fade from blue to green to yellow to red as the z values get bigger. I'll include some stripped down code:
    Code:
    /* radar.cxx */
    void Radar::Draw()
    {
       glEnableClientState(GL_VERTEX_ARRAY);
       glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    
       glTranslatef(-c_center_point.lon, -c_center_point.lat, -depth);
    
       glVertexPointer(3, GL_FLOAT, 0, m_vertex_array);
       
       glTexParameterf( GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
       glTexParameterf( GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
       glTexParameterf( GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
       glTexImage1D( GL_TEXTURE_1D, 0, 3, m_texture.width(), 0,
             GL_RGBA, GL_UNSIGNED_BYTE, m_texture.bits() );
       glTexCoordPointer(1, GL_FLOAT, 0, m_texture_array);
    
       glDrawArrays(GL_TRIANGLE_STRIP, 0, m_vertex_cnt);
    
       glDisableClientState(GL_TEXTURE_COORD_ARRAY);
       glDisableClientState(GL_VERTEX_ARRAY);
    }
    
    void Radar::CreateVertexArray()
    {
          int width, height, offset;
          int cnt = 0;
          int tex_cnt = 0;
    
          // Pointer to a 2-dimensional array of RadarDataPoint structs,
          // containing a latitude, a longitude, and a value.
          RadarDataPoint ***data_grid;
          double isovalue;
    
          // Fill the grid with data
          m_interface->get_lat_lon_data(data_grid);
    
          // Put data grid dimensions into the variables
          m_interface->get_dimensions(width, height, offset);
    
          if (m_texture_array)
          {
             delete[] m_texture_array;
          }
    
          if (m_vertex_array)
          {
             delete[] m_vertex_array;
          }
    
          m_old_data_height = m_data_height;
          m_data_width = width;
          m_data_height = height;
    
          m_vertex_array = new float[m_data_width * m_data_height * 3];
          m_texture_array = new float[m_data_width * m_data_height * 2];
    
          for(int jdy = 0; jdy < m_data_height; jdy++)
          {
             for(int idx = offset; idx < offset + m_data_width; idx++)
             {
                // Because idx represents the radial of the radar, wrap around to 0
                // if it becomes greater than 359
                int use_idx = (idx>=360 ? idx-360 : idx);
    
                // Filter out any invalid data points
                if ((*data_grid)[use_idx][jdy].lat != 0.0 && 
                    (*data_grid)[use_idx][jdy].lon != 0.0)
                {
                   isovalue = ((*data_grid)[use_idx][jdy].value<-10.0 ? -10.0 :
                      (*data_grid)[use_idx][jdy].value);
                   isovalue /= 15.0;
    
                   m_vertex_array[cnt    ] = (*data_grid)[use_idx][jdy].lon;
                   m_vertex_array[cnt + 1] = (*data_grid)[use_idx][jdy].lat;
                   m_vertex_array[cnt + 2] = isovalue;
    
                   m_texture_array[tex_cnt] = isovalue / 2.0;
    
                   cnt+=3;
                   tex_cnt++;
                }
             }
          }   
          m_vertex_cnt = cnt / 3;
    }
    Those places are more than likely where the problem is. Attached is an image of what results. What it appears to me it's doing is taking a vertex or two and drawing triangles from the zero plane to those points. The normals of the triangles are either pointed toward or away from the radar site.

    Some notes:
    1. The data is valid. I didn't go through all of it because there is a bunch of it, and it would take all day. At first glance, it appears valid.
    2. The texture and vertex arrays are initialized to NULL.

    If you need any background information on weather radar: http://en.wikipedia.org/wiki/NEXRAD

    Thanks in advance for any help.

  2. #2
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    Make sure you're passing glDrawArrays a pointer to the first element of you're vertex array, not a pointer to the array itself.
    ie.
    Code:
    glVertexPointer(3, GL_FLOAT, 0, &m_vertex_array[0]);
    Also, can you verify that the data is actually able to be drawn in a triangle strip?
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  3. #3
    Registered User
    Join Date
    Apr 2006
    Posts
    43
    Is the data really arranged in triangle strip format?

  4. #4
    Registered User
    Join Date
    Jul 2007
    Location
    Kansas, USA
    Posts
    12
    No, it's a 2-dimensional grid, except that the idx and jdy in the grid are drawn as polar coordinates (using the latitude and longitude of the point) on the screen.

  5. #5
    Registered User
    Join Date
    Apr 2006
    Posts
    43
    But you draw it with
    Code:
    glDrawArrays(GL_TRIANGLE_STRIP, 0, m_vertex_cnt);
    I don't see where you setup the points to be in triangle strip order at all before rendering them?

    Take just the first three data values and try to get them to render properly first. Then you can visually confirm that it works as you think it does.

  6. #6
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    No, it's a 2-dimensional grid, except that the idx and jdy in the grid are drawn as polar coordinates (using the latitude and longitude of the point) on the screen.
    Triangle strips and triangle fans use shared vertices. If you're data is such that every triangle has three unique vertices, you're best bet is probably GL_TRIANGLES.

    EDIT: actually, they probably don't need to be "unique" exactly. you can try glDrawElements(), which draws the vertex buffer based on vertex indices.


    Hopefully someone can make sense of what I'm too tired to say properly.
    Last edited by psychopath; 07-18-2007 at 07:45 PM.
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  7. #7
    Registered User
    Join Date
    Apr 2006
    Posts
    43
    Please move this discussion of arrays to the C++ language board instead of hijacking aprescotts thread about rendering.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I agree. For reference, the split discussion is at A pointer to the first element of an array is a pointer to the array itself?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed