Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

Renderer.cpp

Go to the documentation of this file.
00001 
00007 #include "Renderer.h"
00008 
00009 /********************************************************************
00010  * Constructor
00011  */
00012 Renderer::Renderer() {
00013         lockFlags = 0xFFFFFFFF;
00014 }
00015 
00016 /********************************************************************
00017  * Destructor
00018  */
00019 Renderer::~Renderer() {
00020 }
00021 
00022 /********************************************************************
00023  * Lock
00024  */
00025 void Renderer::lock(const unsigned int flag) {
00026         lockFlags &= ~flag;
00027 }
00028 
00029 /********************************************************************
00030  * Unlock
00031  */
00032 void Renderer::unlock(const unsigned int flag) {
00033         lockFlags |= flag;
00034 }
00035 
00036 /********************************************************************
00037  * Apply
00038  */
00039 void Renderer::apply() {
00040         if (lockFlags & LF_SHADING) changeShader(selectedShader);
00041 
00042         assignNamedTextures();
00043 
00044         for (int tex = 0; tex < maxTextures; tex++) {
00045                 changeTextureUnit(tex);
00046                 changeTexture(selectedTextures[tex]);
00047         }
00048 
00049         changeBlending(selectedBlendSrc, selectedBlendDest, selectedBlendMode);
00050         changeDepthFunc(selectedDepthFunc);
00051         changeMask(selectedMask);
00052 
00053         reset();
00054 }
00055 
00056 /********************************************************************
00057  * Reset to defaults
00058  */
00059 void Renderer::resetToDefaults() {
00060         for (int tex = 0; tex < maxTextures; tex++) {
00061                 currentTextures[tex] = TEXTURE_NONE;
00062         }
00063 
00064         currentTextureUnit      = 0;
00065 
00066         currentBlendSrc         = BLENDING_NONE;
00067         currentBlendDest        = BLENDING_NONE;
00068         currentBlendMode        = BLENDMODE_ADD;
00069         currentDepthFunc        = LEQUAL;
00070         currentMask                     = ALL;
00071 
00072         currentShader           = SHADER_NONE;
00073 
00074         reset();
00075 }
00076 
00077 /********************************************************************
00078  * Reset
00079  */
00080 void Renderer::reset() {
00081         for (int tex = 0; tex < maxTextures; tex++) {
00082                 selectedTextures[tex] = TEXTURE_NONE;
00083         }
00084 
00085         nNamedTextures          = 0;
00086 
00087         selectedBlendSrc        = BLENDING_NONE;
00088         selectedBlendDest       = BLENDING_NONE;
00089         selectedBlendMode       = BLENDMODE_ADD;
00090         selectedDepthFunc       = LEQUAL;
00091         selectedMask            = ALL;
00092 
00093         selectedShader          = SHADER_NONE;
00094 }
00095 
00096 /********************************************************************
00097  * Add texture (file)
00098  */
00099 TextureID Renderer::addTexture(const char *filename, unsigned int flags) {
00100         Image *image = new Image();
00101 
00102         if (image->loadImage(filename)) {
00103                 return addTexture(image, flags);
00104         }
00105 
00106         delete image;
00107         return TEXTURE_NONE;
00108 }
00109 
00110 /********************************************************************
00111  * Add texture (image)
00112  */
00113 TextureID Renderer::addTexture(Image *image, unsigned int flags) {
00114         Texture texture;
00115 
00116         if (flags & TEXTURE_NORMALMAP) {
00117                 image->toGrayScale();
00118                 image->toNormalMap(true, (flags & TEXTURE_HEIGHTMAP) != 0);
00119         }
00120 
00121         texture.clampS = ((flags & TEXTURE_CLAMP_S) != 0);
00122         texture.clampT = ((flags & TEXTURE_CLAMP_T) != 0);
00123 
00124         texture.textureKind     = TEXTURE_2D;
00125         texture.height          = image->getHeight();
00126         texture.width           = image->getWidth();
00127         texture.depth           = 1;
00128         texture.images[0]       = image;
00129         texture.format          = image->getFormat();
00130 
00131         if (createTexture(texture))
00132                 return insertTexture(texture);
00133 
00134         delete image;
00135         return TEXTURE_NONE;
00136 }
00137 
00138 /********************************************************************
00139  * Add cubemap (files)
00140  */
00141 TextureID Renderer::addCubemap(const char *fNegX, const char *fPosX, const char *fNegY, const char *fPosY, const char *fNegZ, const char *fPosZ) {
00142         const char *filenames[] = { fPosX, fNegX, fNegY, fPosY, fPosZ, fNegZ };
00143         //const char *filenames[] = { fNegX, fPosX, fNegY, fPosY, fNegZ, fPosZ };
00144         Image *images[6];
00145 
00146         for (int i=0; i<6; i++) {
00147                 images[i] = new Image();
00148 
00149                 if (!images[i]->loadImage(filenames[i])) {
00150                         do {
00151                                 delete images[i];
00152                         } while (i--);
00153 
00154                         LOG_ERROR(("Unable to load cubemap images"));
00155                         return TEXTURE_NONE;
00156                 }
00157         }
00158 
00159         return addCubemap(images);
00160 }
00161 
00162 /********************************************************************
00163  * Add cubemap (images)
00164  */
00165 TextureID Renderer::addCubemap(Image *images[6]) {
00166         Texture texture;
00167 
00168         texture.textureKind     = TEXTURE_CUBEMAP;
00169         texture.width           = images[0]->getWidth();
00170         texture.height          = images[0]->getHeight();
00171         texture.depth           = 1;
00172         texture.format          = images[0]->getFormat();
00173 
00174         memcpy(texture.images, images, 6*sizeof(Image *));
00175 
00176         if (createTexture(texture)) {
00177                 LOG_SUCCESS(("Cubemap created"));
00178                 return insertTexture(texture);
00179         }
00180 
00181         LOG_ERROR(("Unable to create cubemap"));
00182         return TEXTURE_NONE;
00183 }
00184 
00185 /********************************************************************
00186  * Insert texture
00187  */
00188 TextureID Renderer::insertTexture(Texture &texture) {
00189         int len = textures.getCount();
00190         for (unsigned int i = 0; i < len; i++) {
00191                 if (textures[i].textureID == UNDEFINED) {
00192                         textures[i] = texture;
00193                         break;
00194                 }
00195         }
00196 
00197         if (i == len) i = textures.add(texture);
00198 
00199         texture.images[0]->clear();
00200 
00201         return i;
00202 }
00203 
00204 /********************************************************************
00205  * Delete texture
00206  */
00207 void Renderer::deleteTexture(const int i) {
00208         if (textures[i].textureID != UNDEFINED) {
00209                 removeTexture(textures[i]);
00210 
00211                 switch (textures[i].textureKind) {
00212                         case TEXTURE_2D:
00213                                 delete textures[i].images[0];
00214                                 break;
00215                         case TEXTURE_CUBEMAP:
00216                                 for (int n=0; n<6; n++) delete textures[i].images[n];
00217                                 break;
00218                 }
00219 
00220                 textures[i].textureID = UNDEFINED;
00221 
00222                 LOG_SUCCESS(("Texture (%d) removed", i));
00223                 return;
00224         }
00225 
00226         LOG_ERROR(("Unable to unload texture (%d)", i));
00227 }
00228 
00229 /********************************************************************
00230  * Add shader
00231  */
00232 ShaderID Renderer::addShader(const char *fileName, const char *extraDefines) {
00233         FILE *file = fopen(fileName, "rb");
00234         if (file == NULL) {
00235 
00236         }
00237         else {
00238                 fseek(file, 0, SEEK_END);
00239                 int length = ftell(file);
00240                 fseek(file, 0, SEEK_SET);
00241 
00242                 char *shaderText = new char[length+1];
00243                 fread(shaderText, length, 1, file);
00244                 fclose(file);
00245                 shaderText[length] = '\0';
00246 
00247                 char *vertexShader = strstr(shaderText, "[Vertex shader]");
00248                 char *fragmentShader = strstr(shaderText, "[Fragment shader]");
00249 
00250                 if (vertexShader != NULL) {
00251                         *vertexShader = '\0';
00252                         vertexShader += 15;
00253                 }
00254 
00255                 if (fragmentShader != NULL) {
00256                         *fragmentShader = '\0';
00257                         fragmentShader += 17;
00258                 }
00259 
00260                 String vShaderString, fShaderString;
00261                 if (vertexShader != NULL) {
00262                         int n = 0;
00263                         char *str = shaderText;
00264                         while (str < vertexShader) {
00265                                 if (*str == '\n') n++;
00266                                 str++;
00267                         }
00268                         if (extraDefines) vShaderString = extraDefines;
00269                         vShaderString += vertexShader;
00270                 }
00271 
00272                 if (fragmentShader != NULL) {
00273                         int n = 0;
00274                         char *str = shaderText;
00275                         while (str < fragmentShader) {
00276                                 if (*str == '\n') n++;
00277                                 str++;
00278                         }
00279                         if (extraDefines) fShaderString = extraDefines;
00280                         fShaderString += fragmentShader;
00281                 }
00282 
00283                 Shader shader;
00284                 bool res = createShader(shader, (vertexShader ? (const char *)vShaderString : NULL), (fragmentShader ? (const char *)fShaderString : NULL));
00285 
00286                 if (res) {
00287                         LOG_SUCCESS(("Shader << %s >> loaded", fileName));
00288                         return insertShader(shader);
00289                 }
00290         }
00291 
00292         LOG_ERROR(("Could not load shader << %s >>", fileName));
00293         return SHADER_NONE;
00294 }
00295 
00296 /********************************************************************
00297  * Insert shader
00298  */
00299 ShaderID Renderer::insertShader(Shader &shader) {
00300         int i, len = shaders.getCount();
00301         for (i=0; i<len; i++) {
00302                 if (shaders[i].programObj == UNDEFINED) {
00303                         shaders[i] = shader;
00304                         return i;
00305                 }
00306         }
00307 
00308         return shaders.add(shader);
00309 }
00310 
00311 /********************************************************************
00312  * Delete shader
00313  */
00314 void Renderer::deleteShader(const int i) {
00315         if (shaders[i].programObj != UNDEFINED) {
00316                 removeShader(shaders[i]);
00317                 shaders[i].programObj = UNDEFINED;
00318                 LOG_SUCCESS(("Shader (%d) removed", i));
00319         }
00320 }
00321 
00322 /********************************************************************
00323  * Add fragment shader (file)
00324  */
00325 ShaderID Renderer::addFragmentShader(unsigned int type, char *filename) {
00326         FragmentShader fragmentShader;
00327         fragmentShader.type = type;
00328 
00329         createFragmentShader(fragmentShader);
00330 
00331         if (filename != NULL) {
00332                 FILE *file = fopen(filename, "rb");
00333 
00334                 if (file == NULL) return SHADER_NONE;
00335 
00336                 fseek(file, 0, SEEK_END);
00337                 fragmentShader.length = ftell(file);
00338                 fseek(file, 0, SEEK_SET);
00339 
00340                 fragmentShader.program = new char[fragmentShader.length];
00341                 fread(fragmentShader.program, fragmentShader.length, 1, file);
00342                 fclose(file);
00343 
00344                 uploadFragmentShader(fragmentShader);
00345                 delete fragmentShader.program;
00346 
00347                 LOG_SUCCESS(("Fragment shader << %s >> added", filename));
00348         }
00349         else {
00350                 LOG_SUCCESS(("Unable to find fragment shader file << %s >>", filename));
00351         }
00352 
00353         return insertFragmentShader(fragmentShader);
00354 }
00355 
00356 /********************************************************************
00357  * Add fragment shader (shaderID)
00358  */
00359 ShaderID Renderer::addFragmentShader(unsigned int type, unsigned int shaderID) {
00360         FragmentShader fragmentShader;
00361         fragmentShader.type = type;
00362         fragmentShader.shaderID = shaderID;
00363 
00364         return insertFragmentShader(fragmentShader);
00365 }
00366 
00367 /********************************************************************
00368  * Add vertex shader (file)
00369  */
00370 ShaderID Renderer::addVertexShader(char *filename) {
00371         VertexShader vertexShader;
00372 
00373         createVertexShader(vertexShader);
00374 
00375         FILE *file;
00376         if ((file = fopen(filename, "rb")) != NULL) {
00377                 fseek(file, 0, SEEK_END);
00378                 vertexShader.length = ftell(file);
00379                 fseek(file, 0, SEEK_SET);
00380 
00381                 vertexShader.program = new char[vertexShader.length];
00382                 fread(vertexShader.program, vertexShader.length, 1, file);
00383                 fclose(file);
00384 
00385                 uploadVertexShader(vertexShader);
00386                 delete vertexShader.program;
00387                 return insertVertexShader(vertexShader);
00388         }
00389 
00390         return SHADER_NONE;
00391 }
00392 
00393 /********************************************************************
00394  * Insert fragment shader
00395  */
00396 ShaderID Renderer::insertFragmentShader(FragmentShader &fragmentShader) {
00397         int i, len = fragmentShaders.getCount();
00398         for (i = 0; i<len; i++) {
00399                 if (fragmentShaders[i].shaderID == UNDEFINED) {
00400                         fragmentShaders[i] = fragmentShader;
00401                         return i;
00402                 }
00403         }
00404 
00405         return fragmentShaders.add(fragmentShader);
00406 }
00407 
00408 /********************************************************************
00409  * Delete fragment shader
00410  */
00411 void Renderer::deleteFragmentShader(const int index) {
00412         if (fragmentShaders[index].shaderID != UNDEFINED) {
00413                 removeFragmentShader(fragmentShaders[index]);
00414                 fragmentShaders[index].shaderID = UNDEFINED;
00415         }
00416 }
00417 
00418 /********************************************************************
00419  * Insert vertex shader
00420  */
00421 ShaderID Renderer::insertVertexShader(VertexShader &vertexShader) {
00422         int i, len = vertexShaders.getCount();
00423         for (i=0; i<len; i++) {
00424                 if (vertexShaders[i].shaderID == UNDEFINED) {
00425                         vertexShaders[i] = vertexShader;
00426                         return i;
00427                 }
00428         }
00429 
00430         return vertexShaders.add(vertexShader);
00431 }
00432 
00433 /********************************************************************
00434  * Delete vertex shader
00435  */
00436 void Renderer::deleteVertexShader(const int index) {
00437         if (vertexShaders[index].shaderID == UNDEFINED) {
00438                 removeVertexShader(vertexShaders[index]);
00439                 vertexShaders[index].shaderID = UNDEFINED;
00440         }
00441 }

Generated on Sun Jun 5 15:47:05 2005 for Defacto by  doxygen 1.4.3