ordering of control points in glMap1f(...data)

Member
Posts: 321
Joined: 2004.10
Post: #1
I'm embarresed to ask this question but I've looked at alot
of OpenGL sites from google and they all seem to gloss over this
important detail. The function

glMap1f(.....data);

creates bezier curves, and a bezier curve is composed of 4 points
that I'll call Start, ControlStart, End and ControlEnd, what
order should they be specified the parameter data?

For instance, is it

data = { start, controlStart, end, controlEnd };
or
data = { start, end, controlStart, controlEnd };

thanks, And if worse comes to worse, I'll just try all
permutations Smile
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #2
I'd guess it's { start, controlStart, controlEnd, end } ... but I've never used the function.
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #3

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Member
Posts: 321
Joined: 2004.10
Post: #4
I've read the page and I do see this for GL_VERTEX_4. It's
much better but still seems a little vague. Quote:

Quote:Each control point is four floating-point values representing
$x$, $y$, $z$, and $w$

Can't find where x, y, z and w are defined?

I assume $x$ and $y$ are start and end. Now is $z$ the control point associated with x or y? Same for "w". It's probably x, y, cx, cy.

At least this can now be narrowed down to just two possible cases.

Thanks.
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #5
I got to wondering what map actually does so I ended up with this glut program. Only lets me click to add 9 times though.

Code:
// gcc map.c -framework GLUT -framework Cocoa -framework OpenGL -o map

#include <stdio.h>

#include <GLUT/glut.h>

#include <OpenGL/gl.h>
#include <OpenGL/glu.h>

int inited;

int points;

#define MAP_MAX 512*3
GLfloat map[MAP_MAX];

void initialize();
void draw();
void cliq(int button, int state, int x, int y);

int main(int argc, char **argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
    glutInitWindowSize(640, 480);
    glutCreateWindow("Splanes");
    glutDisplayFunc(draw);
    glutMouseFunc(cliq);
    
    inited = 0;
    
    glutMainLoop();
    
    return 0;
}

void cliq(int button, int state, int x, int y) {
    if((button == 0) && (state == 0)) {
        map[3*points+0] = x;
        map[3*points+1] = y;
        map[3*points+2] = 0;
        
        points++;
        
        glutPostRedisplay();
    }
}

void initialize()
{
    glClearColor(1, 1, 1, 1);
    
    glViewport(0,0,640,480);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    
    glOrtho(0.0f, 640, 480, 0.0f, -1.0f, 1.0f);
    
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    
    inited = 1;
    
    points = 1;
    map[3*0+0] = 320;
    map[3*0+1] = 240;
    map[3*0+2] = 0;
}

void draw()
{
    if(!inited)
        initialize();
    
    glClear(GL_COLOR_BUFFER_BIT);
    
    glLoadIdentity();
    
    glColor3f(1, 0, 0);
    
    glBegin(GL_LINE_STRIP);
    int t;
    for ( t = 0; t < points; t++ )
        glVertex2f(map[3*t+0], map[3*t+1]);
    glEnd();
    
    
    glColor3f(0, 0, 0);
    
    glMap1f(GL_MAP1_VERTEX_3,0.0f,1000.0f,3,points,map);
    glEnable(GL_MAP1_VERTEX_3);
    glEvalMesh1(GL_LINE, 0, 1000);
    glutSwapBuffers();
}

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Member
Posts: 321
Joined: 2004.10
Post: #6
Quote:glMap1f(GL_MAP1_VERTEX_3,0.0f,1000.0f,3,points,map);
glEnable(GL_MAP1_VERTEX_3);
glBegin(GL_LINE_STRIP);
int t;
for ( t = 0; t < 1000; t++ )
glEvalCoord1f((GLfloat) t);


Don't know if this will help, but all of the examples I've seen up to now has always
had glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, map); and map has always been an array of 4 points. I'd check this on my Mac, but I'm at work and there's only PCs here.
I plan on experimenting - if you don't mind - on your code as soon as I get home.

If I interpret your code correctly and the functions, It might be you are trying to create an entire "path" via the glMap1f() and glEvalCoord1f() functions; I think these commands are only meant for creating a specific curve segment? But I could be wrong.

I do like how you incorporated the mouse clicks into your example. Hadn't thought of that Right now, I'm taking Adobe Illustrator drawings, saving them off as SVG files and then writing a parser that displays the drawing - now a Call List object - in my OpenGL game. I've got straight line polygons working, but now I'm tackling curves. Which explains my original post.

Btw, I stumbled across this by accident which I think is pretty sweet. Gotta love Google.
Some obscure university's prof powerpoint lecture had this note:

Quote:glMapGrid1f(n, u1, u2 );
glEvalMesh1(GL_LINE, n1, n2);

is equivalent to

glBegin(GL_LINE_STRIP);
for( k = n1; k<=n2; k++)
glEvalCoord1f(u1+k*(u2-u1)/n));

Can't say I've tried it yet, but it looks a nice shortcut.
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #7
glEvalMesh1 works nicley, added it to my code and also added a line strip of the places you click which shows you whats going on pretty well. I expected there would be a function to draw the whole line strip at one, but the benefit of being able to generate on coord at a time is you could create some complex 3D models from 3 of these for example.

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Member
Posts: 321
Joined: 2004.10
Post: #8
Could you repost your code so I could play around with it?

I'd probably goof up something if I tried to update the code from
your written description Smile
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #9
Oh sorry, I forgot to mention I edited my previous post with the update.

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Member
Posts: 321
Joined: 2004.10
Post: #10
Thanks. That shows alot of forethought.
Quote this message in a reply
Member
Posts: 321
Joined: 2004.10
Post: #11
Quote:I'd guess it's { start, controlStart, controlEnd, end } ... but I've never used the function.

As usual - or is that, always - Mr. OSC is right again. I guess it is so if you string a series of
bezier curves together, subsequent curves can easily use the end point of the previous curve
as its starting point.

Mr. Unknown, thanks again for posting your code. It gave me a tremendous leg up to
understanding bezier paths. This should make my SVG curve parser much easier to
implement.


Code:
// Bezier Curve Demo

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <fstream>

#include <GLUT/glut.h>
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>

GLfloat map[2048];

int screenWidth = 1000;
int screenHeight = 1000;

int points = 0;    // total number of points
int elements = 0;  // total number of array elements  

int t = 1;

void init(void)
{    
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_FLAT);
    glEnable(GL_MAP1_VERTEX_3);
}

void display(void)
{
   glClear(GL_COLOR_BUFFER_BIT);    
   glColor3f(1.0, 1.0, 1.0);    
      
   for(int p = 3; p < elements; p++)  // originally start at 0, but there is problem when p is 2
   {                                  // and causes modulo to
      if ( (p == 11) || ( ((p-2) % 9) == 0 ) )  // if p = 11 or 20, 29, 38 etc.
      {
         if ( p == 11)  // first curve requires first 4 points
         {                           // u1  u2
            glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &map[0]);            
         }
         else           // subsequent curves requires 3 new points
         {              // First point is the last point of the previous curve
            glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &map[p-11]);
         }
        
         glMapGrid1f(30, 0.0, 1.0 );        
         glEvalMesh1(GL_LINE, 0, 30);
        
      }            
   }
      
    // display the points as red dots
    glPointSize(5.0);
    glColor3f(1.0, 0.0, 0.0);
    glBegin(GL_POINTS);
    {
       for (int i = 0; i < elements; i=i+3)
       {
          glVertex3fv(&map[i]);        
       }    
    }
    glEnd();

    // display the straight line segments as green lines if on
    if ( t > 0)
    {
        glColor3f(0.0, 1.0, 0.0);
        glBegin(GL_LINE_STRIP);
        {
            for (int i = 0; i < elements; i=i+3)
            {
                glVertex3fv(&map[i]);        
            }        
        }
        glEnd();
    }

    glFlush();
    
}



void reshape(int w, int h)
{
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-5.0, 5.0, -5.0 * (GLfloat) h / (GLfloat) w,
             5.0 * (GLfloat) h / (GLfloat) w, -5.0, 5.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}



void keyboard(unsigned char key, int x, int y)
{
    switch (key)
    {
    case 27:
       exit(0);
    break;
    case 't':
    {
       t = -t;  // toggle line segments
       glutPostRedisplay();
    }
    break;        
    }
    
}



void click(int button, int state, int x, int y)
{
   float perCentX = (float) x / (float) screenWidth;
   float perCentY = (float) y / (float) screenHeight;
  
   float distanceX = 5.0 - -5.0;  // values from glOrtho()
   float distanceY = 5.0 - -5.0;
      
   // 0.0 or 10.0;  if 0.0% then at -5.0 edge; if 100% the 10 + -5 = 5.0 edge
   float fx = -5.0 + (perCentX * distanceX);
   // 0.0 or 10.0;  if 0.0% then at -5.0 edge; if 100% the 10 + -5 = 5.0 edge
   float fy = -(-5.0 + (perCentY * distanceY));   // Note: Y is inversed

   if( (button == 0) && (state == 0) )
   {
      map[elements] = fx;
      elements++;
      map[elements] = fy;
      elements++;
      map[elements] = 0.0;
      elements++;              
      points++;
   }
   glutPostRedisplay();
}




int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize (screenWidth, screenHeight);
    glutInitWindowPosition (100, 100);
    glutCreateWindow (argv[0]);
    init ();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutKeyboardFunc (keyboard);
    glutMouseFunc(click);

    glutMainLoop();
    return 0;
}
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Two gluProject points? mikey 5 5,098 Jan 5, 2012 01:03 PM
Last Post: mikey
  surface rendering from data points mc1961 6 5,093 Nov 15, 2007 03:37 PM
Last Post: TomorrowPlusX
  Cocoa and OpenGL entry points? napthali 5 4,002 Dec 31, 2003 06:22 PM
Last Post: AnotherJake
  Selecting 3D Points BlueAvian 4 2,887 Oct 7, 2003 10:57 AM
Last Post: Johan
  Round Points on Various Cards MacFiend 2 2,469 May 10, 2003 04:30 AM
Last Post: MacFiend