![]() |
TAPs 0.7.7.3
|
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