From 2442c23c78fbe205cbebbe2f26d8a20eecbb1347 Mon Sep 17 00:00:00 2001 From: Wolfgang Draxinger Date: Sun, 12 May 2013 02:05:08 +0200 Subject: commit of new sample 'frustum' --- samples/OpenGL/frustum/frustum.c | 326 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 326 insertions(+) create mode 100644 samples/OpenGL/frustum/frustum.c (limited to 'samples/OpenGL/frustum/frustum.c') diff --git a/samples/OpenGL/frustum/frustum.c b/samples/OpenGL/frustum/frustum.c new file mode 100644 index 0000000..dd9c42c --- /dev/null +++ b/samples/OpenGL/frustum/frustum.c @@ -0,0 +1,326 @@ +#include +#include +#include + +#include + +#include +#include +#include +#include + +/* == basic Q^3 vector math functions == */ + +void crossproduct( + double ax, double ay, double az, + double bx, double by, double bz, + double *rx, double *ry, double *rz ) +{ + *rx = ay*bz - az*by; + *ry = az*bx - ax*bz; + *rz = ax*by - ay*bx; +} + +void crossproduct_v( + double const * const a, + double const * const b, + double * const c ) +{ + crossproduct( + a[0], a[1], a[2], + b[0], b[1], b[2], + c, c+1, c+2 ); +} + +double scalarproduct( + double ax, double ay, double az, + double bx, double by, double bz ) +{ + return ax*bx + ay*by + az*bz; +} + +double scalarproduct_v( + double const * const a, + double const * const b ) +{ + return scalarproduct( + a[0], a[1], a[2], + b[0], b[1], b[2] ); +} + +double length( + double ax, double ay, double az ) +{ + return sqrt( + scalarproduct( + ax, ay, az, + ax, ay, az ) ); +} + +double length_v( double const * const a ) +{ + return sqrt( scalarproduct_v(a, a) ); +} + +double normalize( + double *x, double *y, double *z) +{ + double const k = 1./length(*x, *y, *z); + + *x *= k; + *y *= k; + *z *= k; +} + +double normalize_v( double *a ) +{ + double const k = 1./length_v(a); + a[0] *= k; + a[1] *= k; + a[2] *= k; +} + +/* == annotation drawing functions == */ + +void draw_strokestring(void *font, float const size, char const *string) +{ + glPushMatrix(); + float const scale = size * 0.01; /* GLUT character base size is 100 units */ + glScalef(scale, scale, scale); + + char const *c = string; + for(; c && *c; c++) { + glutStrokeCharacter(font, *c); + } + glPopMatrix(); +} + +void draw_arrow( + float ax, float ay, float az, + float bx, float by, float bz, + float ah, float bh, + char const * const annotation, + float annot_size ) +{ + int i; + + GLdouble mv[16]; + glGetDoublev(GL_MODELVIEW_MATRIX, mv); + + /* We're assuming the modelview RS part is (isotropically scaled) + * orthonormal, so the inverse is the transpose. + * The local view direction vector is the 3rd column of the matrix; + * assuming the view direction to be the normal on the arrows tangent + * space taking the cross product of this with the arrow direction + * yields the binormal to be used as the orthonormal base to the + * arrow direction to be used for drawing the arrowheads */ + + double d[3] = { + bx - ax, + by - ay, + bz - az + }; + normalize_v(d); + + double n[3] = { mv[2], mv[6], mv[10] }; + { + double const s = scalarproduct_v(d,n); + for(int i = 0; i < 3; i++) + n[i] -= d[i]*s; + } + normalize_v(n); + + double b[3]; + crossproduct_v(n, d, b); + + GLfloat const pos[][3] = { + {ax, ay, az}, + {bx, by, bz}, + { ax + (0.866*d[0] + 0.5*b[0])*ah, + ay + (0.866*d[1] + 0.5*b[1])*ah, + az + (0.866*d[2] + 0.5*b[2])*ah }, + { ax + (0.866*d[0] - 0.5*b[0])*ah, + ay + (0.866*d[1] - 0.5*b[1])*ah, + az + (0.866*d[2] - 0.5*b[2])*ah }, + { bx + (-0.866*d[0] + 0.5*b[0])*bh, + by + (-0.866*d[1] + 0.5*b[1])*bh, + bz + (-0.866*d[2] + 0.5*b[2])*bh }, + { bx + (-0.866*d[0] - 0.5*b[0])*bh, + by + (-0.866*d[1] - 0.5*b[1])*bh, + bz + (-0.866*d[2] - 0.5*b[2])*bh } + }; + GLushort const idx[][2] = { + {0, 1}, + {0, 2}, {0, 3}, + {1, 4}, {1, 5} + }; + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, pos); + + glDrawElements(GL_LINES, 2*5, GL_UNSIGNED_SHORT, idx); + glDisableClientState(GL_VERTEX_ARRAY); + + if(annotation) { + float w = 0; + for(char const *c = annotation; *c; c++) + w += glutStrokeWidth(GLUT_STROKE_ROMAN, *c); + w *= annot_size / 100.; + + float tx = (ax + bx - w*d[0])/2.; + float ty = (ay + by - w*d[1])/2.; + float tz = (az + bz - w*d[2])/2.; + + GLdouble r[16] = { + d[0], d[1], d[2], 0, + b[0], b[1], b[2], 0, + n[0], n[1], n[2], 0, + 0, 0, 0, 1 + }; + glPushMatrix(); + glTranslatef(tx, ty, tz); + glMultMatrixd(r); + glTranslatef(0, annot_size*0.1, 0); + draw_strokestring(GLUT_STROKE_ROMAN, annot_size, annotation); + glPopMatrix(); + } +} + +void draw_frustum( + float l, float r, float b, float t, + float n, float f ) +{ + GLfloat const kf = f/n; + GLfloat const pos[][3] = { + {0,0,0}, + {l, b, -n}, + {r, b, -n}, + {r, t, -n}, + {l, t, -n}, + {kf*l, kf*b, -f}, + {kf*r, kf*b, -f}, + {kf*r, kf*t, -f}, + {kf*l, kf*t, -f} + }; + GLushort const idx_tip[][2] = { + {0, 1}, + {0, 2}, + {0, 3}, + {0, 4} + }; + GLushort const idx_vol[][2] = { + {1, 5}, {2, 6}, {3, 7}, {4, 8}, + {1, 2}, {2, 3}, {3, 4}, {4, 1}, + {5, 6}, {6, 7}, {7, 8}, {8, 5} + }; + + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, pos); + + glLineWidth(1); + glLineStipple(2, 0xf3cf); + glEnable(GL_LINE_STIPPLE); + glDrawElements(GL_LINES, 2*4, GL_UNSIGNED_SHORT, idx_tip); + + glLineWidth(2); + glLineStipple(1, 0xffff); + glDisable(GL_LINE_STIPPLE); + glDrawElements(GL_LINES, 2*4*3, GL_UNSIGNED_SHORT, idx_vol); + + glLineWidth(1); + glDisableClientState(GL_VERTEX_ARRAY); +} + +/* == scene drawing code == */ + +void display_observer(void) +{ + static float alpha = 0; + + int const win_width = glutGet(GLUT_WINDOW_WIDTH); + int const win_height = glutGet(GLUT_WINDOW_HEIGHT); + float const win_aspect = (float)win_width / (float)win_height; + + glViewport(0, 0, win_width, win_height); + glClearColor(1., 1., 1., 1.); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); +#ifdef USE_ORTHO + glOrtho(-10*win_aspect, 10*win_aspect, -10, 10, 0, 100); +#else + gluPerspective(35, win_aspect, 1, 50); +#endif + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + if(1) { + glTranslatef(0, 0, -5); + glRotatef(30, 1, 0, 0); + glRotatef(alpha, 0, 1, 0); + glTranslatef(0, 0, 2.5); + } else { + gluLookAt(3, 1, -5, 0, 0, -2.5, 0, 1, 0); + } + + float const l = -0.5, + r = 0.5, + b = -0.5, + t = 0.5, + n = 1, + f = 4; + + glEnable(GL_MULTISAMPLE); + + glColor3f(0.,0.,0.); + draw_frustum(l, r, b, t, n, f); + + glLineWidth(1); + draw_arrow(0, 0, 0, 0, 0, -n, 0.1, 0.1, "near", 0.075); + + draw_arrow(l, 0, -n, 0, 0, -n, 0.1, 0, "left", 0.075); + draw_arrow(0, 0, -n, r, 0, -n, 0, 0.1, "right", 0.075); + draw_arrow(0, b, -n, 0, 0, -n, 0.1, 0, "bottom", 0.075); + draw_arrow(0, 0, -n, 0, t, -n, 0, 0.1, "top", 0.075); + + glutSwapBuffers(); + + alpha = fmodf(alpha + 0.1, 360); + glutPostRedisplay(); +} + +void display_frustum_view(void) +{ + int const win_width = glutGet(GLUT_WINDOW_WIDTH); + int const win_height = glutGet(GLUT_WINDOW_HEIGHT); + float const win_aspect = (float)win_width / (float)win_height; + + glViewport(0, 0, win_width, win_height); + glClearColor(0.3, 0.3, 0.6, 1.); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glutSwapBuffers(); +} + +int main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE | GLUT_MULTISAMPLE); + + glutCreateWindow("Observer"); + glutDisplayFunc(display_observer); + + glutCreateWindow("Frustum View"); + glutDisplayFunc(display_frustum_view); + + glutMainLoop(); + return 0; +} -- cgit v1.2.3 From 023bc0f9a7d34735aefac0d95608a210441147fc Mon Sep 17 00:00:00 2001 From: Wolfgang Draxinger Date: Sun, 12 May 2013 02:14:54 +0200 Subject: frustum view aspect now influences observer frustum drawing --- samples/OpenGL/frustum/frustum.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) (limited to 'samples/OpenGL/frustum/frustum.c') diff --git a/samples/OpenGL/frustum/frustum.c b/samples/OpenGL/frustum/frustum.c index dd9c42c..f74b6a5 100644 --- a/samples/OpenGL/frustum/frustum.c +++ b/samples/OpenGL/frustum/frustum.c @@ -9,6 +9,9 @@ #include #include +int window_view; +int window_observer; + /* == basic Q^3 vector math functions == */ void crossproduct( @@ -240,7 +243,7 @@ void draw_frustum( /* == scene drawing code == */ -void display_observer(void) +void display_observer(float frustum_aspect) { static float alpha = 0; @@ -271,8 +274,8 @@ void display_observer(void) gluLookAt(3, 1, -5, 0, 0, -2.5, 0, 1, 0); } - float const l = -0.5, - r = 0.5, + float const l = -0.5*frustum_aspect, + r = 0.5*frustum_aspect, b = -0.5, t = 0.5, n = 1, @@ -297,10 +300,8 @@ void display_observer(void) glutPostRedisplay(); } -void display_frustum_view(void) +void display_view(int const win_width, int const win_height) { - int const win_width = glutGet(GLUT_WINDOW_WIDTH); - int const win_height = glutGet(GLUT_WINDOW_HEIGHT); float const win_aspect = (float)win_width / (float)win_height; glViewport(0, 0, win_width, win_height); @@ -310,16 +311,28 @@ void display_frustum_view(void) glutSwapBuffers(); } +void display(void) +{ + glutSetWindow(window_view); + int const win_view_width = glutGet(GLUT_WINDOW_WIDTH); + int const win_view_height = glutGet(GLUT_WINDOW_HEIGHT); + float const win_view_aspect = (float)win_view_width / (float)win_view_height; + display_view(win_view_width, win_view_height); + + glutSetWindow(window_observer); + display_observer(win_view_aspect); +} + int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE | GLUT_MULTISAMPLE); - glutCreateWindow("Observer"); - glutDisplayFunc(display_observer); + window_observer = glutCreateWindow("Observer"); + glutDisplayFunc(display); - glutCreateWindow("Frustum View"); - glutDisplayFunc(display_frustum_view); + window_view = glutCreateWindow("Frustum View"); + glutDisplayFunc(display); glutMainLoop(); return 0; -- cgit v1.2.3 From 9cbea9d27344e8bcfc0b6eae193fb1e4fd97c1c5 Mon Sep 17 00:00:00 2001 From: Wolfgang Draxinger Date: Sun, 12 May 2013 03:21:47 +0200 Subject: frustum view aspect now influences observer frustum drawing --- samples/OpenGL/frustum/frustum.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'samples/OpenGL/frustum/frustum.c') diff --git a/samples/OpenGL/frustum/frustum.c b/samples/OpenGL/frustum/frustum.c index f74b6a5..493d2eb 100644 --- a/samples/OpenGL/frustum/frustum.c +++ b/samples/OpenGL/frustum/frustum.c @@ -125,6 +125,9 @@ void draw_arrow( }; normalize_v(d); + double r[3] = { mv[0], mv[4], mv[8] }; + int rev = scalarproduct_v(d, r) < 0.; + double n[3] = { mv[2], mv[6], mv[10] }; { double const s = scalarproduct_v(d,n); @@ -173,9 +176,9 @@ void draw_arrow( w += glutStrokeWidth(GLUT_STROKE_ROMAN, *c); w *= annot_size / 100.; - float tx = (ax + bx - w*d[0])/2.; - float ty = (ay + by - w*d[1])/2.; - float tz = (az + bz - w*d[2])/2.; + float tx = (ax + bx)/2.; + float ty = (ay + by)/2.; + float tz = (az + bz)/2.; GLdouble r[16] = { d[0], d[1], d[2], 0, @@ -186,7 +189,9 @@ void draw_arrow( glPushMatrix(); glTranslatef(tx, ty, tz); glMultMatrixd(r); - glTranslatef(0, annot_size*0.1, 0); + if(rev) + glScalef(-1, -1, 1); + glTranslatef(-w/2., annot_size*0.1, 0); draw_strokestring(GLUT_STROKE_ROMAN, annot_size, annotation); glPopMatrix(); } -- cgit v1.2.3 From 22d663cd3978b420aa90c7216973ecef012b2094 Mon Sep 17 00:00:00 2001 From: Wolfgang Draxinger Date: Mon, 13 May 2013 00:57:42 +0200 Subject: added scene drawing to 'frustum' --- samples/OpenGL/frustum/frustum.c | 138 ++++++++++++++++++++++++++++++--------- 1 file changed, 106 insertions(+), 32 deletions(-) (limited to 'samples/OpenGL/frustum/frustum.c') diff --git a/samples/OpenGL/frustum/frustum.c b/samples/OpenGL/frustum/frustum.c index 493d2eb..35a946d 100644 --- a/samples/OpenGL/frustum/frustum.c +++ b/samples/OpenGL/frustum/frustum.c @@ -14,7 +14,7 @@ int window_observer; /* == basic Q^3 vector math functions == */ -void crossproduct( +static void crossproduct( double ax, double ay, double az, double bx, double by, double bz, double *rx, double *ry, double *rz ) @@ -24,7 +24,7 @@ void crossproduct( *rz = ax*by - ay*bx; } -void crossproduct_v( +static void crossproduct_v( double const * const a, double const * const b, double * const c ) @@ -35,14 +35,14 @@ void crossproduct_v( c, c+1, c+2 ); } -double scalarproduct( +static double scalarproduct( double ax, double ay, double az, double bx, double by, double bz ) { return ax*bx + ay*by + az*bz; } -double scalarproduct_v( +static double scalarproduct_v( double const * const a, double const * const b ) { @@ -51,7 +51,7 @@ double scalarproduct_v( b[0], b[1], b[2] ); } -double length( +static double length( double ax, double ay, double az ) { return sqrt( @@ -60,12 +60,12 @@ double length( ax, ay, az ) ); } -double length_v( double const * const a ) +static double length_v( double const * const a ) { return sqrt( scalarproduct_v(a, a) ); } -double normalize( +static double normalize( double *x, double *y, double *z) { double const k = 1./length(*x, *y, *z); @@ -75,7 +75,7 @@ double normalize( *z *= k; } -double normalize_v( double *a ) +static double normalize_v( double *a ) { double const k = 1./length_v(a); a[0] *= k; @@ -241,17 +241,80 @@ void draw_frustum( glLineStipple(1, 0xffff); glDisable(GL_LINE_STIPPLE); glDrawElements(GL_LINES, 2*4*3, GL_UNSIGNED_SHORT, idx_vol); + glDisableClientState(GL_VERTEX_ARRAY); glLineWidth(1); - glDisableClientState(GL_VERTEX_ARRAY); + draw_arrow(0, 0, 0, 0, 0, -n, 0.1, 0.1, "near=1.0", 0.075); + draw_arrow(l, 0, -n, 0, 0, -n, 0.1, 0, "left", 0.075); + draw_arrow(0, 0, -n, r, 0, -n, 0, 0.1, "right", 0.075); + draw_arrow(0, b, -n, 0, 0, -n, 0.1, 0, "bottom", 0.075); + draw_arrow(0, 0, -n, 0, t, -n, 0, 0.1, "top", 0.075); +} + +static void draw_grid1d( + float ax, float ay, float az, /* grid advance */ + float dx, float dy, float dz, /* grid direction */ + float l0, float l1, /* grid line range */ + int major, int begin, int end,/* major line modulus; grid begin, end */ + float or, float og, float ob /* origin line color r,g,b */ ) +{ } /* == scene drawing code == */ -void display_observer(float frustum_aspect) +#define N_LIGHTS 2 +struct { + GLfloat diffuse[3]; + GLfloat position[4]; +} light[N_LIGHTS] = { + { {255./255., 202./255., 99./255.}, {-1, 1, 1, 0} }, + { {30./255, 38./255., 82./255.}, { 0, 1, -0.4, 0} }, +}; + +void draw_scene(void) { - static float alpha = 0; + glPushMatrix(); + glTranslatef(0, 0, -2.5); + + for(int i = 0; i < N_LIGHTS; i++) { + glEnable( GL_LIGHT0 + i); + glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, light[i].diffuse); + glLightfv(GL_LIGHT0 + i, GL_POSITION, light[i].position); + } + + glEnable(GL_LIGHTING); + + glEnable(GL_COLOR_MATERIAL); + glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); + + glPushMatrix(); + glTranslatef(-0.75, 0, -0.5); + glRotatef(45, 0, 1, 0); + + glColor3f(0.9, 0.9, 0.9); + glutSolidTeapot(0.6); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(0.5, 0, 0.5); + glRotatef(45, 0, 1, 0); + + glColor3f(0.9, 0.9, 0.9); + glutSolidCube(0.6); + glPopMatrix(); + glPopMatrix(); +} + +/* == display functions == */ + +struct { + float left, right, bottom, top; + float near, far; +} frustum = {-1, 1, -1, 1, 1, 4}; + +void display_observer(float frustum_aspect) +{ int const win_width = glutGet(GLUT_WINDOW_WIDTH); int const win_height = glutGet(GLUT_WINDOW_HEIGHT); float const win_aspect = (float)win_width / (float)win_height; @@ -265,44 +328,37 @@ void display_observer(float frustum_aspect) #ifdef USE_ORTHO glOrtho(-10*win_aspect, 10*win_aspect, -10, 10, 0, 100); #else - gluPerspective(35, win_aspect, 1, 50); + gluPerspective(60, win_aspect, 1, 50); #endif glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if(1) { glTranslatef(0, 0, -5); - glRotatef(30, 1, 0, 0); - glRotatef(alpha, 0, 1, 0); + glRotatef(15, 1, 0, 0); + glRotatef(-60, 0, 1, 0); glTranslatef(0, 0, 2.5); } else { gluLookAt(3, 1, -5, 0, 0, -2.5, 0, 1, 0); } - float const l = -0.5*frustum_aspect, - r = 0.5*frustum_aspect, - b = -0.5, - t = 0.5, - n = 1, - f = 4; - glEnable(GL_MULTISAMPLE); + glDisable(GL_LIGHTING); + glDepthMask(GL_TRUE); glColor3f(0.,0.,0.); - draw_frustum(l, r, b, t, n, f); - - glLineWidth(1); - draw_arrow(0, 0, 0, 0, 0, -n, 0.1, 0.1, "near", 0.075); + draw_frustum( + frustum.left, + frustum.right, + frustum.bottom, + frustum.top, + frustum.near, + frustum.far ); - draw_arrow(l, 0, -n, 0, 0, -n, 0.1, 0, "left", 0.075); - draw_arrow(0, 0, -n, r, 0, -n, 0, 0.1, "right", 0.075); - draw_arrow(0, b, -n, 0, 0, -n, 0.1, 0, "bottom", 0.075); - draw_arrow(0, 0, -n, 0, t, -n, 0, 0.1, "top", 0.075); + glEnable(GL_DEPTH_TEST); + draw_scene(); glutSwapBuffers(); - - alpha = fmodf(alpha + 0.1, 360); - glutPostRedisplay(); } void display_view(int const win_width, int const win_height) @@ -313,6 +369,24 @@ void display_view(int const win_width, int const win_height) glClearColor(0.3, 0.3, 0.6, 1.); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum( + frustum.left, + frustum.right, + frustum.bottom, + frustum.top, + frustum.near, + frustum.far ); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_MULTISAMPLE); + + draw_scene(); + glutSwapBuffers(); } -- cgit v1.2.3 From 6ae3ddce77ff91c9b66f4f0c993ab85885dd5d14 Mon Sep 17 00:00:00 2001 From: Wolfgang Draxinger Date: Mon, 13 May 2013 20:31:41 +0200 Subject: ... --- samples/OpenGL/frustum/frustum.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) (limited to 'samples/OpenGL/frustum/frustum.c') diff --git a/samples/OpenGL/frustum/frustum.c b/samples/OpenGL/frustum/frustum.c index 35a946d..b6ac75a 100644 --- a/samples/OpenGL/frustum/frustum.c +++ b/samples/OpenGL/frustum/frustum.c @@ -9,6 +9,15 @@ #include #include +#if defined(GLUT_MULTISAMPLE) && defined(GL_MULTISAMPLE) +#define OPTION_GLUT_MULTISAMPLE GLUT_MULTISAMPLE +#define OPTION_MULTISAMPLE 1 +#else +#define OPTION_GLUT_MULTISAMPLE 0 +#define OPTION_MULTISAMPLE 0 +#warning "multisample token(s) not available at compiletime" +#endif + int window_view; int window_observer; @@ -244,11 +253,11 @@ void draw_frustum( glDisableClientState(GL_VERTEX_ARRAY); glLineWidth(1); - draw_arrow(0, 0, 0, 0, 0, -n, 0.1, 0.1, "near=1.0", 0.075); - draw_arrow(l, 0, -n, 0, 0, -n, 0.1, 0, "left", 0.075); - draw_arrow(0, 0, -n, r, 0, -n, 0, 0.1, "right", 0.075); - draw_arrow(0, b, -n, 0, 0, -n, 0.1, 0, "bottom", 0.075); - draw_arrow(0, 0, -n, 0, t, -n, 0, 0.1, "top", 0.075); + draw_arrow(0, 0, 0, 0, 0, -n, 0.1, 0.1, "near", 0.075); + draw_arrow(l, 0, -n, 0, 0, -n, 0.1, 0.0, "left", 0.075); + draw_arrow(0, 0, -n, r, 0, -n, 0.0, 0.1, "right", 0.075); + draw_arrow(0, b, -n, 0, 0, -n, 0.1, 0.0, "bottom", 0.075); + draw_arrow(0, 0, -n, 0, t, -n, 0.0, 0.1, "top", 0.075); } static void draw_grid1d( @@ -342,7 +351,13 @@ void display_observer(float frustum_aspect) gluLookAt(3, 1, -5, 0, 0, -2.5, 0, 1, 0); } +#if OPTION_MULTISAMPLE glEnable(GL_MULTISAMPLE); +#endif + +#ifdef GL_DEPTH_CLAMP + glEnable(GL_DEPTH_CLAMP); +#endif glDisable(GL_LIGHTING); glDepthMask(GL_TRUE); @@ -364,6 +379,7 @@ void display_observer(float frustum_aspect) void display_view(int const win_width, int const win_height) { float const win_aspect = (float)win_width / (float)win_height; + frustum.left = -(frustum.right = win_aspect); glViewport(0, 0, win_width, win_height); glClearColor(0.3, 0.3, 0.6, 1.); @@ -383,7 +399,10 @@ void display_view(int const win_width, int const win_height) glLoadIdentity(); glEnable(GL_DEPTH_TEST); + +#if OPTION_MULTISAMPLE glEnable(GL_MULTISAMPLE); +#endif draw_scene(); @@ -405,7 +424,7 @@ void display(void) int main(int argc, char *argv[]) { glutInit(&argc, argv); - glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE | GLUT_MULTISAMPLE); + glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE | OPTION_GLUT_MULTISAMPLE); window_observer = glutCreateWindow("Observer"); glutDisplayFunc(display); -- cgit v1.2.3 From 12c48a05b2f5c51c61ff744f419bdd85a552612c Mon Sep 17 00:00:00 2001 From: Wolfgang Draxinger Date: Wed, 15 May 2013 09:19:18 +0200 Subject: 'frustum': changed annotation arrow placement, added far annotation arrows, added XY grid --- samples/OpenGL/frustum/frustum.c | 124 ++++++++++++++++++++++++++++++++++----- 1 file changed, 110 insertions(+), 14 deletions(-) (limited to 'samples/OpenGL/frustum/frustum.c') diff --git a/samples/OpenGL/frustum/frustum.c b/samples/OpenGL/frustum/frustum.c index b6ac75a..51efb7e 100644 --- a/samples/OpenGL/frustum/frustum.c +++ b/samples/OpenGL/frustum/frustum.c @@ -2,6 +2,8 @@ #include #include +#include + #include #include @@ -252,21 +254,97 @@ void draw_frustum( glDrawElements(GL_LINES, 2*4*3, GL_UNSIGNED_SHORT, idx_vol); glDisableClientState(GL_VERTEX_ARRAY); - glLineWidth(1); - draw_arrow(0, 0, 0, 0, 0, -n, 0.1, 0.1, "near", 0.075); - draw_arrow(l, 0, -n, 0, 0, -n, 0.1, 0.0, "left", 0.075); - draw_arrow(0, 0, -n, r, 0, -n, 0.0, 0.1, "right", 0.075); - draw_arrow(0, b, -n, 0, 0, -n, 0.1, 0.0, "bottom", 0.075); - draw_arrow(0, 0, -n, 0, t, -n, 0.0, 0.1, "top", 0.075); + glLineWidth(1.5); + + float const text_size = 0.15f; + + draw_arrow(l, 0, 0, 0, 0, 0, 0.1, 0.0, "left", text_size); + draw_arrow(0, 0, 0, r, 0, 0, 0.0, 0.1, "right", text_size); + draw_arrow(0, b, 0, 0, 0, 0, 0.1, 0.0, "bottom", text_size); + draw_arrow(0, 0, 0, 0, t, 0, 0.0, 0.1, "top", text_size); + + draw_arrow(r, 0, 0, r, 0, -n, 0.1, 0.1, "near", text_size); + draw_arrow(l, 0, 0, l, 0, -n, 0.1, 0.1, "near", text_size); + draw_arrow(0, t, 0, 0, t, -n, 0.1, 0.1, "near", text_size); + draw_arrow(0, b, 0, 0, b, -n, 0.1, 0.1, "near", text_size); + + draw_arrow(0, f*t/n, 0, 0, f*t/n, -f, 0.1, 0.1, "far", text_size); + draw_arrow(0, f*b/n, 0, 0, f*b/n, -f, 0.1, 0.1, "far", text_size); + draw_arrow(f*l/n, 0, 0, f*l/n, 0, -f, 0.1, 0.1, "far", text_size); + draw_arrow(f*r/n, 0, 0, f*r/n, 0, -f, 0.1, 0.1, "far", text_size); } static void draw_grid1d( - float ax, float ay, float az, /* grid advance */ - float dx, float dy, float dz, /* grid direction */ - float l0, float l1, /* grid line range */ - int major, int begin, int end,/* major line modulus; grid begin, end */ - float or, float og, float ob /* origin line color r,g,b */ ) + double ax, double ay, double az, /* grid advance */ + double dx, double dy, double dz, /* grid direction */ + float l0, float l1, /* grid line range */ + int major, int begin, int end, /* major line modulus; grid begin, end */ + float or, float og, float ob /* origin line color r,g,b */ ) { + if( begin > end ) { + int t = begin; + begin = end; + end = t; + } + unsigned int const N = end - begin + 1; + + GLfloat *pos = alloca(N*6 * sizeof(*pos)); + GLfloat *col = alloca(N*8 * sizeof(*col)); + + normalize(&dx, &dy, &dz); + + for(int i = begin; i <= end; i++) { + int const j = i - begin; + pos[j*6 + 0] = i*ax + l0*dx; + pos[j*6 + 1] = i*ay + l0*dy; + pos[j*6 + 2] = i*az + l0*dz; + pos[j*6 + 3] = i*ax + l1*dx; + pos[j*6 + 4] = i*ay + l1*dy; + pos[j*6 + 5] = i*az + l1*dz; + + GLfloat r,g,b,a; +#if 1 + if( !i ) { + r = or; + g = og; + b = ob; + a = 1.; + } else if( !(i % major) ) { + r = g = b = 0.3; + a = 0.5; + } else { + r = g = b = 0.5; + a = 0.33; + } +#else + r = 1.; + g = b = 0.; + a = 1.; +#endif + + col[j*8 + 0] = col[j*8 + 4] = r; + col[j*8 + 1] = col[j*8 + 5] = g; + col[j*8 + 2] = col[j*8 + 6] = b; + col[j*8 + 3] = col[j*8 + 7] = a; + } + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + glDisable(GL_LIGHTING); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, pos); + glColorPointer(4, GL_FLOAT, 0, col); + + glLineWidth(1); + glLineStipple(1, 0xffff); + glDisable(GL_LINE_STIPPLE); + + glDrawArrays(GL_LINES, 0, N*2); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); } /* == scene drawing code == */ @@ -329,7 +407,7 @@ void display_observer(float frustum_aspect) float const win_aspect = (float)win_width / (float)win_height; glViewport(0, 0, win_width, win_height); - glClearColor(1., 1., 1., 1.); + glClearColor(1, 1, 1, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); @@ -343,9 +421,9 @@ void display_observer(float frustum_aspect) glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if(1) { - glTranslatef(0, 0, -5); + glTranslatef(0, 0, -10); glRotatef(15, 1, 0, 0); - glRotatef(-60, 0, 1, 0); + glRotatef(-15, 0, 1, 0); glTranslatef(0, 0, 2.5); } else { gluLookAt(3, 1, -5, 0, 0, -2.5, 0, 1, 0); @@ -373,6 +451,24 @@ void display_observer(float frustum_aspect) glEnable(GL_DEPTH_TEST); draw_scene(); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask(GL_FALSE); + draw_grid1d( + 0, 0.1, 0, + 1, 0, 0, + -5, 5, + 10, -50, 50, + 1, 0.3, 0.3 ); + draw_grid1d( + 0.1, 0, 0, + 0, 1, 0, + -5, 5, + 10, -50, 50, + 0.3, 1, 0.3 ); + glDepthMask(GL_TRUE); + glDisable(GL_BLEND); + glutSwapBuffers(); } -- cgit v1.2.3 From 4842cb28522a89c0a6d800139b934001484fadbe Mon Sep 17 00:00:00 2001 From: Wolfgang Draxinger Date: Fri, 26 Jul 2013 11:14:54 +0200 Subject: ... --- samples/OpenGL/frustum/frustum.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'samples/OpenGL/frustum/frustum.c') diff --git a/samples/OpenGL/frustum/frustum.c b/samples/OpenGL/frustum/frustum.c index 51efb7e..c5732c8 100644 --- a/samples/OpenGL/frustum/frustum.c +++ b/samples/OpenGL/frustum/frustum.c @@ -11,6 +11,8 @@ #include #include +#include "linmath.h" + #if defined(GLUT_MULTISAMPLE) && defined(GL_MULTISAMPLE) #define OPTION_GLUT_MULTISAMPLE GLUT_MULTISAMPLE #define OPTION_MULTISAMPLE 1 @@ -208,6 +210,16 @@ void draw_arrow( } } +void draw_arc( + vec3 center, + vec3 a, vec3 b, + float ah, float bh, + char const * const annotation, + float annot_size ) +{ + a[0] = b[2]; +} + void draw_frustum( float l, float r, float b, float t, float n, float f ) -- cgit v1.2.3 From 4542fdb44ae7525b2806233b1d499b1c0202fbf7 Mon Sep 17 00:00:00 2001 From: Wolfgang Draxinger Date: Sat, 26 Apr 2014 18:21:56 +0200 Subject: rotateable observer --- samples/OpenGL/frustum/frustum.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'samples/OpenGL/frustum/frustum.c') diff --git a/samples/OpenGL/frustum/frustum.c b/samples/OpenGL/frustum/frustum.c index c5732c8..2728cee 100644 --- a/samples/OpenGL/frustum/frustum.c +++ b/samples/OpenGL/frustum/frustum.c @@ -412,6 +412,23 @@ struct { float near, far; } frustum = {-1, 1, -1, 1, 1, 4}; +struct { + struct { + float phi, theta; + } rot; +} observer; + +void observer_motion(int x, int y) +{ + int const win_width = glutGet(GLUT_WINDOW_WIDTH); + int const win_height = glutGet(GLUT_WINDOW_HEIGHT); + + observer.rot.phi = -180.f + 360.f * (float)x / (float)win_width; + observer.rot.theta = -90.f + 180.f * (float)y / (float)win_height; + + glutPostRedisplay(); +} + void display_observer(float frustum_aspect) { int const win_width = glutGet(GLUT_WINDOW_WIDTH); @@ -434,8 +451,8 @@ void display_observer(float frustum_aspect) glLoadIdentity(); if(1) { glTranslatef(0, 0, -10); - glRotatef(15, 1, 0, 0); - glRotatef(-15, 0, 1, 0); + glRotatef(observer.rot.theta, 1, 0, 0); + glRotatef(observer.rot.phi, 0, 1, 0); glTranslatef(0, 0, 2.5); } else { gluLookAt(3, 1, -5, 0, 0, -2.5, 0, 1, 0); @@ -536,6 +553,8 @@ int main(int argc, char *argv[]) window_observer = glutCreateWindow("Observer"); glutDisplayFunc(display); + glutMotionFunc(observer_motion); + glutPassiveMotionFunc(observer_motion); window_view = glutCreateWindow("Frustum View"); glutDisplayFunc(display); -- cgit v1.2.3