Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

vertexprog.cpp

Go to the documentation of this file.
00001 // vertexprog.cpp
00002 //
00003 // Copyright (C) 2001 Chris Laurel <claurel@shatters.net>
00004 //
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 
00010 #include <iostream>
00011 #include <fstream>
00012 #include <string>
00013 #include <celutil/util.h>
00014 #include "gl.h"
00015 #include "glext.h"
00016 #include "vertexprog.h"
00017 
00018 using namespace std;
00019 
00020 
00021 unsigned int vp::diffuse = 0;
00022 unsigned int vp::specular = 0;
00023 unsigned int vp::diffuseHaze = 0;
00024 unsigned int vp::diffuseBump = 0;
00025 unsigned int vp::diffuseBumpHaze = 0;
00026 unsigned int vp::shadowTexture = 0;
00027 unsigned int vp::multiShadow = 0;
00028 unsigned int vp::everything = 0;
00029 unsigned int vp::diffuseTexOffset = 0;
00030 unsigned int vp::ringIllum = 0;
00031 unsigned int vp::ringShadow = 0;
00032 unsigned int vp::cometTail = 0;
00033 unsigned int vp::nightLights = 0;
00034 unsigned int vp::glossMap = 0;
00035 unsigned int vp::perFragmentSpecular = 0;
00036 unsigned int vp::perFragmentSpecularAlpha = 0;
00037 unsigned int vp::diffuse_2light = 0;
00038 unsigned int vp::diffuseHaze_2light = 0;
00039 unsigned int vp::diffuseTexOffset_2light = 0;
00040 unsigned int vp::specular_2light = 0;
00041 unsigned int vp::nightLights_2light = 0;
00042 unsigned int vp::ellipticalGalaxy = 0;
00043 
00044 
00045 class VertexProcessorNV : public VertexProcessor
00046 {
00047  public:
00048     VertexProcessorNV();
00049     virtual ~VertexProcessorNV();
00050 
00051     virtual void enable();
00052     virtual void disable();
00053     virtual void use(unsigned int);
00054     virtual void parameter(vp::Parameter, float, float, float, float);
00055     virtual void parameter(vp::Parameter, const float*);
00056 
00057     virtual void enableAttribArray(unsigned int);
00058     virtual void disableAttribArray(unsigned int);
00059     virtual void attribArray(unsigned int index,
00060                              int size,
00061                              GLenum type,
00062                              unsigned int stride,
00063                              const void* pointer);
00064 };
00065 
00066 class VertexProcessorARB : public VertexProcessor
00067 {
00068  public:
00069     VertexProcessorARB();
00070     virtual ~VertexProcessorARB();
00071 
00072     virtual void enable();
00073     virtual void disable();
00074     virtual void use(unsigned int);
00075     virtual void parameter(vp::Parameter, float, float, float, float);
00076     virtual void parameter(vp::Parameter, const float*);
00077 
00078     virtual void enableAttribArray(unsigned int);
00079     virtual void disableAttribArray(unsigned int);
00080     virtual void attribArray(unsigned int index,
00081                              int size,
00082                              GLenum type,
00083                              unsigned int stride,
00084                              const void* pointer);
00085 };
00086 
00087 
00088 
00089 static string* ReadTextFromFile(const string& filename)
00090 {
00091     ifstream textFile(filename.c_str(), ios::in);
00092     if (!textFile.good())
00093         return NULL;
00094 
00095     string* s = new string();
00096 
00097     char c;
00098     while (textFile.get(c))
00099         *s += c;
00100 
00101     return s;
00102 }
00103 
00104 
00105 static bool LoadNvVertexProgram(const string& filename, unsigned int& id)
00106 {
00107     cout << _("Loading NV vertex program: ") << filename << '\n';
00108 
00109     string* source = ReadTextFromFile(filename);
00110     if (source == NULL)
00111     {
00112         cout << _("Error loading NV vertex program: ") << filename << '\n';
00113         return false;
00114     }
00115 
00116     glx::glGenProgramsNV(1, (GLuint*) &id);
00117     glx::glLoadProgramNV(GL_VERTEX_PROGRAM_NV,
00118                          id,
00119                          source->length(),
00120                          reinterpret_cast<const GLubyte*>(source->c_str()));
00121 
00122     delete source;
00123 
00124     GLenum err = glGetError();
00125     if (err != GL_NO_ERROR)
00126     {
00127         GLint errPos = 0;
00128         glGetIntegerv(GL_PROGRAM_ERROR_POSITION_NV, &errPos);
00129         cout << _("Error in vertex program ") << filename <<
00130             " @ " << errPos << '\n';
00131         return false;
00132     }
00133 
00134     return true;
00135 }
00136 
00137 
00138 static int findLineNumber(const string& s, int index)
00139 {
00140     if (index >= (int)s.length())
00141         return -1;
00142 
00143     int lineno = 1;
00144     for (int i = 0; i < index; i++)
00145     {
00146         if (s[i] == '\n')
00147             lineno++;
00148     }
00149 
00150     return lineno;
00151 }
00152 
00153 
00154 static bool LoadARBVertexProgram(const string& filename, unsigned int& id)
00155 {
00156     cout << _("Loading ARB vertex program: ") << filename << '\n';
00157 
00158     string* source = ReadTextFromFile(filename);
00159     if (source == NULL)
00160     {
00161         cout << _("Error loading ARB vertex program: ") << filename << '\n';
00162         return false;
00163     }
00164 
00165     glx::glGenProgramsARB(1, (GLuint*) &id);
00166     if (glGetError() != GL_NO_ERROR)
00167     {
00168         delete source;
00169         return false;
00170     }
00171 
00172     glx::glBindProgramARB(GL_VERTEX_PROGRAM_ARB, id);
00173     glx::glProgramStringARB(GL_VERTEX_PROGRAM_ARB,
00174                             GL_PROGRAM_FORMAT_ASCII_ARB,
00175                             source->length(),
00176                             reinterpret_cast<const GLubyte*>(source->c_str()));
00177 
00178     GLenum err = glGetError();
00179     if (err != GL_NO_ERROR)
00180     {
00181         GLint errPos = 0;
00182         glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos);
00183 
00184         const char* errMsg = (const char*) glGetString(GL_PROGRAM_ERROR_STRING_ARB);
00185         if (errMsg == NULL)
00186             errMsg = "Unknown error";
00187         
00188         cout << _("Error in vertex program ") << filename <<
00189             _(", line ") << findLineNumber(*source, errPos) << ": " << errMsg << '\n';
00190     }
00191 
00192     delete source;
00193 
00194     return err == GL_NO_ERROR;
00195 }
00196 
00197 
00198 // ARB path is preferred; NV vertex program path will eventually go away
00199 VertexProcessor* vp::initNV()
00200 {
00201     cout << _("Initializing NV vertex programs . . .\n");
00202     if (!LoadNvVertexProgram("shaders/diffuse.vp", diffuse))
00203         return NULL;
00204     if (!LoadNvVertexProgram("shaders/specular.vp", specular))
00205         return NULL;
00206     if (!LoadNvVertexProgram("shaders/haze.vp", diffuseHaze))
00207         return NULL;
00208     if (!LoadNvVertexProgram("shaders/bumpdiffuse.vp", diffuseBump))
00209         return NULL;
00210     if (!LoadNvVertexProgram("shaders/bumphaze.vp", diffuseBumpHaze))
00211         return NULL;
00212     if (!LoadNvVertexProgram("shaders/shadowtex.vp", shadowTexture))
00213         return NULL;
00214     if (!LoadNvVertexProgram("shaders/diffuse_texoff.vp", diffuseTexOffset))
00215         return NULL;
00216     if (!LoadNvVertexProgram("shaders/rings.vp", ringIllum))
00217         return NULL;
00218     if (!LoadNvVertexProgram("shaders/ringshadow.vp", ringShadow))
00219         return NULL;
00220     if (!LoadNvVertexProgram("shaders/night.vp", nightLights))
00221         return NULL;
00222     // if (!LoadNvVertexProgram("shaders/comet.vp", cometTail))
00223     //    return false;
00224 
00225     // Two light shaders have only been written for the ARB vertex program path
00226     // Fall back to the the one light versions.
00227     diffuse_2light = diffuse;
00228     diffuseHaze_2light = diffuseHaze;
00229     diffuseTexOffset_2light = diffuseTexOffset;
00230     specular_2light = specular;
00231 
00232     everything = 0;
00233     cout << _("All NV vertex programs loaded successfully.\n");
00234 
00235     glx::glTrackMatrixNV(GL_VERTEX_PROGRAM_NV,
00236                          0, GL_MODELVIEW_PROJECTION_NV, GL_IDENTITY_NV);
00237     glx::glTrackMatrixNV(GL_VERTEX_PROGRAM_NV,
00238                          4, GL_MODELVIEW_PROJECTION_NV, GL_INVERSE_TRANSPOSE_NV);
00239 
00240     return new VertexProcessorNV();
00241 }
00242 
00243 
00244 VertexProcessor* vp::initARB()
00245 {
00246     cout << _("Initializing ARB vertex programs . . .\n");
00247     if (!LoadARBVertexProgram("shaders/diffuse_arb.vp", diffuse))
00248         return NULL;
00249     if (!LoadARBVertexProgram("shaders/specular_arb.vp", specular))
00250         return NULL;
00251     if (!LoadARBVertexProgram("shaders/haze_arb.vp", diffuseHaze))
00252         return NULL;
00253     if (!LoadARBVertexProgram("shaders/bumpdiffuse_arb.vp", diffuseBump))
00254         return NULL;
00255     if (!LoadARBVertexProgram("shaders/bumphaze_arb.vp", diffuseBumpHaze))
00256         return NULL;
00257     if (!LoadARBVertexProgram("shaders/shadowtex_arb.vp", shadowTexture))
00258         return NULL;
00259     if (!LoadARBVertexProgram("shaders/diffuse_texoff_arb.vp", diffuseTexOffset))
00260         return NULL;
00261     if (!LoadARBVertexProgram("shaders/rings_arb.vp", ringIllum))
00262         return NULL;
00263     if (!LoadARBVertexProgram("shaders/ringshadow_arb.vp", ringShadow))
00264         return NULL;
00265     if (!LoadARBVertexProgram("shaders/night_arb.vp", nightLights))
00266         return NULL;
00267     if (!LoadARBVertexProgram("shaders/glossmap_arb.vp", glossMap))
00268         return NULL;
00269     if (!LoadARBVertexProgram("shaders/diffuse2_arb.vp", diffuse_2light))
00270         return NULL;
00271     if (!LoadARBVertexProgram("shaders/haze2_arb.vp", diffuseHaze_2light))
00272         return NULL;
00273     if (!LoadARBVertexProgram("shaders/diffuse_texoff2_arb.vp", diffuseTexOffset_2light))
00274         return NULL;
00275     if (!LoadARBVertexProgram("shaders/specular2_arb.vp", specular_2light))
00276         return NULL;
00277     if (!LoadARBVertexProgram("shaders/night2_arb.vp", nightLights_2light))
00278         return NULL;
00279 
00280     // Load vertex programs that are only required with fragment programs
00281     if (ExtensionSupported("GL_NV_fragment_program") ||
00282         ExtensionSupported("GL_ARB_fragment_program"))
00283     {
00284         if (!LoadARBVertexProgram("shaders/multishadow_arb.vp", multiShadow))
00285             return NULL;
00286         if (!LoadARBVertexProgram("shaders/texphong_arb.vp", perFragmentSpecular))
00287             return NULL;
00288         if (!LoadARBVertexProgram("shaders/texphong_alpha_arb.vp", perFragmentSpecularAlpha))
00289             return NULL;
00290     }
00291 
00292     if (!LoadARBVertexProgram("shaders/ell_galaxy_arb.vp", ellipticalGalaxy))
00293         return NULL;
00294 
00295     cout << _("All ARB vertex programs loaded successfully.\n");
00296 
00297     return new VertexProcessorARB();
00298 }
00299 
00300 
00301 void vp::disable()
00302 {
00303     glDisable(GL_VERTEX_PROGRAM_NV);
00304 }
00305 
00306 
00307 void vp::enable()
00308 {
00309     glEnable(GL_VERTEX_PROGRAM_NV);
00310 }
00311 
00312 
00313 void vp::use(unsigned int prog)
00314 {
00315     glx::glBindProgramNV(GL_VERTEX_PROGRAM_NV, prog);
00316 }
00317 
00318 
00319 void vp::parameter(unsigned int param, const Vec3f& v)
00320 {
00321     glx::glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, param, v.x, v.y, v.z, 0.0f);
00322 }
00323                             
00324 void vp::parameter(unsigned int param, const Point3f& p)
00325 {
00326     glx::glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, param, p.x, p.y, p.z, 0.0f);
00327 }
00328 
00329 void vp::parameter(unsigned int param, const Color& c)
00330 {
00331     glx::glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, param,
00332                                 c.red(), c.green(), c.blue(), c.alpha());
00333 }
00334 
00335 void vp::parameter(unsigned int param, float x, float y, float z, float w)
00336 {
00337     glx::glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, param, x, y, z, w);
00338 }
00339 
00340 
00341 
00342 void arbvp::parameter(unsigned int param, const Vec3f& v)
00343 {
00344     glx::glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, param,
00345                                     v.x, v.y, v.z, 0.0f);
00346 }
00347                             
00348 void arbvp::parameter(unsigned int param, const Point3f& p)
00349 {
00350     glx::glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, param,
00351                                     p.x, p.y, p.z, 0.0f);
00352 }
00353 
00354 void arbvp::parameter(unsigned int param, const Color& c)
00355 {
00356     glx::glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, param,
00357                                    c.red(), c.green(), c.blue(), c.alpha());
00358 }
00359 
00360 void arbvp::parameter(unsigned int param, float x, float y, float z, float w)
00361 {
00362     glx::glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, param, x, y, z, w);
00363 }
00364 
00365 void arbvp::parameter(unsigned int param, const float* fv)
00366 {
00367     glx::glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, param, fv);
00368 }
00369 
00370 
00371 VertexProcessor::VertexProcessor()
00372 {
00373 }
00374 
00375 VertexProcessor::~VertexProcessor()
00376 {
00377 }
00378 
00379 void VertexProcessor::parameter(vp::Parameter param, const Vec3f& v)
00380 {
00381     parameter(param, v.x, v.y, v.z, 0.0f);
00382 }
00383                             
00384 void VertexProcessor::parameter(vp::Parameter param, const Point3f& p)
00385 {
00386     parameter(param, p.x, p.y, p.z, 0.0f);
00387 }
00388 
00389 void VertexProcessor::parameter(vp::Parameter param, const Color& c)
00390 {
00391     parameter(param, c.red(), c.green(), c.blue(), c.alpha());
00392 }
00393 
00394 
00395 
00396 // VertexProcessorNV implementation
00397 
00398 static unsigned int parameterMappings[] = 
00399 {
00400     16, // LightDirection0
00401     15, // EyePosition
00402     20, // DiffuseColor0
00403     34, // SpecularColor0
00404     40, // SpecularExponent
00405     32, // AmbientColor
00406     33, // HazeColor
00407     41, // TextureTranslation
00408     90, // Constant0 - relevant for NV_vertex_program only
00409      0, // Unused
00410     41, // TexGen_S
00411     42, // TexGen_T
00412      0, // TexGen_S2
00413      0, // TexGen_T2
00414      0, // TexGen_S3
00415      0, // TexGen_T3
00416      0, // TexGen_S4
00417      0, // TexGen_T4
00418     50, // LightDirection1
00419     51, // DiffuseColor1,
00420     52, // SpecularColor1
00421 };
00422 
00423 VertexProcessorNV::VertexProcessorNV()
00424 {
00425 }
00426 
00427 VertexProcessorNV::~VertexProcessorNV()
00428 {
00429 }
00430 
00431 void VertexProcessorNV::enable()
00432 {
00433     glEnable(GL_VERTEX_PROGRAM_NV);
00434 }
00435 
00436 void VertexProcessorNV::disable()
00437 {
00438     glDisable(GL_VERTEX_PROGRAM_NV);
00439 }
00440 
00441 void VertexProcessorNV::use(unsigned int prog)
00442 {
00443     glx::glBindProgramNV(GL_VERTEX_PROGRAM_NV, prog);
00444 }
00445 
00446 void VertexProcessorNV::parameter(vp::Parameter param,
00447                                   float x, float y, float z, float w)
00448 {
00449     glx::glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 
00450                                 parameterMappings[param], x, y, z, w);
00451 }
00452 
00453 void VertexProcessorNV::parameter(vp::Parameter param, const float* fv)
00454 {
00455     glx::glProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV,
00456                                  parameterMappings[param], fv);
00457 }
00458 
00459 void VertexProcessorNV::enableAttribArray(unsigned int index)
00460 {
00461     glEnableClientState(GL_VERTEX_ATTRIB_ARRAY0_NV + index);
00462 }
00463 
00464 void VertexProcessorNV::disableAttribArray(unsigned int index)
00465 {
00466     glDisableClientState(GL_VERTEX_ATTRIB_ARRAY0_NV + index);
00467 }
00468 
00469 void VertexProcessorNV::attribArray(unsigned int index,
00470                                      int size,
00471                                      GLenum type,
00472                                      unsigned int stride,
00473                                      const void* ptr)
00474 {
00475     glx::glVertexAttribPointerNV(index, size, type, stride, ptr);
00476 }
00477 
00478 
00479 
00480 // VertexProcessorARB implementation
00481 
00482 VertexProcessorARB::VertexProcessorARB()
00483 {
00484 }
00485 
00486 VertexProcessorARB::~VertexProcessorARB()
00487 {
00488 }
00489 
00490 void VertexProcessorARB::enable()
00491 {
00492     glEnable(GL_VERTEX_PROGRAM_ARB);
00493 }
00494 
00495 void VertexProcessorARB::disable()
00496 {
00497     glDisable(GL_VERTEX_PROGRAM_ARB);
00498 }
00499 
00500 void VertexProcessorARB::use(unsigned int prog)
00501 {
00502     glx::glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog);
00503 }
00504 
00505 void VertexProcessorARB::parameter(vp::Parameter param,
00506                                    float x, float y, float z, float w)
00507 {
00508     glx::glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, param, x, y, z, w);
00509 }
00510 
00511 void VertexProcessorARB::parameter(vp::Parameter param, const float* fv)
00512 {
00513     glx::glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, param, fv);
00514 }
00515 
00516 void VertexProcessorARB::enableAttribArray(unsigned int index)
00517 {
00518     glx::glEnableVertexAttribArrayARB(index);
00519 }
00520 
00521 void VertexProcessorARB::disableAttribArray(unsigned int index)
00522 {
00523     glx::glDisableVertexAttribArrayARB(index);
00524 }
00525 
00526 void VertexProcessorARB::attribArray(unsigned int index,
00527                                      int size,
00528                                      GLenum type,
00529                                      unsigned int stride,
00530                                      const void* ptr)
00531 {
00532     glx::glVertexAttribPointerARB(index, size, type, GL_FALSE, stride, ptr);
00533 }
00534 

Generated on Sat Jan 14 22:30:29 2006 for Celestia by  doxygen 1.4.1