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(); }
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); } }
///////////////////////////////////////////////////////////// // 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; }
///////////////////////////////////////////////////////////////////////////// // 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; }
/////////////////////////////////////////////////////////////////////////////// // 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(); }
// 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); }
// 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]); } }