コード例 #1
0
ファイル: Tunnel.cpp プロジェクト: wjingzhe/OpenGL_SB5_static
void ProcessMenu(int value)
{
	GLfloat fLargest;
	for (size_t i = 0; i < TEXTURE_COUNT; ++i)
	{
		glBindTexture(GL_TEXTURE_2D, uiTextures[i]);

		switch (value)
		{
		case 0:
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
			break;

		case 1:
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			break;

		case 2:
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
			break;

		case 3:
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
			break;

		case 4:
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
			break;

		case 5:
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
			break;

		case 6://在三线性过滤的模式下开启各项异性过滤就会发现计算很远距离的仍然能看到砖缝
			if (gltIsExtSupported("GL_EXT_texture_filter_anisotropic"))
			{
				glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fLargest);
				glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, fLargest);
			}
			break;

		case 7:
			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
			break;
		default:
			break;
		}
	}

	glutPostRedisplay();

}
コード例 #2
0
ファイル: main.cpp プロジェクト: tailnode/chaos
void setupRC()
{
    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    glEnable(GL_DEPTH_TEST);
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    shaderManager.InitializeStockShaders();
    pipelineTransform.SetMatrixStacks(modelViewM, projectionM);

    generateCuboidBatch(cuboidBatch, cuboidLength, cuboidWidth, cuboidHeigth);

    glGenTextures(2, textureID);
    glBindTexture(GL_TEXTURE_2D, textureID[0]);
    LoadTGATexture("stone.tga", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_LINEAR, GL_CLAMP_TO_EDGE);
    glBindTexture(GL_TEXTURE_2D, textureID[1]);
    LoadTGATexture("black_white.tga", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_LINEAR, GL_REPEAT);

    if(gltIsExtSupported("GL_EXT_texture_filter_anisotropic")) {
        isAnisotropySupported = true;
        glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest);
        printf("anisotropy is supported, largest %f\n", largest);
    }
}
コード例 #3
0
/////////////////////////////////////////////////////////////
// Main program entrypoint
int main(int argc, char* argv[])
    {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GL_DOUBLE);
    glutInitWindowSize(600 ,600);
    glutCreateWindow("OpenGL Imaging subset");

    // Check for imaging subset, must be done after window
    // is create or there won't be an OpenGL context to query
    if(gltIsExtSupported("GL_ARB_imaging") == 0)
        {
        printf("Imaging subset not supported\r\n");
        return 0;
        }

    glutReshapeFunc(ChangeSize);
    glutDisplayFunc(RenderScene);
    
    // Create the Menu and add choices
	glutCreateMenu(ProcessMenu);
	glutAddMenuEntry("Save Image",0);
    glutAddMenuEntry("Raw Stretched Image",1);
    glutAddMenuEntry("Increase Contrast",2);
    glutAddMenuEntry("Invert Color", 3);
    glutAddMenuEntry("Emboss Image", 4);
    glutAddMenuEntry("Sharpen Image", 5);
    glutAddMenuEntry("Histogram", 6);
    
    glutAttachMenu(GLUT_RIGHT_BUTTON);
    
    SetupRC();          // Do setup
    
    glutMainLoop();     // Main program loop

    ShutdownRC();       // Do shutdown

    return 0;
    }
コード例 #4
0
/////////////////////////////////////////////////////////////////////////////
// Dialog procedure for the startup dialog
BOOL APIENTRY StartupDlgProc (HWND hDlg, UINT message, UINT wParam, LONG lParam)
{
    switch (message)
    {
    // Initialize the dialog box
    case WM_INITDIALOG:
    {
        int nPF;
        HDC hDC;                        // Dialogs device context
        HGLRC hRC;
        DEVMODE devMode;
        unsigned int iMode;
        unsigned int nWidth;	// Current settings
        unsigned int nHeight;
        char cBuffer[64];
        HWND hListBox;

        PIXELFORMATDESCRIPTOR pfd = {   // Not going to be too picky
            sizeof(PIXELFORMATDESCRIPTOR),
            1,
            PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
            PFD_TYPE_RGBA,		// Full color
            32,					// Color depth
            0,0,0,0,0,0,0,		// Ignored
            0,0,0,0,		    // Accumulation buffer
            16,					// Depth bits
            8,					// Stencil bits
            0,0,0,0,0,0
        };		// Some used, some not


        // Initialize render options
        startupOptions.bFSAA = FALSE;
        startupOptions.bFullScreen = FALSE;
        startupOptions.bVerticalSync = FALSE;

        // Create a "temporary" OpenGL rendering context
        hDC = GetDC(hDlg);

        // Set pixel format one time....
        nPF = ChoosePixelFormat(hDC, &pfd);
        SetPixelFormat(hDC, nPF, &pfd);
        DescribePixelFormat(hDC, nPF, sizeof(PIXELFORMATDESCRIPTOR), &pfd);

        // Create the GL context
        hRC = wglCreateContext(hDC);
        wglMakeCurrent(hDC, hRC);

        // Set text in dialog
        SetDlgItemText(hDlg, IDC_VENDOR, (const char *)glGetString(GL_VENDOR));
        SetDlgItemText(hDlg, IDC_RENDERER, (const char *)glGetString(GL_RENDERER));
        SetDlgItemText(hDlg, IDC_VERSION, (const char *)glGetString(GL_VERSION));

        // Vertical Sync off by default
        if(gltIsExtSupported("WGL_EXT_swap_control"))
            EnableWindow(GetDlgItem(hDlg, IDC_VSYNC_CHECK), TRUE);

        // Find a multisampled and non-multisampled pixel format
        FindBestPF(hDC, &startupOptions.nPixelFormat, &startupOptions.nPixelFormatMS);

        // Done with GL context
        wglMakeCurrent(hDC, NULL);
        wglDeleteContext(hRC);

        // Enumerate display modes
        iMode = 0;
        nWidth = GetSystemMetrics(SM_CXSCREEN);	// Current settings
        nHeight = GetSystemMetrics(SM_CYSCREEN);
        hListBox = GetDlgItem(hDlg, IDC_DISPLAY_COMBO);
        while(EnumDisplaySettings(NULL, iMode, &devMode))
        {
            //if(devMode.dmBitsPerPel == pfd.cColorBits)
            {
                int iItem;
                sprintf(cBuffer,"%d x %d x %dbpp @%dhz", devMode.dmPelsWidth,
                        devMode.dmPelsHeight, devMode.dmBitsPerPel, devMode.dmDisplayFrequency);

                iItem = SendMessage(hListBox, CB_ADDSTRING, 0, (LPARAM)cBuffer);
                SendMessage(hListBox, CB_SETITEMDATA, iItem, iMode);

                if(devMode.dmPelsHeight == nHeight &&
                        devMode.dmPelsWidth == nWidth)
                    SendMessage(hListBox, CB_SETCURSEL, iItem, 0);
            }
            iMode++;
        }


        // Set other defaults /////////////
        // Windowed or full screen
        CheckDlgButton(hDlg, IDC_FS_CHECK, BST_CHECKED);

        // FSAA, but only if support detected
        if(startupOptions.nPixelFormatMS != 0)
            EnableWindow(GetDlgItem(hDlg, IDC_MULTISAMPLED_CHECK), TRUE);

        return (TRUE);
    }
    break;

    // Process command messages
    case WM_COMMAND:
    {
        // Validate and Make the changes
        if(LOWORD(wParam) == IDOK)
        {
            // Read options ////////////////////////////////////////
            // Display mode
            HWND hListBox = GetDlgItem(hDlg, IDC_DISPLAY_COMBO);
            int iMode = SendMessage(hListBox, CB_GETCURSEL, 0, 0);
            iMode = SendMessage(hListBox, CB_GETITEMDATA, iMode, 0);
            EnumDisplaySettings(NULL, iMode, &startupOptions.devMode);

            // Full screen or windowed?
            if(IsDlgButtonChecked(hDlg, IDC_FS_CHECK))
                startupOptions.bFullScreen = TRUE;
            else
                startupOptions.bFullScreen = FALSE;


            // FSAA
            if(IsDlgButtonChecked(hDlg, IDC_MULTISAMPLED_CHECK))
                startupOptions.bFSAA = TRUE;
            else
                startupOptions.bFSAA = FALSE;

            // Vertical Sync.
            if(IsDlgButtonChecked(hDlg, IDC_VSYNC_CHECK))
                startupOptions.bVerticalSync = TRUE;
            else
                startupOptions.bVerticalSync = FALSE;


            EndDialog(hDlg,TRUE);
        }

        if(LOWORD(wParam) == IDCANCEL)
            EndDialog(hDlg, FALSE);
    }
    break;

    // Closed from sysbox
    case WM_CLOSE:
        EndDialog(hDlg,FALSE); // Same as cancel
        break;
    }

    return FALSE;
}
コード例 #5
0
///////////////////////////////////////////////////////////////////////////////
// Setup. Create font/bitmaps, load textures, create display lists
void SetupRC(HDC hDC)
{
    M3DVector3f vPoints[3] = {{ 0.0f, -0.4f, 0.0f },
        { 10.0f, -0.4f, 0.0f },
        { 5.0f, -0.4f, -5.0f }
    };
    int iSphere;
    int i;

    // Setup the Font characteristics
    HFONT hFont;
    LOGFONT logfont;

    logfont.lfHeight = -20;
    logfont.lfWidth = 0;
    logfont.lfEscapement = 0;
    logfont.lfOrientation = 0;
    logfont.lfWeight = FW_BOLD;
    logfont.lfItalic = FALSE;
    logfont.lfUnderline = FALSE;
    logfont.lfStrikeOut = FALSE;
    logfont.lfCharSet = ANSI_CHARSET;
    logfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
    logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
    logfont.lfQuality = DEFAULT_QUALITY;
    logfont.lfPitchAndFamily = DEFAULT_PITCH;
    strcpy(logfont.lfFaceName,"Arial");

    // Create the font and display list
    hFont = CreateFontIndirect(&logfont);
    SelectObject (hDC, hFont);


    //Create display lists for glyphs 0 through 128
    nFontList = glGenLists(128);
    wglUseFontBitmaps(hDC, 0, 128, nFontList);

    DeleteObject(hFont);		// Don't need original font anymore

    // Grayish background
    glClearColor(fLowLight[0], fLowLight[1], fLowLight[2], fLowLight[3]);

    // Clear stencil buffer with zero, increment by one whenever anybody
    // draws into it. When stencil function is enabled, only write where
    // stencil value is zero. This prevents the transparent shadow from drawing
    // over itself
    glStencilOp(GL_INCR, GL_INCR, GL_INCR);
    glClearStencil(0);
    glStencilFunc(GL_EQUAL, 0x0, 0x01);

    // Cull backs of polygons
    glCullFace(GL_BACK);
    glFrontFace(GL_CCW);
    glEnable(GL_CULL_FACE);
    glEnable(GL_DEPTH_TEST);


    // Setup light parameters
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, fNoLight);
    glLightfv(GL_LIGHT0, GL_AMBIENT, fLowLight);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, fBrightLight);
    glLightfv(GL_LIGHT0, GL_SPECULAR, fBrightLight);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

    // Calculate shadow matrix
    M3DVector4f pPlane;
    m3dGetPlaneEquation(pPlane, vPoints[0], vPoints[1], vPoints[2]);
    m3dMakePlanarShadowMatrix(mShadowMatrix, pPlane, fLightPos);

    // Mostly use material tracking
    glEnable(GL_COLOR_MATERIAL);
    glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
    glMateriali(GL_FRONT, GL_SHININESS, 128);

    // Randomly place the sphere inhabitants
    for(iSphere = 0; iSphere < NUM_SPHERES; iSphere++)
    {
        // Pick a random location between -20 and 20 at .1 increments
        spheres[iSphere].SetOrigin((float)((rand() % 400) - 200) * 0.1f,
                                   0.0f,
                                   (float)((rand() % 400) - 200) * 0.1f);
    }

    // Set up texture maps
    glEnable(GL_TEXTURE_2D);
    glGenTextures(NUM_TEXTURES, textureObjects);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

    // Load teach texture
    for(i = 0; i < NUM_TEXTURES; i++)
    {
        GLbyte *pBytes;
        GLint iWidth, iHeight, iComponents;
        GLenum eFormat;

        glBindTexture(GL_TEXTURE_2D, textureObjects[i]);

        // Load this texture map
        pBytes = gltLoadTGA(szTextureFiles[i], &iWidth, &iHeight, &iComponents, &eFormat);
        gluBuild2DMipmaps(GL_TEXTURE_2D, iComponents, iWidth, iHeight, eFormat, GL_UNSIGNED_BYTE, pBytes);
        free(pBytes);

        // Trilinear mipmapping
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    }

    // Get window position function pointer if it exists
    glWindowPos2i = (PFNGLWINDOWPOS2IPROC)wglGetProcAddress("glWindowPos2i");

    // Get swap interval function pointer if it exists
    wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
    if(wglSwapIntervalEXT != NULL && startupOptions.bVerticalSync == TRUE)
        wglSwapIntervalEXT(1);

    // If multisampling was available and was selected, enable
    if(startupOptions.bFSAA == TRUE && startupOptions.nPixelFormatMS != 0)
        glEnable(GL_MULTISAMPLE_ARB);

    // If sepearate specular color is available, make torus shiney
    if(gltIsExtSupported("GL_EXT_separate_specular_color"))
        glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);


    // Initialize the timers
    QueryPerformanceFrequency(&CounterFrequency);
    QueryPerformanceCounter(&FPSCount);
    CameraTimer = FPSCount;

    // Build display lists for the torus and spheres
    // (You could do one for the ground as well)
    lTorusList = glGenLists(2);
    lSphereList = lTorusList + 1;

    glNewList(lTorusList, GL_COMPILE);
    gltDrawTorus(0.35f, 0.15f, 61, 37);
    glEndList();

    glNewList(lSphereList, GL_COMPILE);
    gltDrawSphere(0.3f, 31, 16);
    glEndList();
}
コード例 #6
0
ファイル: bufferobject.c プロジェクト: Daft-Freak/vogl
// This function does any needed initialization on the rendering
// context. 
void SetupRC()
{
    const GLubyte *version;
    GLboolean glVersion15 = GL_FALSE;

    fprintf(stdout, "Buffer Object Demo\n\n");

    // Make sure required functionality is available!
    version = glGetString(GL_VERSION);
    if ((version[0] == '1') && (version[1] == '.') &&
        (version[2] >= '5') && (version[2] <= '9'))
    {
        glVersion15 = GL_TRUE;
    }

    if (!glVersion15 && !gltIsExtSupported("GL_ARB_vertex_buffer_object"))
    {
        fprintf(stderr, "Neither OpenGL 1.5 nor GL_ARB_vertex_buffer_object"
                        " extension is available!\n");
        sleep(2);
        exit(0);
    }

    // Load the function pointers
    if (glVersion15)
    {
        glBindBuffer = gltGetExtensionPointer("glBindBuffer");
        glBufferData = gltGetExtensionPointer("glBufferData");
        glBufferSubData = gltGetExtensionPointer("glBufferSubData");
        glDeleteBuffers = gltGetExtensionPointer("glDeleteBuffers");
        glGenBuffers = gltGetExtensionPointer("glGenBuffers");
        glMapBuffer = gltGetExtensionPointer("glMapBuffer");
        glUnmapBuffer = gltGetExtensionPointer("glUnmapBuffer");
    }
    else
    {
        glBindBuffer = gltGetExtensionPointer("glBindBufferARB");
        glBufferData = gltGetExtensionPointer("glBufferDataARB");
        glBufferSubData = gltGetExtensionPointer("glBufferSubDataARB");
        glDeleteBuffers = gltGetExtensionPointer("glDeleteBuffersARB");
        glGenBuffers = gltGetExtensionPointer("glGenBuffersARB");
        glMapBuffer = gltGetExtensionPointer("glMapBufferARB");
        glUnmapBuffer = gltGetExtensionPointer("glUnmapBufferARB");
    }

    if (!glBindBuffer || !glBufferData || !glBufferSubData || 
        !glDeleteBuffers || !glGenBuffers || !glMapBuffer || !glUnmapBuffer)
    {
        fprintf(stderr, "Not all entrypoints were available!\n");
        sleep(2);
        exit(0);
    }

    sphereVertexArray = (GLfloat *)malloc(sizeof(GLfloat) * 
                                          numSphereVertices * 3);
    if (!sphereVertexArray)
    {
        fprintf(stderr, "Unable to allocate system memory for vertex arrays!");
        sleep(2);
        exit(0);
    }

    fprintf(stdout, "Controls:\n");
    fprintf(stdout, "\tRight-click for menu\n\n");
    fprintf(stdout, "\tx/X\t\tMove +/- in x direction\n");
    fprintf(stdout, "\ty/Y\t\tMove +/- in y direction\n");
    fprintf(stdout, "\tz/Z\t\tMove +/- in z direction\n\n");
    fprintf(stdout, "\tq\t\tExit demo\n\n");
    
    // Generate a buffer object
    glGenBuffers(1, &bufferID);
    // Create the data store 
    glBindBuffer(GL_ARRAY_BUFFER, bufferID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 
                 numSphereVertices * 3, NULL, 
                 GL_STATIC_DRAW);

    // Set up vertex arrays
    RegenerateSphere();
    SetRenderingMethod();
    glEnableClientState(GL_NORMAL_ARRAY);
    glEnableClientState(GL_VERTEX_ARRAY);

    // Black background
    glClearColor(0.3f, 0.3f, 0.3f, 1.0f );

    // Hidden surface removal
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);

    // Set up some lighting state that never changes
    glShadeModel(GL_SMOOTH);
    glEnable(GL_LIGHTING);
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_NORMALIZE);
    glEnable(GL_LIGHT0);
    glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
}
コード例 #7
0
ファイル: vertexblending.c プロジェクト: Daft-Freak/vogl
// This function does any needed initialization on the rendering
// context. 
void SetupRC()
{
    const GLubyte *version;
    GLint i;

    fprintf(stdout, "Vertex Blending Demo\n\n");

    // Make sure required functionality is available!
    if (gltIsExtSupported("GL_ARB_vertex_shader") &&
        gltIsExtSupported("GL_ARB_shader_objects") &&
        gltIsExtSupported("GL_ARB_shading_language_100"))
    {
        highLevelAvailable = GL_TRUE;
    }
    if (gltIsExtSupported("GL_ARB_vertex_program"))
    {
        lowLevelAvailable = GL_TRUE;
    }
    if (!lowLevelAvailable && !highLevelAvailable)
    {
        fprintf(stderr, "Neither vertex shader"
                        " extension is available!\n");
        usleep(2000);
        exit(0);
    }

    // Make sure we have 1.3+, multitexture, cube maps, and texenv add!
    version = glGetString(GL_VERSION);
    if ( ((version[0] == '1') && ((version[1] != '.') || (version[2] < '3') || (version[2] > '9'))) &&
         (!gltIsExtSupported("GL_ARB_multitexture") || !gltIsExtSupported("GL_ARB_texture_env_add")) )
    {
        fprintf(stderr, "Neither OpenGL 1.3 nor necessary"
                        " extensions are available!\n");
        usleep(2000);
        exit(0);
    }

    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);

    if (lowLevelAvailable)
    {
        glGenProgramsARB = gltGetExtensionPointer("glGenProgramsARB");
        glBindProgramARB = gltGetExtensionPointer("glBindProgramARB");
        glProgramStringARB = gltGetExtensionPointer("glProgramStringARB");
        glDeleteProgramsARB = gltGetExtensionPointer("glDeleteProgramsARB");
        glProgramLocalParameter4fARB = gltGetExtensionPointer("glProgramLocalParameter4fARB");
        glProgramLocalParameter4fvARB = gltGetExtensionPointer("glProgramLocalParameter4fvARB");
        glVertexAttrib1fARB = gltGetExtensionPointer("glVertexAttrib1fARB");

        if (!glGenProgramsARB || !glBindProgramARB || 
            !glProgramStringARB || !glDeleteProgramsARB ||
            !glProgramLocalParameter4fARB || 
            !glProgramLocalParameter4fvARB || !glVertexAttrib1fARB)
        {
            fprintf(stderr, "Not all entrypoints were available!\n");
            usleep(2000);
            exit(0);
        }
    }

    if (highLevelAvailable)
    {
        glCreateShaderObjectARB = gltGetExtensionPointer("glCreateShaderObjectARB");
        glCreateProgramObjectARB = gltGetExtensionPointer("glCreateProgramObjectARB");
        glAttachObjectARB = gltGetExtensionPointer("glAttachObjectARB");
        glDetachObjectARB = gltGetExtensionPointer("glDetachObjectARB");
        glDeleteObjectARB = gltGetExtensionPointer("glDeleteObjectARB");
        glShaderSourceARB = gltGetExtensionPointer("glShaderSourceARB");
        glCompileShaderARB = gltGetExtensionPointer("glCompileShaderARB");
        glLinkProgramARB = gltGetExtensionPointer("glLinkProgramARB");
        glValidateProgramARB = gltGetExtensionPointer("glValidateProgramARB");
        glUseProgramObjectARB = gltGetExtensionPointer("glUseProgramObjectARB");
        glGetObjectParameterivARB = gltGetExtensionPointer("glGetObjectParameterivARB");
        glGetInfoLogARB = gltGetExtensionPointer("glGetInfoLogARB");
        glUniform3fvARB = gltGetExtensionPointer("glUniform3fvARB");
        glUniformMatrix3fvARB = gltGetExtensionPointer("glUniformMatrix3fvARB");
        glUniformMatrix4fvARB = gltGetExtensionPointer("glUniformMatrix4fvARB");
        glVertexAttrib1fARB = gltGetExtensionPointer("glVertexAttrib1fARB");
        glGetUniformLocationARB = gltGetExtensionPointer("glGetUniformLocationARB");
        glGetAttribLocationARB = gltGetExtensionPointer("glGetAttribLocationARB");

        if (!glCreateShaderObjectARB || !glCreateProgramObjectARB || 
            !glAttachObjectARB || !glDetachObjectARB || !glDeleteObjectARB || 
            !glShaderSourceARB || !glCompileShaderARB || !glLinkProgramARB ||
            !glValidateProgramARB || !glUseProgramObjectARB || 
            !glGetObjectParameterivARB || !glGetInfoLogARB || 
            !glUniformMatrix4fvARB || !glUniformMatrix4fvARB || 
            !glUniform3fvARB || !glVertexAttrib1fARB ||
            !glGetUniformLocationARB || !glGetAttribLocationARB)
        {
            fprintf(stderr, "Not all entrypoints were available!\n");
            usleep(2000);
            exit(0);
        }

        useHighLevel = GL_TRUE;
    }

    fprintf(stdout, "Controls:\n");
    fprintf(stdout, "\tRight-click for menu\n\n");
    fprintf(stdout, "\tL/R arrows\tChange sphere of influence\n");
    fprintf(stdout, "\tU/D arrows\tChange angle of forearm\n\n");
    fprintf(stdout, "\tx/X\t\tMove  +/- in x direction\n");
    fprintf(stdout, "\ty/Y\t\tMove  +/- in y direction\n");
    fprintf(stdout, "\tz/Z\t\tMove  +/- in z direction\n\n");
    fprintf(stdout, "\tq\t\tExit demo\n\n");
    
    // Black background
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f );

    // Hidden surface removal
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);

    // Misc.
    glShadeModel(GL_SMOOTH);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glPointSize(10.0f);
    glLineWidth(5.0f);

    // Texture state
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
    glBindTexture(GL_TEXTURE_1D, 0+1);
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    CreatePowMap(1.0, 1.0, 1.0);
    glEnable(GL_TEXTURE_1D);

    if (lowLevelAvailable)
    {
        glGenProgramsARB(TOTAL_SHADERS, ids);
        // Low-level will always be enabled, but high-level 
        // will take precedence if they're both enabled
        glEnable(GL_VERTEX_PROGRAM_ARB);
    }

    // Load and compile low- and high-level shaders
    for (i = 0; i < TOTAL_SHADERS; i++)
    {
        PrepareShader(i);
    }

    // Install first shader
    if (lowLevelAvailable)
    {
        glBindProgramARB(GL_VERTEX_PROGRAM_ARB, ids[0]);
    }
    if (useHighLevel)
    {
        glUseProgramObjectARB(progObj[0]);
    }
}