TAPs 0.7.7.3
TAPsShaderFns.hpp
Go to the documentation of this file.
00001 // Modified from
00002 /* ===========================================================================
00003 Copyright (C) 2002-2004  3Dlabs Inc. Ltd.
00004 All rights reserved.
00005 
00006 Redistribution and use in source and binary forms, with or without
00007 modification, are permitted provided that the following conditions
00008 are met:
00009 
00010     Redistributions of source code must retain the above copyright
00011     notice, this list of conditions and the following disclaimer.
00012 
00013     Redistributions in binary form must reproduce the above
00014     copyright notice, this list of conditions and the following
00015     disclaimer in the documentation and/or other materials provided
00016     with the distribution.
00017 
00018     Neither the name of 3Dlabs Inc. Ltd. nor the names of its
00019     contributors may be used to endorse or promote products derived
00020     from this software without specific prior written permission.
00021 
00022 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00026 COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00028 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00032 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033 POSSIBILITY OF SUCH DAMAGE.
00034 =========================================================================== */
00035 // By Sukitti Punak (03/28/2005)
00036 // Update (09/10/2010)
00037 
00038 #ifndef TAPs_SHADER_FNS_HPP
00039 #define TAPs_SHADER_FNS_HPP
00040 
00041 #include <stdlib.h>
00042 #include <stdio.h>
00043 #include <string.h>
00044 #include <fcntl.h>
00045 
00046 #ifdef WIN32 /*[*/
00047 #include <io.h>
00048 #endif /*]*/
00049 
00050 #include <iostream>
00051 #include <cmath>
00052 
00053 #define GLEW_STATIC 1
00054 #include <GL/glew.h>
00055 #include <GL/wglew.h>
00056 
00057 #include "../Core/TAPsLib.hpp"
00058 //#include "../../OpenGLModel/TAPsOpenGLPNTriangleVolPresModel.hpp"
00059 
00060 //-----------------------------------------------------------------------------
00061 #ifndef TAPs_USE_GLSL
00062     #define TAPs_USE_GLSL
00063 #endif
00064 
00065 BEGIN_NAMESPACE_TAPs__OpenGL
00066 //=============================================================================
00067 // Shader types
00068 //-----------------------------------------------------------------------------
00069 typedef enum {
00070     EVertexShader,
00071     EFragmentShader
00072 } EShaderType;
00073 
00074 //=============================================================================
00075 // Fn Declarations
00076 //-----------------------------------------------------------------------------
00077 //int ReadShaderSource(char *fileName, GLcharARB **vertexShader, GLcharARB **fragmentShader);
00078 //int InstallBrickShaders(const GLcharARB *PNTriVertex, const GLcharARB *PNTriFragment, GLhandleARB &PNTriProg);
00079 int PrintOglError(char *file, int line);
00080 
00081 #define PrintOpenGLError() PrintOglError(__FILE__, __LINE__)
00082 
00083 //=============================================================================
00084 // Global handles for the currently active program object, 
00085 // with its two shader objects
00086 //-----------------------------------------------------------------------------
00087 bool gbUseGPU = true;
00088 int gbSmoothness = 10;
00089 GLhandleARB ProgramObject        = 0;
00090 GLhandleARB VertexShaderObject   = 0;
00091 GLhandleARB FragmentShaderObject = 0;
00092 
00093 //=============================================================================
00094 // Get the location of a uniform variable
00095 //-----------------------------------------------------------------------------
00096 static GLint GetUniLoc(GLhandleARB program, const GLcharARB *name)
00097 {
00098     GLint loc;
00099 
00100     loc = glGetUniformLocationARB(program, name);
00101 
00102     if (loc == -1)
00103         printf("No such uniform named \"%s\"\n", name);
00104 
00105     PrintOpenGLError();  // Check for OpenGL errors
00106     return loc;
00107 }
00108 
00109 //=============================================================================
00110 // Get the location of a uniform variable
00111 //-----------------------------------------------------------------------------
00112 // location variable is for debugging
00113 static GLint GetUniLoc(GLhandleARB program, const GLcharARB *name, int location)
00114 {
00115     GLint loc;
00116 
00117     loc = glGetUniformLocationARB(program, name);
00118 
00119     if (loc == -1)
00120         printf("No such uniform named \"%s\"\n", name);
00121 
00122     if (location != 0) {
00123         std::cout << "Loc: " << location << "\n";
00124     }
00125     PrintOpenGLError();  // Check for OpenGL errors
00126     return loc;
00127 }
00128 
00129 //=============================================================================
00130 // Print out the information log for a shader object or a program object
00131 //-----------------------------------------------------------------------------
00132 static void PrintInfoLog(GLhandleARB obj)
00133 {
00134     int infologLength = 0;
00135     int charsWritten  = 0;
00136     GLcharARB *infoLog;
00137 
00138     PrintOpenGLError();  // Check for OpenGL errors
00139 
00140     glGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB,
00141                                          &infologLength);
00142     PrintOpenGLError();  // Check for OpenGL errors
00143 
00144     if (infologLength > 0)
00145     {
00146         infoLog = (GLcharARB*)malloc(infologLength);
00147         if (infoLog == NULL)
00148         {
00149             printf("ERROR: Could not allocate InfoLog buffer\n");
00150             exit(1);
00151         }
00152         glGetInfoLogARB(obj, infologLength, &charsWritten, infoLog);
00153         printf("InfoLog:\n%s\n\n", infoLog);
00154         free(infoLog);
00155     }
00156     PrintOpenGLError();  // Check for OpenGL errors
00157 }
00158 
00159 //=============================================================================
00160 // Shader Size
00161 //-----------------------------------------------------------------------------
00162 static int ShaderSize(char *fileName, EShaderType shaderType)
00163 {
00164     //
00165     // Returns the size in bytes of the shader fileName.
00166     // If an error occurred, it returns -1.
00167     //
00168     // File name convention:
00169     //
00170     // <fileName>.vert
00171     // <fileName>.frag
00172     //
00173     int fd;
00174     char name[128];
00175     int count = -1;
00176 
00177     strcpy(name, fileName);
00178 
00179     switch (shaderType)
00180     {
00181         case EVertexShader:
00182             strcat(name, ".vert");
00183             break;
00184         case EFragmentShader:
00185             strcat(name, ".frag");
00186             break;
00187         default:
00188             printf("ERROR: unknown shader file type\n");
00189             exit(1);
00190             break;
00191     }
00192 
00193     //
00194     // Open the file, seek to the end to find its length
00195     //
00196 #ifdef WIN32 /*[*/
00197     fd = _open(name, _O_RDONLY);
00198     if (fd != -1)
00199     {
00200         count = _lseek(fd, 0, SEEK_END) + 1;
00201         _close(fd);
00202     }
00203 #else /*][*/
00204     fd = open(name, O_RDONLY);
00205     if (fd != -1)
00206     {
00207         count = lseek(fd, 0, SEEK_END) + 1;
00208         close(fd);
00209     }
00210 #endif /*]*/
00211 
00212     return count;
00213 }
00214 
00215 //=============================================================================
00216 // Read Shader
00217 //-----------------------------------------------------------------------------
00218 static int ReadShader(char *fileName, EShaderType shaderType, char *shaderText, int size)
00219 {
00220     //
00221     // Reads a shader from the supplied file and returns the shader in the
00222     // arrays passed in. Returns 1 if successful, 0 if an error occurred.
00223     // The parameter size is an upper limit of the amount of bytes to read.
00224     // It is ok for it to be too big.
00225     //
00226     FILE *fh;
00227     char name[100];
00228     int count;
00229 
00230     strcpy(name, fileName);
00231 
00232     switch (shaderType) 
00233     {
00234         case EVertexShader:
00235             strcat(name, ".vert");
00236             break;
00237         case EFragmentShader:
00238             strcat(name, ".frag");
00239             break;
00240         default:
00241             printf("ERROR: unknown shader file type\n");
00242             exit(1);
00243             break;
00244     }
00245 
00246     //
00247     // Open the file
00248     //
00249     fh = fopen(name, "r");
00250     if (!fh)
00251         return -1;
00252 
00253     //
00254     // Get the shader from a file.
00255     //
00256     fseek(fh, 0, SEEK_SET);
00257     count = static_cast<int>( fread(shaderText, 1, size, fh) );
00258     shaderText[count] = '\0';
00259 
00260     if (ferror(fh))
00261         count = 0;
00262 
00263     fclose(fh);
00264     return count;
00265 }
00266 
00267 //=============================================================================
00268 // Read Shader Source
00269 //-----------------------------------------------------------------------------
00270 int ReadShaderSource(char *fileName, GLcharARB **vertexShader, GLcharARB **fragmentShader)
00271 {
00272     int vSize, fSize;
00273 
00274     //
00275     // Allocate memory to hold the source of our shaders.
00276     //
00277     vSize = ShaderSize(fileName, EVertexShader);
00278     fSize = ShaderSize(fileName, EFragmentShader);
00279     std::cout << "vSize = " << vSize << std::endl;
00280     std::cout << "fSize = " << fSize << std::endl;
00281     //char c;
00282     //std::cout << "Press any key to continue." << std::endl;
00283     //std::cin >> c;
00284 
00285     if (vSize == -1)
00286     {
00287         printf("Cannot determine size of the shader %s.vert\n", fileName);
00288         exit(1);
00289         return 0;
00290     }
00291     if (fSize == -1)
00292     {
00293         printf("Cannot determine size of the shader %s.frag\n", fileName);
00294         exit(1);
00295         return 0;
00296     }
00297 
00298     *vertexShader = (GLcharARB *) malloc(vSize);
00299     *fragmentShader = (GLcharARB *) malloc(fSize);
00300 
00301     //
00302     // Read the source code
00303     //
00304     if (!ReadShader(fileName, EVertexShader, *vertexShader, vSize))
00305     {
00306         printf("Cannot read the file %s.vert\n", fileName);
00307         return 0;
00308     }
00309 
00310     if (!ReadShader(fileName, EFragmentShader, *fragmentShader, fSize))
00311     {
00312         printf("Cannot read the file %s.frag\n", fileName);
00313         return 0;
00314     }
00315 
00316     return 1;
00317 }
00318 
00319 //=============================================================================
00320 // Install Shaders
00321 //-----------------------------------------------------------------------------
00322 int InstallShaders(
00323     const GLcharARB *PNTriVertex,
00324     const GLcharARB *PNTriFragment,
00325     GLhandleARB &PNTriProg )
00326 {
00327     GLhandleARB PNTriVS, PNTriFS;//, PNTriProg;   // handles to objects
00328     GLint       vertCompiled, fragCompiled;    // status values
00329     GLint       linked;
00330 
00331     // Create a vertex shader object and a fragment shader object
00332 
00333     PNTriVS = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
00334     PNTriFS = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
00335 
00336     // Load source code strings into shaders
00337 
00338     glShaderSourceARB(PNTriVS, 1, &PNTriVertex, NULL);
00339     glShaderSourceARB(PNTriFS, 1, &PNTriFragment, NULL);
00340 
00341     // Compile the PNTri vertex shader, and print out
00342     // the compiler log file.
00343 
00344     glCompileShaderARB(PNTriVS);
00345     PrintOpenGLError();  // Check for OpenGL errors
00346     glGetObjectParameterivARB(PNTriVS,
00347                 GL_OBJECT_COMPILE_STATUS_ARB, &vertCompiled);
00348     PrintInfoLog(PNTriVS);
00349 
00350     // Compile the PNTri vertex shader, and print out
00351     // the compiler log file.
00352 
00353     glCompileShaderARB(PNTriFS);
00354     PrintOpenGLError();  // Check for OpenGL errors
00355     glGetObjectParameterivARB(PNTriFS,
00356                 GL_OBJECT_COMPILE_STATUS_ARB, &fragCompiled);
00357     PrintInfoLog(PNTriFS);
00358 
00359     if (!vertCompiled || !fragCompiled)
00360         return 0;
00361 
00362     // Create a program object and attach the two compiled shaders
00363 
00364     PNTriProg = glCreateProgramObjectARB();
00365     glAttachObjectARB(PNTriProg, PNTriVS);
00366     glAttachObjectARB(PNTriProg, PNTriFS);
00367 
00368     // Link the program object and print out the info log
00369 
00370     glLinkProgramARB(PNTriProg);
00371     PrintOpenGLError();  // Check for OpenGL errors
00372     glGetObjectParameterivARB(PNTriProg,
00373                 GL_OBJECT_LINK_STATUS_ARB, &linked);
00374     PrintInfoLog(PNTriProg);
00375 
00376     if (!linked)
00377         return 0;
00378 
00379     // Install program object as part of current state
00380     glUseProgramObjectARB(PNTriProg);
00381 
00382     // Set up initial uniform values
00383     glUniform3fARB(GetUniLoc(PNTriProg, "BrickColor"), 1.0f, 0.3f, 0.2f);
00384     glUniform3fARB(GetUniLoc(PNTriProg, "MortarColor"), 0.85f, 0.86f, 0.84f);
00385     //glUniform2fARB(GetUniLoc(PNTriProg, "BrickSize"), 0.30f, 0.15f);
00386     glUniform2fARB(GetUniLoc(PNTriProg, "BrickSize"), 1.80f, 0.90f);
00387     glUniform2fARB(GetUniLoc(PNTriProg, "BrickPct"), 0.90f, 0.85f);
00388     glUniform3fARB(GetUniLoc(PNTriProg, "LightPosition"), 0.0f, 2.0f, 4.0f);
00389     glUniform1fARB(GetUniLoc(PNTriProg, "SpecMag"), 16.0f);
00390 
00391     return 1;
00392 }
00393 
00394 //=============================================================================
00395 // Update Uniform Variables for calculating a PN-Triangle Patch
00396 //-----------------------------------------------------------------------------
00397 void SetUniformVariables() {
00398     static float brickSize[] = { 1.80f, 0.90f };
00399     static int count = 1;
00400     // handles to (shader) program object
00401     GLhandleARB PNTriProg = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
00402 
00403     glUniform2fARB(GetUniLoc(PNTriProg, "BrickSize"), brickSize[0], brickSize[1]);
00404     
00405     float inc = 0.000025f;
00406     if (count <= 10000) {
00407         brickSize[0] += inc;
00408         brickSize[1] += inc;
00409     }
00410     else if (count <= 20000) {
00411         brickSize[0] -= inc;
00412         brickSize[1] -= inc;
00413     }
00414     else {
00415         count = 0;
00416     }
00417     ++count;
00418     //std::cout << count << std::endl;
00419 }
00420 
00421 
00422 //=============================================================================
00423 // Draw a PN-Triangle Patch
00424 //-----------------------------------------------------------------------------
00425 void DrawPNTrianglePatch(int faceNo, int smoothness, float *b, float *n) {
00426     //std::cout << "Face#" << faceNo << "\n";
00427 
00428     // b is a pointer to a cubic triangle Bezier cofficient (10 pts * 3 dimensions)
00429     // n is a pointer to a quadratic triangle Bezier normal ( 6 pts * 3 dimensions)
00430 
00431     // handles to (shader) program object
00432     GLhandleARB PNTriProg = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
00433 
00434     int noOfVertices = smoothness*(smoothness+1)/2;
00435     float *vertex = new float[noOfVertices*3];
00436     float *normal = new float[noOfVertices*3];
00437 
00438     // Set Uniform Variables
00439     int bIdx = faceNo*30;
00440     int nIdx = faceNo*18;
00441     glUniform3fvARB(GetUniLoc(PNTriProg, "BezierCoeffi"), 10, b+bIdx);
00442     //std::cerr << "TEST1\n";
00443     glUniform3fvARB(GetUniLoc(PNTriProg, "BezierNormal"),  6, n+nIdx);
00444     //std::cerr << "TEST2\n";
00445 
00447     int index = 0;
00448     float uInc = static_cast<float>( 1.0 / (smoothness-1) );
00449     float vInc = static_cast<float>( 1.0 / (smoothness-1) );
00450     float u = 0.0f;
00451     float v = 0.0f;
00452 
00453     u = 0.0f;
00454     int row1 = 0, row2 = smoothness*3;
00455     for ( int r = 1; r < smoothness; ++r, row1+=3 ) {
00456         v = 0.0f;
00457         glBegin( GL_TRIANGLE_STRIP );
00458             for ( int i = 0; i < smoothness-r; ++i, row1+=3, row2+=3 ) {
00459                 glNormal3f( u, v, normal[row1+2] );
00460                 glVertex3f( u, v, vertex[row1+2] );
00461                 u += uInc;
00462                 glNormal3f( u, v, normal[row2+2] );
00463                 glVertex3f( u, v, vertex[row2+2] );
00464                 v += vInc;
00465                 u -= uInc;
00466             }
00467             glNormal3f( u, v, normal[row1+2] );
00468             glVertex3f( u, v, vertex[row1+2] );
00469         glEnd();
00470         u += uInc;
00471     }
00472     delete [] vertex;
00473     delete [] normal;
00474 }
00475 
00476 //=============================================================================
00477 // Draw PN-Triangle Mesh
00478 //-----------------------------------------------------------------------------
00479 void DrawTriangleUsingHardware(int noOfFaces, int smoothness, float *b, float *n) {
00480     
00481     int noOfVertices = smoothness*(smoothness+1)/2;
00482     float *vertex = new float[noOfVertices*3];
00483     float *normal = new float[noOfVertices*3];
00484     for ( int faceNo = 0; faceNo < noOfFaces; ++faceNo ) {
00485         //std::cout << "Face#" << faceNo << "\n";
00486 
00487         // b is a pointer to a cubic triangle Bezier cofficient (10 pts * 3 dimensions)
00488         // n is a pointer to a quadratic triangle Bezier normal ( 6 pts * 3 dimensions)
00489 
00490         // handles to (shader) program object
00491         GLhandleARB PNTriProg = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
00492 
00493         // Set Uniform Variables
00494         int bIdx = faceNo*30;
00495         int nIdx = faceNo*18;
00496         glUniform3fvARB(GetUniLoc(PNTriProg, "BezierCoeffi"), 10, b+bIdx);
00497         //std::cerr << "TEST1\n";
00498         glUniform3fvARB(GetUniLoc(PNTriProg, "BezierNormal"),  6, n+nIdx);
00499         //std::cerr << "TEST2\n";
00500 
00502         int index = 0;
00503         float uInc = static_cast<float>( 1.0 / (smoothness-1) );
00504         float vInc = static_cast<float>( 1.0 / (smoothness-1) );
00505         float u = 0.0f;
00506         float v = 0.0f;
00507 
00508         u = 0.0f;
00509         int row1 = 0, row2 = smoothness*3;
00510         for ( int r = 1; r < smoothness; ++r, row1+=3 ) {
00511             v = 0.0f;
00512             glBegin( GL_TRIANGLE_STRIP );
00513                 for ( int i = 0; i < smoothness-r; ++i, row1+=3, row2+=3 ) {
00514                     glNormal3f( u, v, normal[row1+2] );
00515                     glVertex3f( u, v, vertex[row1+2] );
00516                     u += uInc;
00517                     glNormal3f( u, v, normal[row2+2] );
00518                     glVertex3f( u, v, vertex[row2+2] );
00519                     v += vInc;
00520                     u -= uInc;
00521                 }
00522                 glNormal3f( u, v, normal[row1+2] );
00523                 glVertex3f( u, v, vertex[row1+2] );
00524             glEnd();
00525             u += uInc;
00526         }
00527     }
00528     delete [] vertex;
00529     delete [] normal;
00530 }
00531 
00532 //=============================================================================
00533 // Calculate the volume covered by a triangular mesh
00534 //-----------------------------------------------------------------------------
00535 void DetermineExtensions ( 
00536 //  OpenGLPNTriangleVolPresModel<Real> * pTriMesh,      // I/P
00537     Real rVolume                                        // O/P
00538 )
00539 {
00540     if (WGLEW_ARB_pbuffer) {
00541         std::cout << "OK, we can use pbuffers.\n";
00542     }
00543     else {
00544         std::cout << "Sorry, pbuffers will not work on this platform.\n";
00545     }
00546 }
00547 
00548 //=============================================================================
00549 // Print Out GLSL Error
00550 //-----------------------------------------------------------------------------
00551 int PrintOglError(char *file, int line)
00552 {
00553     //
00554     // Returns 1 if an OpenGL error occurred, 0 otherwise.
00555     //
00556     GLenum glErr;
00557     int    retCode = 0;
00558 
00559     glErr = glGetError();
00560     while (glErr != GL_NO_ERROR)
00561     {
00562         printf("glError in file %s @ line %d: %s\n", file, line, gluErrorString(glErr));
00563         retCode = 1;
00564         glErr = glGetError();
00565     }
00566     return retCode;
00567 }
00568 //-----------------------------------------------------------------------------
00569 //=============================================================================
00570 END_NAMESPACE_TAPs__OpenGL
00571 //-----------------------------------------------------------------------------
00572 // Include definition if TAPs_USE_EXPORT is not defined
00573 #if !defined( TAPs_USE_EXPORT )
00574     //#include "TAPsShaderFns.cpp"
00575 #endif
00576 //-----------------------------------------------------------------------------
00577 #endif
00578 //345678901234567890123456789012345678901234567890123456789012345678901234567890
00579 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines