00001 /*
00002 File: GLRenderer.cc
00003
00004 Function: OpenGL-based renderer
00005
00006 Author: Andrew Willmott
00007
00008 Notes:
00009 */
00010
00011 #include "gcl/GLRenderer.h"
00012 #ifndef GCL_NO_GL
00013 #include "vl/VLgl.h"
00014
00015
00016 // --- Copying data from & to an image ----------------------------------------
00017
00018
00019 GLRenderer::GLRenderer(Int w, Int h) : Renderer(),
00020 glWidth(w), glHeight(h), oldImage(0)
00021 {
00022 }
00023
00024 Renderer &GLRenderer::GetImage(Image &image)
00025 {
00026 if (image.Tag() == imgRGBATag)
00027 {
00028 image.SetSize(glWidth, glHeight);
00029
00030 SetWindow();
00031 glReadBuffer(GL_FRONT);
00032 glPixelStorei(GL_PACK_ALIGNMENT, 8);
00033
00034 glReadPixels(0, 0, glWidth, glHeight, GL_RGBA, GL_UNSIGNED_BYTE,
00035 ((RGBAImage&) image).RGBAData());
00036 }
00037 else
00038 _Error("(GetImage) non-RGBA images unsupported");
00039
00040 return(SELF);
00041 }
00042
00043 Renderer &GLRenderer::PutImage(const Image &image, Int x, Int y)
00044 {
00045 if (image.Tag() == imgRGBATag)
00046 {
00047 SetWindow();
00048 glDrawBuffer(GL_FRONT);
00049 glRasterPos2i(x, y);
00050 glDrawPixels(image.Width(), image.Height(), GL_RGBA,
00051 GL_UNSIGNED_BYTE, ((RGBAImage&) image).RGBAData());
00052 }
00053 else
00054 _Error("(PutImage) non-RGBA images unsupported");
00055
00056 return(SELF);
00057 }
00058
00059
00060 // --- GLRenderer Drawing Operators -------------------------------------------
00061
00062 // translation from render-style to GL style...
00063 static Int pcTable[8] =
00064 { 0, GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_LINE_LOOP, GL_POLYGON, GL_TRIANGLES, GL_TRIANGLE_STRIP };
00065
00066 Void GLRenderer::Show()
00067 {
00068 SetWindow();
00069 glFlush();
00070 }
00071
00072 Renderer &GLRenderer::SetPoint(const Point &p)
00073 {
00074 glVertex(p);
00075
00076 return(SELF);
00077 }
00078
00079 Renderer &GLRenderer::SetNormal(const Vector &n)
00080 {
00081 glNormal(n);
00082
00083 return(SELF);
00084 }
00085
00086 Renderer &GLRenderer::SetCoord(const Coord &c)
00087 {
00088 glVertex(c);
00089
00090 return(SELF);
00091 }
00092
00093 Renderer &GLRenderer::SetTexCoord(const Coord &c)
00094 {
00095 glTexCoord(c);
00096
00097 return(SELF);
00098 }
00099
00100 Renderer &GLRenderer::SetColour(const Colour &c)
00101 {
00102 glColor(c);
00103
00104 return(SELF);
00105 }
00106
00107 Renderer &GLRenderer::SetColour(const Colour4 &c)
00108 {
00109 glColor(c);
00110
00111 return(SELF);
00112 }
00113
00114 Renderer &GLRenderer::SetTransform(const Transform &t)
00115 {
00116 glMultMatrix(t);
00117
00118 return(SELF);
00119 }
00120
00121 Renderer &GLRenderer::SetCamera(const Camera &c)
00122 {
00123 GLint mm;
00124 Int i;
00125
00126 SetWindow();
00127
00128 glGetIntegerv(GL_MATRIX_MODE, &mm); // save the current matrix mode
00129
00130 glMatrixMode(GL_PROJECTION); // set the projection matrix
00131 glLoadMatrix(c.ProjMatrix());
00132 glMatrixMode(GL_MODELVIEW); // clear the model matrix
00133 glLoadMatrix(c.ModelMatrix());
00134
00135 glMatrixMode((GLenum) mm); // restore matrix mode
00136
00137 return(SELF);
00138 }
00139
00140 Renderer &GLRenderer::SetTexture(const Image *image)
00141 {
00142 SetWindow();
00143
00144 if (image == oldImage) return(SELF);
00145
00146 if (!image)
00147 {
00148 glDisable(GL_TEXTURE_2D);
00149 oldImage = 0;
00150 return(SELF);
00151 }
00152
00153 if (image->Tag() == imgRGBATag)
00154 {
00155 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00156 glTexImage2D(GL_TEXTURE_2D, 0, 3, image->Width(), image->Height(), 0,
00157 GL_RGBA, GL_UNSIGNED_BYTE,
00158 ((RGBAImage*) image)->RGBAData());
00159 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00160 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00161 // glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00162 // glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00163 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00164 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00165 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00166 glEnable(GL_TEXTURE_2D);
00167 oldImage = image;
00168 }
00169 else
00170 _Error("non-rgba images unsupported");
00171
00172 return(SELF);
00173 }
00174
00175 Renderer &GLRenderer::Pop()
00176 {
00177 glPopMatrix();
00178
00179 return(SELF);
00180 }
00181
00182 Renderer &GLRenderer::Push()
00183 {
00184 glPushMatrix();
00185
00186 return(SELF);
00187 }
00188
00189 Renderer &GLRenderer::Clear()
00190 {
00191 SetWindow();
00192 glClearDepth(1);
00193 glClearColor(bgColour[0], bgColour[1], bgColour[2], 1.0);
00194 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
00195
00196 return(SELF);
00197 }
00198
00199 Renderer &GLRenderer::Begin(RenderStyle style)
00200 {
00201 glBegin((GLenum) pcTable[style]);
00202 return(SELF);
00203 }
00204
00205 Renderer &GLRenderer::End()
00206 {
00207 glEnd();
00208 return(SELF);
00209 }
00210
00211 Void GLRenderer::Print(ostream &s)
00212 // Output state of the Renderer. Largely for debugging.
00213 {
00214 Double m[16];
00215 Int i;
00216
00217 SetWindow();
00218
00219 glGetDoublev(GL_PROJECTION_MATRIX, m);
00220
00221 s << "projection transform: " << endl;
00222
00223 for (i = 0; i < 4; i++)
00224 s << "[ " << m[i] << " " << m[i+ 4] << " " << m[i + 8] << " "
00225 << m[i + 12] << " ]" << endl;
00226 s << endl;
00227
00228 glGetDoublev(GL_MODELVIEW_MATRIX, m);
00229
00230 s << "model transform: " << endl;
00231
00232 for (i = 0; i < 4; i++)
00233 s << "[ " << m[i] << " " << m[i+ 4] << " " << m[i + 8] << " "
00234 << m[i + 12] << " ]" << endl;
00235 s << endl;
00236 }
00237
00238 Void GLRenderer::Init()
00239 {
00240 // call from attach() routine...
00241 glMatrixMode(GL_MODELVIEW);
00242 glEnable(GL_DEPTH_TEST);
00243 glCullFace(GL_BACK);
00244 glEnable(GL_CULL_FACE);
00245 glEnable(GL_NORMALIZE);
00246 glEnable(GL_BLEND);
00247 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00248 }
00249
00250 static GLfloat light0Position[] = { 0.0, 0.0, 1.0, 0.0 };
00251 static GLfloat matAmbient[] = { 0.0, 0.0, 0.0, 1.0 };
00252 static GLfloat matDiffuse[] = { 0.7, 0.7, 0.7, 1.0 };
00253 static GLfloat matSpecular[] = { 0.03, 0.03, 0.03, 1.0 };
00254 static GLfloat matShininess[] = { 100.0 };
00255
00256 Void GLRenderer::SetDoubleSided(Bool on)
00257 {
00258 if (!on)
00259 glEnable(GL_CULL_FACE);
00260 else
00261 glDisable(GL_CULL_FACE);
00262 }
00263
00264 Void GLRenderer::SetHeadlight(Bool on)
00265 {
00266 SetWindow();
00267
00268 if (on)
00269 {
00270 glMatrixMode(GL_MODELVIEW);
00271 glPushMatrix();
00272 glLoadIdentity();
00273 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
00274 glEnable(GL_AUTO_NORMAL);
00275 glEnable(GL_LIGHT0);
00276 glEnable(GL_LIGHTING);
00277 glEnable(GL_COLOR_MATERIAL);
00278 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
00279 glLightfv(GL_LIGHT0, GL_POSITION, light0Position);
00280
00281 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, matAmbient);
00282 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiffuse);
00283 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matSpecular);
00284 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, matShininess);
00285 glPopMatrix();
00286 }
00287 else
00288 {
00289 glDisable(GL_LIGHTING);
00290 glDisable(GL_COLOR_MATERIAL);
00291 }
00292 }
00293
00294 #endif
00295