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