void WINDOW::Shutdown(void) //PROPERLY KILL WINDOW { //Delete font display lists glDeleteLists(base, 96); if (fullscreen) { ChangeDisplaySettings(NULL, 0); //restore desktop mode ShowCursor(TRUE); //show mouse cursor } errorLog.OutputNewline(); if(hRC) //have a rendering context? { if(!wglMakeCurrent(NULL, NULL)) //try to release rend cont { errorLog.OutputError("Release of DC and RC Failed."); } else errorLog.OutputSuccess("DC and RC released."); if(!wglDeleteContext(hRC)) //try to delete RC { errorLog.OutputError("Release Rendering Context Failed."); } else errorLog.OutputSuccess("Rendering Context Released."); hRC=NULL; //set RC to NULL } if(hDC && !ReleaseDC(hWnd, hDC)) //Are we able to release DC? { errorLog.OutputError("Release of Device Context Failed."); hDC=NULL; } else errorLog.OutputSuccess("Device Context Released."); if(hWnd && !DestroyWindow(hWnd)) //Can we destroy window? { errorLog.OutputError("Could not release hWnd"); hWnd=NULL; } else errorLog.OutputSuccess("hWnd released."); if (!UnregisterClass("OpenGL", hInstance)) //can we unreg. class? { errorLog.OutputError("Could Not Unregister Class."); hInstance=NULL; } else errorLog.OutputSuccess("Class unregistered."); }
//ENTRY POINT FOR APPLICATION //CALL WINDOW CREATION ROUTINE, DEAL WITH MESSAGES, WATCH FOR INTERACTION int WINAPI WinMain( HINSTANCE hInstance, //instance HINSTANCE hPrevInstance, //Previous Instance LPSTR lpCmdLine, //command line parameters int nCmdShow) //Window show state { //Initiation errorLog.Init("Error Log.txt"); //init variables etc, then GL if(!DemoInit()) { errorLog.OutputError("Demo Initiation failed"); return 0; } else errorLog.OutputSuccess("Demo Initiation Successful"); if(!GLInit()) { errorLog.OutputError("OpenGL Initiation failed"); return 0; } else errorLog.OutputSuccess("OpenGL Initiation Successful"); //Main Loop for(;;) { if(!(window.HandleMessages())) break;//handle windows messages, quit if returns false UpdateFrame(); RenderFrame(); } DemoShutdown(); errorLog.OutputSuccess("Exiting..."); return (window.msg.wParam); //Exit The Program }
bool LoadNV_vertex_program(char * filename, GLuint programID) { //load from file std::ifstream vpFile(filename, std::ios::in | std::ios::binary); if(vpFile.fail()) { printf("Unable to open vertex program\n"); return false; } //calculate the size of the file vpFile.seekg(0, std::ios::end); int vpSize=vpFile.tellg(); vpFile.seekg(0, std::ios::beg); //allocate memory unsigned char * vpText=new unsigned char[vpSize]; if(!vpText) { printf("Unable to allocate space for vertex program text\n"); return false; } //read file vpFile.read(reinterpret_cast<char *>(vpText), vpSize); vpFile.close(); //load program glLoadProgramNV(GL_VERTEX_PROGRAM_NV, programID, vpSize, vpText); if(vpText) delete [] vpText; vpText=NULL; //Output if there was an error int errorPos; glGetIntegerv(GL_PROGRAM_ERROR_POSITION_NV, &errorPos); if(errorPos!=-1) { errorLog.OutputError("Program error at position %d in %s\n", errorPos, filename); return false; } else errorLog.OutputSuccess("%s loaded correctly", filename); return true; }
bool SetUpEXT_texture_edge_clamp() { //Check for support char * extensionString=(char *)glGetString(GL_EXTENSIONS); char * extensionName="GL_EXT_texture_edge_clamp"; char * endOfString; //store pointer to end of string unsigned int distanceToSpace; //distance to next space endOfString=extensionString+strlen(extensionString); //loop through string while(extensionString<endOfString) { //find distance to next space distanceToSpace=strcspn(extensionString, " "); //see if we have found extensionName if((strlen(extensionName)==distanceToSpace) && (strncmp(extensionName, extensionString, distanceToSpace)==0)) { EXT_texture_edge_clamp_supported=true; } //if not, move on extensionString+=distanceToSpace+1; } if(!EXT_texture_edge_clamp_supported) { errorLog.OutputError("EXT_texture_edge_clamp unsupported!"); return false; } errorLog.OutputSuccess("EXT_texture_edge_clamp supported!"); //get function pointers //none specified return true; }
//Set up variables bool DemoInit() { if(!window.Init("Project Template", 640, 480, 32, 24, 8, WINDOWED_SCREEN)) return 0; //quit if not created SetUpARB_multitexture(); SetUpARB_texture_cube_map(); SetUpEXT_texture_edge_clamp(); SetUpNV_register_combiners(); SetUpNV_register_combiners2(); SetUpNV_vertex_program(); //Check for necessary extensions if( !ARB_multitexture_supported || !ARB_texture_cube_map_supported || !EXT_texture_edge_clamp_supported || !NV_register_combiners_supported || !NV_vertex_program_supported) return false; //Check for single-pass chromatic aberration states GLint maxTextureUnits; glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits); if( NV_register_combiners2_supported && maxTextureUnits>=4) { errorLog.OutputSuccess("Single Pass Chromatic Aberration Supported!"); pathOneSupported=true; renderPath=CHROMATIC_SINGLE; } camera.Init(VECTOR3D(0.0f, 0.0f, 4.0f), 2.5f, 10.0f); if( !cubeMapPosX.Load("cube_face_posx.tga") || !cubeMapNegX.Load("cube_face_negx.tga") || !cubeMapPosY.Load("cube_face_posy.tga") || !cubeMapNegY.Load("cube_face_negy.tga") || !cubeMapPosZ.Load("cube_face_posz.tga") || !cubeMapNegZ.Load("cube_face_negz.tga")) return false; //Build a texture from the data glGenTextures(1, &cubeMapTexture); //Generate Texture ID glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, cubeMapTexture); //Bind texture glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, GL_RGBA8, cubeMapPosX.width, cubeMapPosX.height, 0, cubeMapPosX.format, GL_UNSIGNED_BYTE, cubeMapPosX.data); glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, 0, GL_RGBA8, cubeMapNegX.width, cubeMapNegX.height, 0, cubeMapNegX.format, GL_UNSIGNED_BYTE, cubeMapNegX.data); glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, 0, GL_RGBA8, cubeMapPosY.width, cubeMapPosY.height, 0, cubeMapPosY.format, GL_UNSIGNED_BYTE, cubeMapPosY.data); glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, 0, GL_RGBA8, cubeMapNegY.width, cubeMapNegY.height, 0, cubeMapNegY.format, GL_UNSIGNED_BYTE, cubeMapNegY.data); glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, 0, GL_RGBA8, cubeMapPosZ.width, cubeMapPosZ.height, 0, cubeMapPosZ.format, GL_UNSIGNED_BYTE, cubeMapPosZ.data); glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, 0, GL_RGBA8, cubeMapNegZ.width, cubeMapNegZ.height, 0, cubeMapNegZ.format, GL_UNSIGNED_BYTE, cubeMapNegZ.data); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); //reset timer for start timer.Reset(); return true; }
//Load8BitBMP - load an 8 bit paletted bitmap file bool IMAGE::Load8BitBMP(char * filename) { errorLog.OutputSuccess("Loading %s in Load8bitBMP()", filename); //set bpp and format bpp=24; //after conversion format=GL_RGB; FILE * file; //the texture file BITMAPFILEHEADER fileHeader; //bitmap file header BITMAPINFOHEADER infoHeader; //bitmap info header //open file for reading file=fopen(filename, "rb"); if(file==NULL) { errorLog.OutputError("Unable to open %s", filename); return false; } //read the file header fread(&fileHeader, sizeof(BITMAPFILEHEADER), 1, file); //check it's a bitmap if(fileHeader.bfType != BITMAP_ID) { fclose(file); errorLog.OutputError("%s is not a legal .BMP", filename); return false; } //read in the information header fread(&infoHeader, sizeof(BITMAPINFOHEADER), 1, file); //set size width=infoHeader.biWidth; height=infoHeader.biHeight; //make space for palette unsigned char * palette=new unsigned char[256*4]; if(!palette) { errorLog.OutputError("Unable to alllocate memory for palette"); return false; } //load the palette fread(palette, 256*4, 1, file); //point file to the beginning of the data fseek(file, fileHeader.bfOffBits, SEEK_SET); //calculate the stride in bytes between one row and the next unsigned int stride=width; if(width%4 != 0) stride+=4-width%4; //allocate space for color indices unsigned char * indices=new unsigned char[stride*height]; if(!indices) { errorLog.OutputError("Unable to allocate memory for indices"); return false; } //load indices fread(indices, 1, stride*height, file); //close the file fclose(file); //allocate space for the image data data=new unsigned char[stride*height*bpp/8]; if(!data) { fclose(file); errorLog.OutputError("Unable to allocate memory for %s", filename); return false; } //calculate the color values - keeping the padding colors for(unsigned int currentRow=0; currentRow<height; currentRow++) { for(unsigned int i=0; i<stride; i++) { data[(currentRow*stride+i)*3+0]=palette[indices[currentRow*stride+i]*4+2]; data[(currentRow*stride+i)*3+1]=palette[indices[currentRow*stride+i]*4+1]; data[(currentRow*stride+i)*3+2]=palette[indices[currentRow*stride+i]*4+0];//BGR } } errorLog.OutputSuccess("Loaded %s correctly.", filename); return true; }
//load in an 8 bit greyscale TGA as an alpha channel bool IMAGE::LoadAlphaTGA(char * filename) { unsigned char TGAHeader[12]={0, 1, 1, 0, 0, 0, 1, 24, 0, 0, 0, 0}; unsigned char TGAcompare[12]; //Used to compare TGA header unsigned char header[6]; //First 6 useful bytes of the header errorLog.OutputSuccess("Loading %s in LoadAlphaTGA()", filename); if(!(format==GL_RGB || format==GL_RGBA)) { errorLog.OutputError("Can only load an alpha channel to RGB / RGBA format images. %s caused error", filename); return false; } FILE * file = fopen(filename, "rb"); //Open the TGA file if(file == NULL) //Does the file exist? { errorLog.OutputError("%s does not exist.", filename); return false; } if( fread(TGAcompare, 1, sizeof(TGAcompare), file)!=sizeof(TGAcompare)|| //Are there 12 bytes to read? memcmp(TGAHeader, TGAcompare, sizeof(TGAHeader))!=0 || //Is the header correct? fread(header, 1, sizeof(header), file)!=sizeof(header)) //Read next 6 bytes { fclose(file); //If anything else failed, close the file errorLog.OutputError("Could not load %s correctly, general failure.", filename); return false; } //save data into class member variables unsigned int alphaWidth= header[1]*256+header[0]; //determine the image width unsigned int alphaHeight= header[3]*256+header[2]; //determine image height int alphaBpp= header[4]; if( alphaWidth<=0 || //if width <=0 alphaHeight<=0 || //or height<=0 alphaBpp!=8) //bpp not 8 { fclose(file); //close the file errorLog.OutputError("%s's height or width is less than zero, or the TGA is not 8 bpp.", filename); return false; } //check it is the same size as the image if(alphaWidth!=width || alphaHeight!=height) { errorLog.OutputError("%s is not the same size as the color texture", filename); return false; } //make space for palette unsigned char * palette=new unsigned char[256*3]; if(!palette) { errorLog.OutputError("Unable to allocate memory for palette"); return false; } //load the palette fread(palette, 256*3, 1, file); //we dont use the palette delete [] palette; palette=NULL; //allocate space for alpha values unsigned char * values=new unsigned char[width*height]; if(!values) { errorLog.OutputError("Unable to allocate memory for alpha values"); return false; } //load indices fread(values, 1, alphaWidth*alphaHeight, file); //close the file fclose(file); //now put in the alpha data if(format==GL_RGBA) { for(unsigned int i=0; i<width*height; i++) { data[i*4+3]=values[i]; } } else if(format==GL_RGB) { unsigned char * tempData=new unsigned char[width*height*4]; if(!tempData) { errorLog.OutputError("Unable to allocate memory for Temporary Data"); return false; } for(unsigned int i=0; i<width*height; i++) { tempData[i*4+0]=data[i*3+0]; tempData[i*4+1]=data[i*3+1]; tempData[i*4+2]=data[i*3+2]; tempData[i*4+3]=values[i]; } //update member variables bpp=32; format=GL_RGBA; if(data) delete [] data; data=tempData; } errorLog.OutputSuccess("Loaded %s correctly.", filename); return true; }
//Load24BitBMP - load a 24 bit bitmap file bool IMAGE::Load24BitBMP(char * filename) { errorLog.OutputSuccess("Loading %s in Load24bitBMP()", filename); //set bpp and format bpp=24; format=GL_RGB; FILE * file; //the texture file BITMAPFILEHEADER fileHeader; //bitmap file header BITMAPINFOHEADER infoHeader; //bitmap info header //open file for reading file=fopen(filename, "rb"); if(file==NULL) { errorLog.OutputError("Unable to open %s", filename); return false; } //read the file header fread(&fileHeader, sizeof(BITMAPFILEHEADER), 1, file); //check it's a bitmap if(fileHeader.bfType != BITMAP_ID) { fclose(file); errorLog.OutputError("%s is not a legal .BMP", filename); return false; } //read in the information header fread(&infoHeader, sizeof(BITMAPINFOHEADER), 1, file); //set size width=infoHeader.biWidth; height=infoHeader.biHeight; //calculate the stride in bytes: width*bpp/8 plus padding bytes at the end of each row unsigned int stride=width*bpp/8; if(width%4==1) stride+=1; if(width%4==2) stride+=2; if(width%4==3) stride+=3; //point file to the beginning of the data fseek(file, fileHeader.bfOffBits, SEEK_SET); //allocate space for the image data data=new unsigned char[stride*height]; if(!data) { fclose(file); errorLog.OutputError("Unable to allocate memory for %s", filename); return false; } //read in the data fread(data, 1, stride*height, file); //close the file fclose(file); //data is in BGR format //swap b and r for(unsigned int row=0; row<height; row++) { for(unsigned int i=0; i<width*3; i+=bpp/8) { //repeated XOR to swap bytes 0 and 2 data[(row*stride)+i] ^= data[(row*stride)+i+2] ^= data[(row*stride)+i] ^= data[(row*stride)+i+2]; } } errorLog.OutputSuccess("Loaded %s correctly.", filename); return true; }
//load an uncompressed TGA texture (24 or 32 bpp) bool IMAGE::LoadUncompressedTrueColorTGA(char * filename) { unsigned char TGAheader[12]={0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //Uncompressed TGA header unsigned char TGAcompare[12]; //Used to compare TGA header unsigned char header[6]; //First 6 useful bytes of the header unsigned int bytesPerPixel; //bytes per pixel unsigned int imageSize; //Stores Image size when in RAM errorLog.OutputSuccess("Loading %s in LoadUncompressedTGA()", filename); FILE * file = fopen(filename, "rb"); //Open the TGA file if(file == NULL) //Does the file exist? { errorLog.OutputError("%s does not exist.", filename); return false; } if( fread(TGAcompare, 1, sizeof(TGAcompare), file)!=sizeof(TGAcompare)|| //Are there 12 bytes to read? memcmp(TGAheader, TGAcompare, sizeof(TGAheader))!=0 || //Is the header correct? fread(header, 1, sizeof(header), file)!=sizeof(header)) //Read next 6 bytes { fclose(file); //If anything else failed, close the file errorLog.OutputError("Could not load %s correctly, general failure.", filename); return false; } //save data into class member variables width= header[1]*256+header[0]; //determine the image width height= header[3]*256+header[2]; //determine image height bpp= header[4]; if( width<=0 || //if width <=0 height<=0 || //or height<=0 bpp!=24 && bpp!=32) //bpp not 24 or 32 { fclose(file); //close the file errorLog.OutputError("%s's height or width is less than zero, or the TGA is not 24 or 32 bpp.", filename); return false; } //set format if(bpp == 24) format=GL_RGB; else format=GL_RGBA; bytesPerPixel=bpp/8; //calc bytes per pixel imageSize=width*height*bytesPerPixel; //calc memory required data=new unsigned char[imageSize]; //reserve the memory for the data if( data==NULL) //Does the storage memory exist? { errorLog.OutputError("Unable to allocate memory for %s image", filename); fclose(file); return false; } //read in the image data if(fread(data, 1, imageSize, file)!=imageSize) //Does the image size match the required? { //If not if(data) //If data loaded delete [] data; //free memory errorLog.OutputError("Could not read %s image data", filename); fclose(file); //close file return false; } fclose(file); //data is in BGR format //swap b and r for(int i=0; i<(int)imageSize; i+=bytesPerPixel) { //repeated XOR to swap bytes 0 and 2 data[i] ^= data[i+2] ^= data[i] ^= data[i+2]; } errorLog.OutputSuccess("Loaded %s correctly.", filename); return true; }
//load a compressed TGA texture (24 or 32 bpp) bool IMAGE::LoadCompressedTrueColorTGA(char * filename) { unsigned char TGAheader[12]={0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //Compressed TGA header unsigned char TGAcompare[12]; //Used to compare TGA header unsigned char header[6]; //First 6 useful bytes of the header unsigned int bytesPerPixel; //bytes per pixel unsigned int imageSize; //Stores Image size when in RAM errorLog.OutputSuccess("Loading %s in LoadCompressedTGA()", filename); FILE * file = fopen(filename, "rb"); //Open the TGA file if(file == NULL) //Does the file exist? { errorLog.OutputError("%s does not exist.", filename); return false; } if( fread(TGAcompare, 1, sizeof(TGAcompare), file)!=sizeof(TGAcompare)|| //Are there 12 bytes to read? memcmp(TGAheader, TGAcompare, sizeof(TGAheader))!=0 || //Is the header correct? fread(header, 1, sizeof(header), file)!=sizeof(header)) //Read next 6 bytes { fclose(file); //If anything else failed, close the file errorLog.OutputError("Could not load %s correctly, general failure.", filename); return false; } //save data into class member variables width= header[1]*256+header[0]; //determine the image width height= header[3]*256+header[2]; //determine image height bpp= header[4]; if( width<=0 || //if width <=0 height<=0 || //or height<=0 bpp!=24 && bpp!=32) //bpp not 24 or 32 { fclose(file); //close the file errorLog.OutputError("%s's height or width is less than zero, or the TGA is not 24 or 32 bpp.", filename); return false; } //set format if(bpp == 24) format=GL_RGB; else format=GL_RGBA; bytesPerPixel=bpp/8; //calc bytes per pixel imageSize=width*height*bytesPerPixel; //calc memory required data=new unsigned char[imageSize]; //reserve the memory for the data if(!data) //Does the storage memory exist? { errorLog.OutputError("Unable to allocate memory for %s image", filename); fclose(file); return false; } //read in the image data int pixelCount = height*width; int currentPixel= 0; int currentByte = 0; unsigned char * colorBuffer=new unsigned char[bytesPerPixel]; do { unsigned char chunkHeader=0; if(fread(&chunkHeader, sizeof(unsigned char), 1, file) == 0) { errorLog.OutputError("Could not read RLE chunk header"); if(file) fclose(file); if(data) delete [] data; return false; } if(chunkHeader<128) //Read raw color values { chunkHeader++; for(short counter=0; counter<chunkHeader; counter++) { if(fread(colorBuffer, 1, bytesPerPixel, file) != bytesPerPixel) { errorLog.OutputError("Unable to read %s image data", filename); if(file) fclose(file); if(colorBuffer) delete [] colorBuffer; if(data) delete [] data; return false; } //transfer pixel color to data (swapping r and b values) data[currentByte] = colorBuffer[2]; data[currentByte+1] = colorBuffer[1]; data[currentByte+2] = colorBuffer[0]; if(bytesPerPixel==4) data[currentByte+3]=colorBuffer[3]; currentByte+=bytesPerPixel; currentPixel++; if(currentPixel > pixelCount) { errorLog.OutputError("Too many pixels read"); if(file) fclose(file); if(colorBuffer) delete [] colorBuffer; if(data) delete [] data; return false; } } } else //chunkHeader>=128 { chunkHeader-=127; if(fread(colorBuffer, 1, bytesPerPixel, file) != bytesPerPixel) { errorLog.OutputError("Unable to read %s image data", filename); if(file) fclose(file); if(colorBuffer) delete [] colorBuffer; if(data) delete [] data; return false; } for(short counter=0; counter<chunkHeader; counter++) { //transfer pixel color to data (swapping r and b values) data[currentByte] = colorBuffer[2]; data[currentByte+1] = colorBuffer[1]; data[currentByte+2] = colorBuffer[0]; if(bytesPerPixel==4) data[currentByte+3]=colorBuffer[3]; currentByte+=bytesPerPixel; currentPixel++; if(currentPixel > pixelCount) { errorLog.OutputError("Too many pixels read"); if(file) fclose(file); if(colorBuffer) delete [] colorBuffer; if(data) delete [] data; return false; } } } }while(currentPixel<pixelCount); fclose(file); errorLog.OutputSuccess("Loaded %s correctly.", filename); return true; }
//LoadPCX - load a .pcx texture - 256 color, paletted bool IMAGE::LoadPCX(char * filename) { errorLog.OutputSuccess("Loading %s in LoadPCX()", filename); //set bpp and format bpp=24; format=GL_RGB; FILE * file; file=fopen(filename, "rb"); if(!file) { errorLog.OutputError("Unable to open %s", filename); return false; } //retrieve header, first 4 bytes, first 2 should be 0x0A0C unsigned short header[2]; fread(header, 4, 1, file); if(header[0]!=0x050A) { errorLog.OutputError("%s is not a legal .PCX file", filename); fclose(file); return false; } //retrieve minimum x value int xMin=fgetc(file); //loword xMin |= fgetc(file) << 8; //hiword //retrieve minimum y value int yMin=fgetc(file); //loword yMin |= fgetc(file) << 8; //hiword //retrieve maximum x value int xMax=fgetc(file); //loword xMax |= fgetc(file) << 8; //hiword //retrieve maximum y value int yMax=fgetc(file); //loword yMax |= fgetc(file) << 8; //hiword //calculate width and height width = xMax-xMin+1; height= yMax-yMin+1; //allocate memory for pixel data (paletted) unsigned char * pixelData=new unsigned char[width*height]; if(!pixelData) { errorLog.OutputError("Unable to allocate %d bytes for the image data of %s", width*height, filename); fclose(file); return false; } //set file pointer to beginning of image data fseek(file, 128, SEEK_SET); //decode and store the pixel data unsigned int index=0; while(index<(width*height)) { int c = getc(file); if(c>0xBF) { int numRepeat = 0x3F & c; c=getc(file); for(int i=0; i<numRepeat; i++) pixelData[index++] = c; } else pixelData[index++] = c; fflush(stdout); } //allocate memory for the image palette unsigned char * paletteData = new unsigned char[768]; //the palette is the last 769 bytes of the file fseek(file, -769, SEEK_END); //retrieve first character, should be equal to 12 int c=getc(file); if(c!=12) { errorLog.OutputError("%s is not a legal .PCX file - the palette data has an illegal header, %d", filename, c); fclose(file); return false; } //read and store the palette fread(paletteData, 1, 768, file); //close the file fclose(file); //allocate memory for the "unpaletted" data data = new unsigned char[width*height*3]; if(!data) { errorLog.OutputError("Unable to allocate memory for the expanded data of %s", filename); return false; } //calculate the "unpaletted" data - "flipping" the texture top-bottom for(unsigned int j=0; j<height; j++) { for(unsigned int i=0; i<width; i++) { data[3*(j*width+i)] = (unsigned char) paletteData[3*pixelData[(height-1-j)*width+i]]; data[3*(j*width+i)+1] = (unsigned char) paletteData[3*pixelData[(height-1-j)*width+i]+1]; data[3*(j*width+i)+2] = (unsigned char) paletteData[3*pixelData[(height-1-j)*width+i]+2]; } } errorLog.OutputSuccess("Loaded %s correctly.", filename); return true; }
//load an 8 bit uncompressed paletted TGA bool IMAGE::LoadUncompressed8BitTGA(char * filename) { unsigned char TGAHeader[12]={0, 1, 1, 0, 0, 0, 1, 24, 0, 0, 0, 0}; unsigned char TGAcompare[12]; //Used to compare TGA header unsigned char header[6]; //First 6 useful bytes of the header errorLog.OutputSuccess("Loading %s in LoadUncompressed8BitTGA()", filename); FILE * file = fopen(filename, "rb"); //Open the TGA file if(file == NULL) //Does the file exist? { errorLog.OutputError("%s does not exist.", filename); return false; } if( fread(TGAcompare, 1, sizeof(TGAcompare), file)!=sizeof(TGAcompare)|| //Are there 12 bytes to read? memcmp(TGAHeader, TGAcompare, sizeof(TGAHeader))!=0 || //Is the header correct? fread(header, 1, sizeof(header), file)!=sizeof(header)) //Read next 6 bytes { fclose(file); //If anything else failed, close the file errorLog.OutputError("Could not load %s correctly, general failure.", filename); return false; } //save data into class member variables width= header[1]*256+header[0]; //determine the image width height= header[3]*256+header[2]; //determine image height bpp= header[4]; if( width<=0 || //if width <=0 height<=0 || //or height<=0 bpp!=8) //bpp not 8 { fclose(file); //close the file errorLog.OutputError("%s's height or width is less than zero, or the TGA is not 8 bpp.", filename); return false; } //set format format=GL_RGB; //make space for palette unsigned char * palette=new unsigned char[256*3]; if(!palette) { errorLog.OutputError("Unable to allocate memory for palette"); return false; } //load the palette fread(palette, 256*3, 1, file); //allocate space for color indices unsigned char * indices=new unsigned char[width*height]; if(!indices) { errorLog.OutputError("Unable to allocate memory for indices"); return false; } //load indices fread(indices, 1, width*height, file); //close the file fclose(file); //allocate space for the image data data=new unsigned char[width*height*3]; if(!data) { fclose(file); errorLog.OutputError("Unable to allocate memory for %s", filename); return false; } //calculate the color values for(unsigned int currentRow=0; currentRow<height; currentRow++) { for(unsigned int i=0; i<width; i++) { data[(currentRow*width+i)*3+0]=palette[indices[currentRow*width+i]*3+2]; data[(currentRow*width+i)*3+1]=palette[indices[currentRow*width+i]*3+1]; data[(currentRow*width+i)*3+2]=palette[indices[currentRow*width+i]*3+0];//BGR } } errorLog.OutputSuccess("Loaded %s correctly.", filename); return true; }
bool WINDOW::Init(char * windowTitle, int newWidth, int newHeight, int newColorBits, int newDepthBits, int newStencilBits, int fullscreenflag) //CREATE WINDOW { WNDCLASS wc; //windows class structure DWORD dwExStyle; //extended style info. DWORD dwStyle; //style info //set class's member variables title=windowTitle; width=newWidth; height=newHeight; colorBits=newColorBits; depthBits=newDepthBits; stencilBits=newStencilBits; //set class's fullscreen flag if(fullscreenflag == FULL_SCREEN) { fullscreen=true; } if(fullscreenflag == WINDOWED_SCREEN) { fullscreen=false; } if(fullscreenflag == CHOOSE_SCREEN) //Ask user if fullscreen { if(MessageBox(NULL,"Would You Like To Run In Fullscreen Mode?","Start FullScreen",MB_YESNO|MB_ICONQUESTION)==IDNO) { fullscreen=false; //If answered no } else { fullscreen=true; //if answered yes } } RECT WindowRect; //grab rect. upper left/lower right values WindowRect.left=(long)0; WindowRect.right=(long)width; WindowRect.top=(long)0; WindowRect.bottom=(long)height; hInstance= GetModuleHandle(NULL); //Grab an instance for window wc.style= CS_HREDRAW | CS_VREDRAW | CS_OWNDC; //window style: redraw on move, own DC wc.lpfnWndProc= (WNDPROC) WndProc; //Wndproc handles messages wc.cbClsExtra= 0; wc.cbWndExtra= 0; //no extra window data wc.hInstance= hInstance; //Set the instance wc.hIcon= LoadIcon(NULL, IDI_WINLOGO); //load default icon wc.hCursor= LoadCursor(NULL, IDC_ARROW); //Load arrow cursor wc.hbrBackground=NULL; //No background rqd for GL wc.lpszMenuName=NULL; //No menu wc.lpszClassName="OpenGL"; //set class name if(!RegisterClass(&wc)) //try to register class { errorLog.OutputError("Failed to register the window class"); return FALSE; } else errorLog.OutputSuccess("Window Class Registered"); if(fullscreen) //try to set up fullscreen? { DEVMODE dmScreenSettings; //Device mode memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); //clear memory dmScreenSettings.dmSize=sizeof(dmScreenSettings); //size of devmode structure dmScreenSettings.dmPelsWidth=width; //selected width dmScreenSettings.dmPelsHeight=height; //selected height dmScreenSettings.dmBitsPerPel=colorBits; //selected bpp dmScreenSettings.dmFields=DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; if(ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) //try to set mode.CDS_FULLSCREEN removes start bar { //If mode fails, give 2 options, quit or run in window if(MessageBox(NULL, "The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?",title, MB_YESNO|MB_ICONEXCLAMATION)==IDYES) { fullscreen=FALSE; //if "yes", try windowed } else { //tell user program is closing errorLog.OutputError("Program Closed, As Fullscreen Mode Not Supported."); return FALSE; //exit and return FALSE } } } if (fullscreen) //still fullscreen? { dwExStyle=WS_EX_APPWINDOW; //window extended style dwStyle=WS_POPUP | WS_VISIBLE; //window style (no border), visible ShowCursor(FALSE); //hide mouse pointer } else { dwExStyle=WS_EX_CLIENTEDGE; //window extended style(3d look) dwStyle=WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_VISIBLE; //window style (close button, title bar, border, visible) } AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); //adjust window to actual requested size, rather than including borders in size. in fullscreen, no effect if(!(hWnd=CreateWindowEx( dwExStyle, //extended style for window "OpenGL", //class name title, //window title WS_CLIPSIBLINGS | //required style WS_CLIPCHILDREN | //required style dwStyle, //Selected style 0, 0, //window position WindowRect.right-WindowRect.left, //calculate adjusted width WindowRect.bottom-WindowRect.top, //calculate adjusted height NULL, // no parent window NULL, //No Menu hInstance, //Instance NULL))) //Dont pass anything to WM_CREATE { Shutdown(); //if not set up, reset display errorLog.OutputError("Window Creation Error."); //pop up error message return FALSE; //return false, to quit program } else errorLog.OutputSuccess("Window Created."); //set up pixel format(openGL supporting, RGBA, correct bits GLuint pixelFormat; //holds result after searching for mode match //calculate alpha bits int alphaBits=0; if(colorBits==32) alphaBits=8; static PIXELFORMATDESCRIPTOR pfd= //pfd tells windows how we want things to be { sizeof(PIXELFORMATDESCRIPTOR), //size of Pixel format descriptor 1, //Version Number PFD_DRAW_TO_WINDOW | //must support window PFD_SUPPORT_OPENGL | //must support opengl PFD_DOUBLEBUFFER, //must support double buffer PFD_TYPE_RGBA, //request RGBA format colorBits, //select colour depth 0, 0, 0, 0, 0, 0, //colour bits ignored alphaBits, //alpha buffer bits 0, //shift bit ignored 0, //no accumulation buffer 0, 0, 0, 0, //accumulation bits ignored depthBits, //z buffer bits stencilBits, //stencil buffer bits 0, //no auxiliary buffer PFD_MAIN_PLANE, //main drawing layer 0, //reserved 0, 0, 0 //layer masks ignored }; if(!(hDC=GetDC(hWnd))) //did we get a device context? { //if not Shutdown(); //Reset display errorLog.OutputError("Can't Create a GL Device context."); return FALSE; //return false, to exit } else errorLog.OutputSuccess("DC Created"); if(!(pixelFormat=ChoosePixelFormat(hDC,&pfd))) //found a matching pixel format? { //if not Shutdown(); errorLog.OutputError("Can't Find a Suitable PixelFormat."); return FALSE; } else errorLog.OutputSuccess("Pixel Format Found."); if(!SetPixelFormat(hDC, pixelFormat,&pfd)) //are we able to set pixel format? { //if not Shutdown(); errorLog.OutputError("Can't set the pixelformat."); return FALSE; } else errorLog.OutputSuccess("Pixel Format set."); if(!(hRC=wglCreateContext(hDC))) //are we able to get rendering context? { //if not Shutdown(); errorLog.OutputError("Can't create a GL rendering context."); return FALSE; } else errorLog.OutputSuccess("GL Rendering Context Created."); if(!MakeCurrent()) //are we able to activate rendering context? { //if not Shutdown(); return FALSE; } else errorLog.OutputSuccess("GL Rendering Context Activated."); //get pixel format parameters static PIXELFORMATDESCRIPTOR finalPfd; DescribePixelFormat(hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &finalPfd); //output window parameters errorLog.OutputNewline(); errorLog.OutputSuccess("Window Size: (%d, %d)", width, height); errorLog.OutputSuccess("Color Buffer Bits (R, G, B, A): (%d, %d, %d, %d)", finalPfd.cRedBits, finalPfd.cGreenBits, finalPfd.cBlueBits, finalPfd.cAlphaBits); errorLog.OutputSuccess("Depth Buffer Bits: %d", finalPfd.cDepthBits); errorLog.OutputSuccess("Stencil Buffer Bits: %d", finalPfd.cStencilBits); errorLog.OutputNewline(); ShowWindow(hWnd,SW_SHOW); //show window SetForegroundWindow(hWnd); //slightly higher priority SetFocus(hWnd); //Set keyboard focus to the window errorLog.OutputSuccess("Window Created!"); errorLog.OutputNewline(); //Init the font HFONT font; //windows font ID //create 96 display lists base = glGenLists(96); font = CreateFont( -18, //font height 0, //default width 0, 0, //angles - escapement, orientation FW_BOLD, //font weight, 0-1000, NORMAL, BOLD false, //italic false, //underline false, //strikeout ANSI_CHARSET, //character set OUT_TT_PRECIS, //precision CLIP_DEFAULT_PRECIS, //clip precision ANTIALIASED_QUALITY, //output quality FF_DONTCARE | DEFAULT_PITCH,//family and pitch "Courier New"); //font name //select the font SelectObject(hDC, font); //create 96 display lists, starting at 32 wglUseFontBitmaps(hDC, 32, 96, base); errorLog.OutputSuccess("Font created successfully."); return TRUE; //success! }
////////////////////BSP::Load/////////////// //////////////////////////////////////////// bool BSP::Load(char * filename, int curveTesselation) { FILE * file; file=fopen(filename, "rb"); if(!file) { errorLog.OutputError("Unable to open %s", filename); return false; } //read in header fread(&header, sizeof(BSP_HEADER), 1, file); //check header data is correct if( header.string[0]!='I' || header.string[1]!='B' || header.string[2]!='S' || header.string[3]!='P' || header.version !=0x2E ) { errorLog.OutputError("%s is not a version 0x2E .bsp map file", filename); return false; } //Load in vertices if(!LoadVertices(file)) return false; //Load in mesh indices //Calculate number of indices int numMeshIndices=header.directoryEntries[bspMeshIndices].length/sizeof(int); //Create space meshIndices=new int[numMeshIndices]; if(!meshIndices) { errorLog.OutputError("Unable to allocate memory for %d mesh indices", numMeshIndices); return false; } //read in the mesh indices fseek(file, header.directoryEntries[bspMeshIndices].offset, SEEK_SET); fread(meshIndices, header.directoryEntries[bspMeshIndices].length, 1, file); //Load in faces if(!LoadFaces(file, curveTesselation)) return false; //Load textures if(!LoadTextures(file)) return false; //Load Lightmaps if(!LoadLightmaps(file)) return false; //Load BSP Data if(!LoadBSPData(file)) return false; //Load in entity string entityString=new char[header.directoryEntries[bspEntities].length]; if(!entityString) { errorLog.OutputError( "Unable to allocate memory for %d length entity string", header.directoryEntries[bspEntities].length); return false; } //Go to entity string in file fseek(file, header.directoryEntries[bspEntities].offset, SEEK_SET); fread(entityString, 1, header.directoryEntries[bspEntities].length, file); //Output the entity string //errorLog.OutputSuccess("Entity String: %s", entityString); fclose(file); errorLog.OutputSuccess("%s Loaded successfully", filename); return true; }
void WINDOW::SaveScreenshot(void) { FILE * file; //first calculate the filename to save to char filename[32]; for(int i=0; i<1000; i++) { sprintf(filename, "screen%03d.tga", i); //try opening this file - if not possible, use this filename file=fopen(filename, "rb"); if(!file) { break; } //otherwise, the file exists, try next, except if this is the last one fclose(file); if(i==999) { errorLog.OutputError("No space to save screenshot - 0-999 exist"); return; } } errorLog.OutputSuccess("Saving %s", filename); GLubyte TGAheader[12]={0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //Uncompressed TGA header GLubyte infoHeader[6]; unsigned char * data=new unsigned char[4*width*height]; if(!data) { errorLog.OutputError("Unable to allocate memory for screen data"); return; } //read in the screen data glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); //data needs to be in BGR format //swap b and r for(int i=0; i<(int)width*height*4; i+=4) { //repeated XOR to swap bytes 0 and 2 data[i] ^= data[i+2] ^= data[i] ^= data[i+2]; } //open the file file = fopen(filename, "wb"); //save header fwrite(TGAheader, 1, sizeof(TGAheader), file); //save info header infoHeader[0]=(width & 0x00FF); infoHeader[1]=(width & 0xFF00) >> 8; infoHeader[2]=(height & 0x00FF); infoHeader[3]=(height & 0xFF00) >> 8; infoHeader[4]=32; infoHeader[5]=0; //save info header fwrite(infoHeader, 1, sizeof(infoHeader), file); //save the image data fwrite(data, 1, width*height*4, file); fclose(file); errorLog.OutputSuccess("Saved Screenshot: %s", filename); return; }
bool PBUFFER::Init( int newWidth, int newHeight, int newColorBits, int newDepthBits, int newStencilBits, int numExtraIAttribs, int * extraIAttribList, int * flags) { //Check for pbuffer support if( !WGL_ARB_extensions_string_supported || !WGL_ARB_pixel_format_supported || !WGL_ARB_pbuffer_supported) { errorLog.OutputError("Extension required for pbuffer unsupported"); return false; } //set class's member variables width=newWidth; height=newHeight; colorBits=newColorBits; depthBits=newDepthBits; stencilBits=newStencilBits; //Get the current device context HDC hCurrentDC=wglGetCurrentDC(); if(!hCurrentDC) { errorLog.OutputError("Unable to get current Device Context"); return false; } //choose pixel format GLint pixelFormat; const int standardIAttribList[]={ WGL_DRAW_TO_PBUFFER_ARB, 1, WGL_COLOR_BITS_ARB, colorBits, WGL_ALPHA_BITS_ARB, colorBits==32 ? 8 : 0, WGL_DEPTH_BITS_ARB, depthBits, WGL_STENCIL_BITS_ARB, stencilBits}; const float fAttribList[]={ 0}; //add the extraIAttribList to the standardIAttribList int * iAttribList=new int[sizeof(standardIAttribList)/sizeof(int)+numExtraIAttribs*2+1]; if(!iAttribList) { errorLog.OutputError("Unable to allocate space for iAttribList"); return false; } memcpy( iAttribList, standardIAttribList, sizeof(standardIAttribList)); memcpy( iAttribList+sizeof(standardIAttribList)/sizeof(int), extraIAttribList, numExtraIAttribs*2*sizeof(int)+sizeof(int)); //Choose pixel format unsigned int numFormats; if(!wglChoosePixelFormatARB(hCurrentDC, iAttribList, fAttribList, 1, &pixelFormat, &numFormats)) { errorLog.OutputError("Unable to find a pixel format for the pbuffer"); return false; } //Create the pbuffer hBuffer=wglCreatePbufferARB(hCurrentDC, pixelFormat, width, height, flags); if(!hBuffer) { errorLog.OutputError("Unable to create pbuffer"); return false; } //Get the pbuffer's device context hDC=wglGetPbufferDCARB(hBuffer); if(!hDC) { errorLog.OutputError("Unable to get pbuffer's device context"); return false; } //Create a rendering context for the pbuffer hRC=wglCreateContext(hDC); if(!hRC) { errorLog.OutputError("Unable to create pbuffer's rendering context"); return false; } //Set and output the actual pBuffer dimensions wglQueryPbufferARB(hBuffer, WGL_PBUFFER_WIDTH_ARB, &width); wglQueryPbufferARB(hBuffer, WGL_PBUFFER_HEIGHT_ARB, &height); errorLog.OutputSuccess("Pbuffer Created: (%d x %d)", width, height); return TRUE; //success! }
bool SetUpNV_vertex_program() { //Check for support char * extensionString=(char *)glGetString(GL_EXTENSIONS); char * extensionName="GL_NV_vertex_program"; char * endOfString; //store pointer to end of string unsigned int distanceToSpace; //distance to next space endOfString=extensionString+strlen(extensionString); //loop through string while(extensionString<endOfString) { //find distance to next space distanceToSpace=strcspn(extensionString, " "); //see if we have found extensionName if((strlen(extensionName)==distanceToSpace) && (strncmp(extensionName, extensionString, distanceToSpace)==0)) { NV_vertex_program_supported=true; } //if not, move on extensionString+=distanceToSpace+1; } if(!NV_vertex_program_supported) { errorLog.OutputError("NV_vertex_program unsupported!"); return false; } errorLog.OutputSuccess("NV_vertex_program supported!"); //get function pointers glBindProgramNV = (PFNGLBINDPROGRAMNVPROC) wglGetProcAddress("glBindProgramNV"); glDeleteProgramsNV = (PFNGLDELETEPROGRAMSNVPROC) wglGetProcAddress("glDeleteProgramsNV"); glExecuteProgramNV = (PFNGLEXECUTEPROGRAMNVPROC) wglGetProcAddress("glExecuteProgramNV"); glGenProgramsNV = (PFNGLGENPROGRAMSNVPROC) wglGetProcAddress("glGenProgramsNV"); glAreProgramsResidentNV = (PFNGLAREPROGRAMSRESIDENTNVPROC) wglGetProcAddress("glAreProgramsResidentNV"); glRequestResidentProgramsNV = (PFNGLREQUESTRESIDENTPROGRAMSNVPROC) wglGetProcAddress("glRequestResidentProgramsNV"); glGetProgramParameterfvNV = (PFNGLGETPROGRAMPARAMETERFVNVPROC) wglGetProcAddress("glGetProgramParameterfvNV"); glGetProgramParameterdvNV = (PFNGLGETPROGRAMPARAMETERDVNVPROC) wglGetProcAddress("glGetProgramParameterdvNV"); glGetProgramivNV = (PFNGLGETPROGRAMIVNVPROC) wglGetProcAddress("glGetProgramivNV"); glGetProgramStringNV = (PFNGLGETPROGRAMSTRINGNVPROC) wglGetProcAddress("glGetProgramStringNV"); glGetTrackMatrixivNV = (PFNGLGETTRACKMATRIXIVNVPROC) wglGetProcAddress("glGetTrackMatrixivNV"); glGetVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) wglGetProcAddress("glGetVertexAttribdvNV"); glGetVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) wglGetProcAddress("glGetVertexAttribfvNV"); glGetVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC) wglGetProcAddress("glGetVertexAttribivNV"); glGetVertexAttribPointervNV = (PFNGLGETVERTEXATTRIBPOINTERVNVPROC) wglGetProcAddress("glGetVertexAttribPointervNV"); glIsProgramNV = (PFNGLISPROGRAMNVPROC) wglGetProcAddress("glIsProgramNV"); glLoadProgramNV = (PFNGLLOADPROGRAMNVPROC) wglGetProcAddress("glLoadProgramNV"); glProgramParameter4fNV = (PFNGLPROGRAMPARAMETER4FNVPROC) wglGetProcAddress("glProgramParameter4fNV"); glProgramParameter4dNV = (PFNGLPROGRAMPARAMETER4DNVPROC) wglGetProcAddress("glProgramParameter4dNV"); glProgramParameter4fvNV = (PFNGLPROGRAMPARAMETER4FVNVPROC) wglGetProcAddress("glProgramParameter4fvNV"); glProgramParameter4dvNV = (PFNGLPROGRAMPARAMETER4DVNVPROC) wglGetProcAddress("glProgramParameter4dvNV"); glProgramParameters4fvNV = (PFNGLPROGRAMPARAMETERS4FVNVPROC) wglGetProcAddress("glProgramParameters4fvNV"); glProgramParameters4dvNV = (PFNGLPROGRAMPARAMETERS4DVNVPROC) wglGetProcAddress("glProgramParameters4dvNV"); glTrackMatrixNV = (PFNGLTRACKMATRIXNVPROC) wglGetProcAddress("glTrackMatrixNV"); glVertexAttribPointerNV = (PFNGLVERTEXATTRIBPOINTERNVPROC) wglGetProcAddress("glVertexAttribPointerNV"); glVertexAttrib1sNV = (PFNGLVERTEXATTRIB1SNVPROC) wglGetProcAddress("glVertexAttrib1sNV"); glVertexAttrib1fNV = (PFNGLVERTEXATTRIB1FNVPROC) wglGetProcAddress("glVertexAttrib1fNV"); glVertexAttrib1dNV = (PFNGLVERTEXATTRIB1DNVPROC) wglGetProcAddress("glVertexAttrib1dNV"); glVertexAttrib2sNV = (PFNGLVERTEXATTRIB2SNVPROC) wglGetProcAddress("glVertexAttrib2sNV"); glVertexAttrib2fNV = (PFNGLVERTEXATTRIB2FNVPROC) wglGetProcAddress("glVertexAttrib2fNV"); glVertexAttrib2dNV = (PFNGLVERTEXATTRIB2DNVPROC) wglGetProcAddress("glVertexAttrib2dNV"); glVertexAttrib3sNV = (PFNGLVERTEXATTRIB3SNVPROC) wglGetProcAddress("glVertexAttrib3sNV"); glVertexAttrib3fNV = (PFNGLVERTEXATTRIB3FNVPROC) wglGetProcAddress("glVertexAttrib3fNV"); glVertexAttrib3dNV = (PFNGLVERTEXATTRIB3DNVPROC) wglGetProcAddress("glVertexAttrib3dNV"); glVertexAttrib4sNV = (PFNGLVERTEXATTRIB4SNVPROC) wglGetProcAddress("glVertexAttrib4sNV"); glVertexAttrib4fNV = (PFNGLVERTEXATTRIB4FNVPROC) wglGetProcAddress("glVertexAttrib4fNV"); glVertexAttrib4dNV = (PFNGLVERTEXATTRIB4DNVPROC) wglGetProcAddress("glVertexAttrib4dNV"); glVertexAttrib4ubNV = (PFNGLVERTEXATTRIB4UBNVPROC) wglGetProcAddress("glVertexAttrib4ubNV"); glVertexAttrib1svNV = (PFNGLVERTEXATTRIB1SVNVPROC) wglGetProcAddress("glVertexAttrib1svNV"); glVertexAttrib1fvNV = (PFNGLVERTEXATTRIB1FVNVPROC) wglGetProcAddress("glVertexAttrib1fvNV"); glVertexAttrib1dvNV = (PFNGLVERTEXATTRIB1DVNVPROC) wglGetProcAddress("glVertexAttrib1dvNV"); glVertexAttrib2svNV = (PFNGLVERTEXATTRIB2SVNVPROC) wglGetProcAddress("glVertexAttrib2svNV"); glVertexAttrib2fvNV = (PFNGLVERTEXATTRIB2FVNVPROC) wglGetProcAddress("glVertexAttrib2fvNV"); glVertexAttrib2dvNV = (PFNGLVERTEXATTRIB2DVNVPROC) wglGetProcAddress("glVertexAttrib2dvNV"); glVertexAttrib3svNV = (PFNGLVERTEXATTRIB3SVNVPROC) wglGetProcAddress("glVertexAttrib3svNV"); glVertexAttrib3fvNV = (PFNGLVERTEXATTRIB3FVNVPROC) wglGetProcAddress("glVertexAttrib3fvNV"); glVertexAttrib3dvNV = (PFNGLVERTEXATTRIB3DVNVPROC) wglGetProcAddress("glVertexAttrib3dvNV"); glVertexAttrib4svNV = (PFNGLVERTEXATTRIB4SVNVPROC) wglGetProcAddress("glVertexAttrib4svNV"); glVertexAttrib4fvNV = (PFNGLVERTEXATTRIB4FVNVPROC) wglGetProcAddress("glVertexAttrib4fvNV"); glVertexAttrib4dvNV = (PFNGLVERTEXATTRIB4DVNVPROC) wglGetProcAddress("glVertexAttrib4dvNV"); glVertexAttrib4ubvNV = (PFNGLVERTEXATTRIB4UBVNVPROC) wglGetProcAddress("glVertexAttrib4ubvNV"); glVertexAttribs1svNV = (PFNGLVERTEXATTRIBS1SVNVPROC) wglGetProcAddress("glVertexAttribs1svNV"); glVertexAttribs1fvNV = (PFNGLVERTEXATTRIBS1FVNVPROC) wglGetProcAddress("glVertexAttribs1fvNV"); glVertexAttribs1dvNV = (PFNGLVERTEXATTRIBS1DVNVPROC) wglGetProcAddress("glVertexAttribs1dvNV"); glVertexAttribs2svNV = (PFNGLVERTEXATTRIBS2SVNVPROC) wglGetProcAddress("glVertexAttribs2svNV"); glVertexAttribs2fvNV = (PFNGLVERTEXATTRIBS2FVNVPROC) wglGetProcAddress("glVertexAttribs2fvNV"); glVertexAttribs2dvNV = (PFNGLVERTEXATTRIBS2DVNVPROC) wglGetProcAddress("glVertexAttribs2dvNV"); glVertexAttribs3svNV = (PFNGLVERTEXATTRIBS3SVNVPROC) wglGetProcAddress("glVertexAttribs3svNV"); glVertexAttribs3fvNV = (PFNGLVERTEXATTRIBS3FVNVPROC) wglGetProcAddress("glVertexAttribs3fvNV"); glVertexAttribs3dvNV = (PFNGLVERTEXATTRIBS3DVNVPROC) wglGetProcAddress("glVertexAttribs3dvNV"); glVertexAttribs4svNV = (PFNGLVERTEXATTRIBS4SVNVPROC) wglGetProcAddress("glVertexAttribs4svNV"); glVertexAttribs4fvNV = (PFNGLVERTEXATTRIBS4FVNVPROC) wglGetProcAddress("glVertexAttribs4fvNV"); glVertexAttribs4dvNV = (PFNGLVERTEXATTRIBS4DVNVPROC) wglGetProcAddress("glVertexAttribs4dvNV"); glVertexAttribs4ubvNV = (PFNGLVERTEXATTRIBS4UBVNVPROC) wglGetProcAddress("glVertexAttribs4ubvNV"); return true; }