ax2638

01-08-2016, 08:42 AM

I'm new to opengl and I'm trying to project a polygon into 2d, but I need that the polygon always stay flat to the camera to get

a orthographic projection (something like billboard)

What I did was to calculate the normal vector of the polygon and then set the view from the extreme of the

normal vector to the point of the polygon, so the view is totally flat.

But I cannot get the right 2d coords.

if I move/rotate the viewport, the 2d coord change, and I don't want that.

For me the important are the relation between points of the polygon, because I need this data to triangulate, so the position relative to viewport is not important.

This is the code. The initial routine is: stroke_2d_flat

/* get 2d location */

void get_2d_loc(GLdouble objx, GLdouble objy, GLdouble objz, int r_co[2])

{

GLdouble modelMatrix[16];

GLdouble projMatrix[16];

GLint viewport[4];

glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);

glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);

glGetIntegerv(GL_VIEWPORT, viewport);

GLdouble win_x;

GLdouble win_y;

GLdouble win_z;

int result = gluProject(objx, objy, objz, modelMatrix, projMatrix, viewport,

&win_x, &win_y, &win_z);

r_co[0] = (int)win_x;

// reverse y to adapt from OpenGL to windows

r_co[1] = viewport[1] + viewport[3] - (int)win_y;

}

/* get points always flat to view */

void stroke_2d_flat(bGPDspoint *points, int totpoints, float(*points2d)[2])

{

bGPDspoint *pt;

int i;

GLfloat modelMatrix[4][4];

GLfloat projMatrix[4][4];

GLint viewport[4];

glGetIntegerv(GL_VIEWPORT, viewport);

bGPDspoint dpt0 = points[0];

bGPDspoint dpt1 = points[1];

bGPDspoint dpt2 = points[2];

// Create vectors

GLdouble v1[3] = { dpt1.x - dpt0.x, dpt1.y - dpt0.y, dpt1.z - dpt0.z };

GLdouble v2[3] = { dpt2.x - dpt1.x, dpt2.y - dpt1.y, dpt2.z - dpt1.z };

// Cross product to get normal vector (no need normalize)

GLdouble cx = (v1[1] * v2[2]) - (v1[2] * v2[1]);

GLdouble cy = (v1[2] * v2[0]) - (v1[0] * v2[2]);

GLdouble cz = (v1[0] * v2[1]) - (v1[1] * v2[0]);

// Set camera from normal to vertice (point 2)

glMatrixMode(GL_MODELVIEW);

glPushMatrix();

glLoadIdentity();

gluLookAt(cx + dpt1.x, cy + dpt1.y, cz + dpt1.z, dpt1.x, dpt1.y, dpt1.z, 0, 1, 0);

// Create orthographic projection matrix

glMatrixMode(GL_PROJECTION);

glPushMatrix();

glLoadIdentity();

glOrtho(0, 0, viewport[2], viewport[3], 0.0f, 1.0f);

// Convert all points to 2d

printf("Points:\n");

for (i = 0, pt = points; i < totpoints; i++, pt++)

{

int co[2];

get_2d_loc(pt->x, pt->y, pt->z, co);

printf("%d: 3d: %f, %f, %f \t 2d: %d,%d\n", i, pt->x, pt->y, pt->z, co[0], co[1]);

points2d[i][0] = co[0];

points2d[i][1] = co[1];

}

// Reset

glMatrixMode(GL_PROJECTION);

glPopMatrix();

glMatrixMode(GL_MODELVIEW);

glPopMatrix();

a orthographic projection (something like billboard)

What I did was to calculate the normal vector of the polygon and then set the view from the extreme of the

normal vector to the point of the polygon, so the view is totally flat.

But I cannot get the right 2d coords.

if I move/rotate the viewport, the 2d coord change, and I don't want that.

For me the important are the relation between points of the polygon, because I need this data to triangulate, so the position relative to viewport is not important.

This is the code. The initial routine is: stroke_2d_flat

/* get 2d location */

void get_2d_loc(GLdouble objx, GLdouble objy, GLdouble objz, int r_co[2])

{

GLdouble modelMatrix[16];

GLdouble projMatrix[16];

GLint viewport[4];

glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);

glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);

glGetIntegerv(GL_VIEWPORT, viewport);

GLdouble win_x;

GLdouble win_y;

GLdouble win_z;

int result = gluProject(objx, objy, objz, modelMatrix, projMatrix, viewport,

&win_x, &win_y, &win_z);

r_co[0] = (int)win_x;

// reverse y to adapt from OpenGL to windows

r_co[1] = viewport[1] + viewport[3] - (int)win_y;

}

/* get points always flat to view */

void stroke_2d_flat(bGPDspoint *points, int totpoints, float(*points2d)[2])

{

bGPDspoint *pt;

int i;

GLfloat modelMatrix[4][4];

GLfloat projMatrix[4][4];

GLint viewport[4];

glGetIntegerv(GL_VIEWPORT, viewport);

bGPDspoint dpt0 = points[0];

bGPDspoint dpt1 = points[1];

bGPDspoint dpt2 = points[2];

// Create vectors

GLdouble v1[3] = { dpt1.x - dpt0.x, dpt1.y - dpt0.y, dpt1.z - dpt0.z };

GLdouble v2[3] = { dpt2.x - dpt1.x, dpt2.y - dpt1.y, dpt2.z - dpt1.z };

// Cross product to get normal vector (no need normalize)

GLdouble cx = (v1[1] * v2[2]) - (v1[2] * v2[1]);

GLdouble cy = (v1[2] * v2[0]) - (v1[0] * v2[2]);

GLdouble cz = (v1[0] * v2[1]) - (v1[1] * v2[0]);

// Set camera from normal to vertice (point 2)

glMatrixMode(GL_MODELVIEW);

glPushMatrix();

glLoadIdentity();

gluLookAt(cx + dpt1.x, cy + dpt1.y, cz + dpt1.z, dpt1.x, dpt1.y, dpt1.z, 0, 1, 0);

// Create orthographic projection matrix

glMatrixMode(GL_PROJECTION);

glPushMatrix();

glLoadIdentity();

glOrtho(0, 0, viewport[2], viewport[3], 0.0f, 1.0f);

// Convert all points to 2d

printf("Points:\n");

for (i = 0, pt = points; i < totpoints; i++, pt++)

{

int co[2];

get_2d_loc(pt->x, pt->y, pt->z, co);

printf("%d: 3d: %f, %f, %f \t 2d: %d,%d\n", i, pt->x, pt->y, pt->z, co[0], co[1]);

points2d[i][0] = co[0];

points2d[i][1] = co[1];

}

// Reset

glMatrixMode(GL_PROJECTION);

glPopMatrix();

glMatrixMode(GL_MODELVIEW);

glPopMatrix();