00001
00011 #include "standard.h"
00012 #include <windows.h>
00013 #include <GL/glu.h>
00014 #include "GLutils.h"
00015 #include <assert.h>
00016
00017
00018
00029 void printBitmapString (const char *str, HDC hdc)
00030 {
00031 GLint listBase = glGenLists(256);
00032 if (listBase == 0) throw RuntimeError("printBitmapString(): Couldn't generate a display list for string display.");
00033
00034 HGDIOBJ font = GetStockObject (SYSTEM_FONT);
00035 if (!font) throw RuntimeError("printBitmapString(): Can't get SYSTEM_FONT!");
00036
00037 HGDIOBJ old_obj = SelectObject (hdc, font);
00038 if (!wglUseFontBitmaps (hdc, 0, 255, listBase))
00039 {
00040 char errorString[512] ;
00041
00042 FormatMessage(
00043 FORMAT_MESSAGE_FROM_SYSTEM,
00044 NULL,
00045 GetLastError(),
00046 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00047 (LPTSTR) &errorString,
00048 512,
00049 NULL);
00050
00051 throw RuntimeError("printBitmapString(): wglUseFontBitmaps failure: %s", errorString);
00052 }
00053
00054 assert(!glGetError());
00055 SelectObject (hdc, old_obj);
00056
00057 if (GL_FALSE == glIsList (listBase))
00058 throw LogicError("printBitmapString(): no display list base for drawing strings.\n");
00059
00060 GLint viewport[4];
00061 glGetIntegerv (GL_VIEWPORT, viewport);
00062 int width = viewport[2];
00063 int height = viewport[3];
00064
00065 GLint matrixMode;
00066 glGetIntegerv(GL_MATRIX_MODE, &matrixMode);
00067 glPushAttrib (GL_ENABLE_BIT);
00068 glDisable (GL_LIGHTING);
00069 glEnable (GL_COLOR_MATERIAL);
00070 glColor3f(1,1,1);
00071 glDisable(GL_DEPTH_TEST);
00072
00073
00074 glMatrixMode (GL_PROJECTION);
00075 glPushMatrix();
00076 glLoadIdentity();
00077 gluOrtho2D (0, width, 0, height);
00078
00079
00080 glMatrixMode (GL_MODELVIEW);
00081 glPushMatrix ();
00082
00083 glLoadIdentity();
00084 glRasterPos2f(10,10);
00085
00086 GLint oldListBase;
00087 glGetIntegerv (GL_LIST_BASE, &oldListBase);
00088
00089 glListBase (listBase);
00090 glCallLists (strlen (str), GL_UNSIGNED_BYTE, str);
00091 glListBase (oldListBase);
00092
00093 glPopMatrix ();
00094
00095 glMatrixMode (GL_PROJECTION);
00096 glPopMatrix();
00097 glPopAttrib();
00098
00099
00100
00101
00102 glFinish();
00103
00104 glDeleteLists(listBase, 256);
00105
00106 glMatrixMode (matrixMode);
00107 }
00108
00109
00110
00111 void
00112 drawCube(GLfloat size, GLenum type)
00113 {
00114 static GLfloat n[6][3] =
00115 {
00116 {-1.0, 0.0, 0.0},
00117 {0.0, 1.0, 0.0},
00118 {1.0, 0.0, 0.0},
00119 {0.0, -1.0, 0.0},
00120 {0.0, 0.0, 1.0},
00121 {0.0, 0.0, -1.0}
00122 };
00123 static GLint faces[6][4] =
00124 {
00125 {0, 1, 2, 3},
00126 {3, 2, 6, 7},
00127 {7, 6, 5, 4},
00128 {4, 5, 1, 0},
00129 {5, 6, 2, 1},
00130 {7, 4, 0, 3}
00131 };
00132 GLfloat v[8][3];
00133 GLint i;
00134
00135 v[0][0] = v[1][0] = v[2][0] = v[3][0] = -size / 2;
00136 v[4][0] = v[5][0] = v[6][0] = v[7][0] = size / 2;
00137 v[0][1] = v[1][1] = v[4][1] = v[5][1] = -size / 2;
00138 v[2][1] = v[3][1] = v[6][1] = v[7][1] = size / 2;
00139 v[0][2] = v[3][2] = v[4][2] = v[7][2] = -size / 2;
00140 v[1][2] = v[2][2] = v[5][2] = v[6][2] = size / 2;
00141
00142 for (i = 5; i >= 0; i--) {
00143 glBegin(type);
00144 glNormal3fv(&n[i][0]);
00145
00146 glVertex3fv(&v[faces[i][0]][0]);
00147 glVertex3fv(&v[faces[i][1]][0]);
00148 glVertex3fv(&v[faces[i][2]][0]);
00149 glVertex3fv(&v[faces[i][3]][0]);
00150 glEnd();
00151 }
00152 }
00153
00154
00156 void ProjectionMatrix::setPerspective (double fovy, double aspect, double zNear, double zFar)
00157 {
00158 double radians = fovy / 2 * M_PI / 180;
00159 double sine = sin(radians);
00160 double deltaZ = zFar - zNear;
00161
00162 if (!deltaZ || !sine || !aspect)
00163 return;
00164
00165 double cotangent = cos(radians) / sine;
00166
00167 Matrix<4, 4, double> m;
00168 m.setToIdentity();
00169 m[0] = cotangent / aspect;
00170 m[5] = cotangent;
00171 m[10] = -(zFar+zNear) / deltaZ;
00172 m[11] = -1;
00173 m[14] = -2 * zNear * zFar / deltaZ;
00174 m[15] = 0;
00175
00176 ((Matrix<4,4,double>*)this)->operator=(*this * m);
00177 }
00178
00179 void ModelviewMatrix::translate (double x, double y, double z)
00180 {
00181 array[12] = x * array[0] + y * array[4] + z * array[8] + array[12];
00182 array[13] = x * array[1] + y * array[5] + z * array[9] + array[13];
00183 array[14] = x * array[2] + y * array[6] + z * array[10] + array[14];
00184 array[15] = x * array[3] + y * array[7] + z * array[11] + array[15];
00185 }
00186
00187
00188 void ModelviewMatrix::lookAt (Vertex3d COP, Vertex3d lookatPoint, ColVector3d upVector)
00189 {
00190 ColVector3d forward = lookatPoint - COP;
00191 forward.normalize();
00192
00193 ColVector3d side = forward.crossProduct (upVector);
00194 side.normalize();
00195
00196 upVector = side.crossProduct (forward);
00197
00198 ModelviewMatrix modeltmp;
00199 modeltmp.setToIdentity();
00200 modeltmp.elementAt(0,0) = side[0];
00201 modeltmp.elementAt(1,0) = side[1];
00202 modeltmp.elementAt(2,0) = side[2];
00203
00204 modeltmp.elementAt(0,1) = upVector[0];
00205 modeltmp.elementAt(1,1) = upVector[1];
00206 modeltmp.elementAt(2,1) = upVector[2];
00207
00208 modeltmp.elementAt(0,2) = -forward[0];
00209 modeltmp.elementAt(1,2) = -forward[1];
00210 modeltmp.elementAt(2,2) = -forward[2];
00211
00212 ((Matrix<4,4,double>*)this)->operator=(*this * modeltmp);
00213
00214 translate (-COP[0], -COP[1], -COP[2]);
00215 }
00216
00217
00228 void ModelviewMatrix::lookAtWithOffset (Vertex3d COP, Vertex3d lookatPoint, ColVector3d upVector, double latitude, double longitude)
00229 {
00230 double phi = -(M_PI*latitude/180. - M_PI/2.);
00231 double theta = M_PI*longitude/180.;
00232
00233 ColVector3d zDirection = lookatPoint - COP;
00234 double radius = zDirection.getLength();
00235 zDirection.normalize();
00236
00237 ColVector3d xDirection = zDirection.crossProduct (upVector);
00238 xDirection.normalize();
00239
00240 ColVector3d yDirection = xDirection.crossProduct (zDirection);
00241 yDirection.normalize();
00242
00243 ColVector3 x = xDirection * radius * sin(theta) * sin(phi);
00244 ColVector3 z = zDirection * -radius * cos(theta) * sin(phi);
00245 ColVector3 y = yDirection * radius * cos(phi);
00246
00247 Vertex newCOP = x + y + z + lookatPoint;
00248
00249 lookAt (newCOP, lookatPoint, upVector);
00250 }