From 163b963b1d6c1d0d288e27aeb978ff521a241917 Mon Sep 17 00:00:00 2001 From: Kyle K Date: Sun, 3 Oct 2010 18:30:04 -0500 Subject: Initial commit --- lib/gltools.cpp | 651 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 651 insertions(+) create mode 100644 lib/gltools.cpp (limited to 'lib/gltools.cpp') diff --git a/lib/gltools.cpp b/lib/gltools.cpp new file mode 100644 index 0000000..bcdd957 --- /dev/null +++ b/lib/gltools.cpp @@ -0,0 +1,651 @@ +/* + * gltools.c + * Block + * + * Created by Richard Wright on 10/16/06. + * OpenGL SuperBible, 4th Edition + * + */ + +#include "gltools.h" +#include "math3d.h" +#include + +/////////////////////////////////////////////////////////////////////////////// +// Get the OpenGL version number +bool gltGetOpenGLVersion(int &nMajor, int &nMinor) +{ + const char *szVersionString = (const char *)glGetString(GL_VERSION); + if (szVersionString == NULL) + { + nMajor = 0; + nMinor = 0; + return false; + } + + // Get major version number. This stops at the first non numeric character + nMajor = atoi(szVersionString); + + // Get minor version number. Start past the first ".", atoi terminates on first non numeric char. + nMinor = atoi(strstr(szVersionString, ".")+1); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +// This function determines if the named OpenGL Extension is supported +// Returns 1 or 0 +int gltIsExtSupported(const char *extension) +{ + GLubyte *extensions = NULL; + const GLubyte *start; + GLubyte *where, *terminator; + + where = (GLubyte *) strchr(extension, ' '); + if (where || *extension == '\0') + return 0; + + extensions = (GLubyte *)glGetString(GL_EXTENSIONS); + + start = extensions; + for (;;) + { + where = (GLubyte *) strstr((const char *) start, extension); + + if (!where) + break; + + terminator = where + strlen(extension); + + if (where == start || *(where - 1) == ' ') + { + if (*terminator == ' ' || *terminator == '\0') + return 1; + } + start = terminator; + } + return 0; +} + +#ifdef _WIN32 +/////////////////////////////////////////////////////////////////////////////// +// Win32 Only, check for WGL extension +#include "wglext.h" +int gltIsWGLExtSupported(HDC hDC, const char *szExtension) +{ + GLubyte *extensions = NULL; + const GLubyte *start; + GLubyte *where, *terminator; + PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB; + + // Just look or the entry point + wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB"); + if (wglGetExtensionsStringARB == NULL) + return 0; + + where = (GLubyte *) strchr(szExtension, ' '); + if (where || *szExtension == '\0') + return 0; + + extensions = (GLubyte *)wglGetExtensionsStringARB(hDC); + + start = extensions; + for (;;) + { + where = (GLubyte *) strstr((const char *) start, szExtension); + + if (!where) + break; + + terminator = where + strlen(szExtension); + + if (where == start || *(where - 1) == ' ') + { + if (*terminator == ' ' || *terminator == '\0') + return 1; + } + start = terminator; + } + return 0; +} +#endif + +///////////////////////////////////////////////////////////// +// Get a pointer to an OpenGL extension +// Note on the Mac, this does a lot of work that could be saved +// if you call this function repeatedly. Write your own function that +// gets the bundle once, gets all the function pointers, then releases +// the bundle. +void *gltGetExtensionPointer(const char *szExtensionName) +{ +#ifdef WIN32 + // Well, this one is simple. An OpenGL context must be + // current first. Returns NULL if extension not supported + return (void *)wglGetProcAddress(szExtensionName); +#endif + +#ifdef linux + // Pretty much ditto above + return (void *)glXGetProcAddress((GLubyte *)szExtensionName); +#endif + +#ifdef __APPLE__ + // Mac is a bit more tricky. + // First we need the bundle + CFBundleRef openGL = 0; + SInt16 fwVersion = 0; + SInt32 fwDir = 0; + + if (FindFolder(kSystemDomain, kFrameworksFolderType, kDontCreateFolder, &fwVersion, &fwDir) != noErr) + return NULL; + + FSSpec fSpec; + FSRef fRef; + if (FSMakeFSSpec(fwVersion, fwDir, "\pOpenGL.framework", &fSpec) != noErr) + return NULL; + + FSpMakeFSRef(&fSpec, &fRef); + CFURLRef url = CFURLCreateFromFSRef(kCFAllocatorDefault, &fRef); + if (!url) + return NULL; + + openGL = CFBundleCreate(kCFAllocatorDefault, url); + CFRelease(url); + + // Then load the function pointer from the bundle + CFStringRef string = CFStringCreateWithCString(kCFAllocatorDefault, szExtensionName, kCFStringEncodingMacRoman); + void *pFunc = CFBundleGetFunctionPointerForName(openGL, string); + + // Release the bundle and string + CFRelease(string); + CFRelease(openGL); + + // Return the function ponter + return pFunc; +#endif +} + +/////////////////////////////////////////////////////////////////// +// Draw the unit axis. A small white sphere represents the origin +// and the three axes are colored Red, Green, and Blue, which +// corresponds to positive X, Y, and Z respectively. Each axis has +// an arrow on the end, and normals are provided should the axes +// be lit. These are all built using the quadric shapes. For best +// results, put this in a display list. +void gltDrawUnitAxes(void) +{ + GLUquadricObj *pObj; // Temporary, used for quadrics + + // Measurements + float fAxisRadius = 0.025f; + float fAxisHeight = 1.0f; + float fArrowRadius = 0.06f; + float fArrowHeight = 0.1f; + + // Setup the quadric object + pObj = gluNewQuadric(); + gluQuadricDrawStyle(pObj, GLU_FILL); + gluQuadricNormals(pObj, GLU_SMOOTH); + gluQuadricOrientation(pObj, GLU_OUTSIDE); + gluQuadricTexture(pObj, GLU_FALSE); + + /////////////////////////////////////////////////////// + // Draw the blue Z axis first, with arrowed head + glColor3f(0.0f, 0.0f, 1.0f); + gluCylinder(pObj, fAxisRadius, fAxisRadius, fAxisHeight, 10, 1); + glPushMatrix(); + glTranslatef(0.0f, 0.0f, 1.0f); + gluCylinder(pObj, fArrowRadius, 0.0f, fArrowHeight, 10, 1); + glRotatef(180.0f, 1.0f, 0.0f, 0.0f); + gluDisk(pObj, fAxisRadius, fArrowRadius, 10, 1); + glPopMatrix(); + + /////////////////////////////////////////////////////// + // Draw the Red X axis 2nd, with arrowed head + glColor3f(1.0f, 0.0f, 0.0f); + glPushMatrix(); + glRotatef(90.0f, 0.0f, 1.0f, 0.0f); + gluCylinder(pObj, fAxisRadius, fAxisRadius, fAxisHeight, 10, 1); + glPushMatrix(); + glTranslatef(0.0f, 0.0f, 1.0f); + gluCylinder(pObj, fArrowRadius, 0.0f, fArrowHeight, 10, 1); + glRotatef(180.0f, 0.0f, 1.0f, 0.0f); + gluDisk(pObj, fAxisRadius, fArrowRadius, 10, 1); + glPopMatrix(); + glPopMatrix(); + + /////////////////////////////////////////////////////// + // Draw the Green Y axis 3rd, with arrowed head + glColor3f(0.0f, 1.0f, 0.0f); + glPushMatrix(); + glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); + gluCylinder(pObj, fAxisRadius, fAxisRadius, fAxisHeight, 10, 1); + glPushMatrix(); + glTranslatef(0.0f, 0.0f, 1.0f); + gluCylinder(pObj, fArrowRadius, 0.0f, fArrowHeight, 10, 1); + glRotatef(180.0f, 1.0f, 0.0f, 0.0f); + gluDisk(pObj, fAxisRadius, fArrowRadius, 10, 1); + glPopMatrix(); + glPopMatrix(); + + //////////////////////////////////////////////////////// + // White Sphere at origin + glColor3f(1.0f, 1.0f, 1.0f); + gluSphere(pObj, 0.05f, 15, 15); + + // Delete the quadric + gluDeleteQuadric(pObj); +} + +// For best results, put this in a display list +// Draw a torus (doughnut) at z = fZVal... torus is in xy plane +void gltDrawTorus(GLfloat majorRadius, GLfloat minorRadius, GLint numMajor, GLint numMinor) +{ + M3DVector3f vNormal; + double majorStep = 2.0f*M3D_PI / numMajor; + double minorStep = 2.0f*M3D_PI / numMinor; + int i, j; + + for (i=0; i This is defined in gltools.h +static GLubyte shaderText[MAX_SHADER_LENGTH]; + +//////////////////////////////////////////////////////////////// +// Load the shader from the specified file. Returns false if the +// shader could not be loaded +bool bLoadShaderFile(const char *szFile, GLhandleARB shader) +{ + GLint shaderLength = 0; + FILE *fp; + GLcharARB *fsStringPtr[1]; + + // Open the shader file + fp = fopen(szFile, "r"); + if (fp != NULL) + { + // See how long the file s + while (fgetc(fp) != EOF) + shaderLength++; + + // Allocate a block of memory to send in the shader + assert(shaderLength < MAX_SHADER_LENGTH); // make me bigger! + if (shaderLength > MAX_SHADER_LENGTH) + { + fclose(fp); + return false; + } + + // Go back to beginning of file + rewind(fp); + + // Read the whole file in + if (shaderText != NULL) + fread(shaderText, 1, shaderLength, fp); + + // Make sure it is null terminated and close the file + shaderText[shaderLength] = '\0'; + fclose(fp); + } + else + return false; + + // Load the string + fsStringPtr[0] = (GLcharARB *)shaderText; + glShaderSourceARB(shader, 1, (const GLcharARB **)fsStringPtr, NULL); + + return true; +} + +///////////////////////////////////////////////////////////////// +// Load a pair of shaders, compile, and link together. Specify the complete +// path and file name of each ASCII shader file. Note, there is no support for +// just loading say a vertex program... you have to do both. +GLhandleARB gltLoadShaderPair(const char *szVertexProg, const char *szFragmentProg) +{ + // Temporary Shader objects + GLhandleARB hVertexShader; + GLhandleARB hFragmentShader; + GLhandleARB hReturn = 0; + GLint testVal; + + // Create shader objects + hVertexShader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB); + hFragmentShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); + + // Load them. If fail clean up and return null + if (bLoadShaderFile(szVertexProg, hVertexShader) == false) + { + glDeleteObjectARB(hVertexShader); + glDeleteObjectARB(hFragmentShader); + return 0; + } + + if (bLoadShaderFile(szFragmentProg, hFragmentShader) == false) + { + glDeleteObjectARB(hVertexShader); + glDeleteObjectARB(hFragmentShader); + return 0; + } + + // Compile them + glCompileShaderARB(hVertexShader); + glCompileShaderARB(hFragmentShader); + + // Check for errors + glGetObjectParameterivARB(hVertexShader, GL_OBJECT_COMPILE_STATUS_ARB, &testVal); + if (testVal == GL_FALSE) + { + glDeleteObjectARB(hVertexShader); + glDeleteObjectARB(hFragmentShader); + return 0; + } + + glGetObjectParameterivARB(hFragmentShader, GL_OBJECT_COMPILE_STATUS_ARB, &testVal); + if (testVal == GL_FALSE) + { + glDeleteObjectARB(hVertexShader); + glDeleteObjectARB(hFragmentShader); + return 0; + } + + // Link them - assuming it works... + hReturn = glCreateProgramObjectARB(); + glAttachObjectARB(hReturn, hVertexShader); + glAttachObjectARB(hReturn, hFragmentShader); + glLinkProgramARB(hReturn); + + // These are no longer needed + glDeleteObjectARB(hVertexShader); + glDeleteObjectARB(hFragmentShader); + + return hReturn; +} + -- cgit v1.2.3