#define KPI 3.1415926 void Perspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); double xmin, xmax, ymin, ymax; ymax = zNear * tan(fovy * KPI / 360); ymin = -ymax; xmin = ymin * aspect; xmax = ymax * aspect; glFrustumf(xmin, xmax, ymin, ymax, zNear, zFar); glMatrixMode(GL_MODELVIEW); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glDepthMask(GL_TRUE); } void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx, GLfloat centery, GLfloat centerz, GLfloat upx, GLfloat upy, GLfloat upz) { GLfloat m[16]; GLfloat x[3], y[3], z[3]; GLfloat mag; /* Make rotation matrix */ /* Z vector */ z[0] = eyex - centerx; z[1] = eyey - centery; z[2] = eyez - centerz; mag = sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]); if (mag) { /* mpichler, 19950515 */ z[0] /= mag; z[1] /= mag; z[2] /= mag; } /* Y vector */ y[0] = upx; y[1] = upy; y[2] = upz; /* X vector = Y cross Z */ x[0] = y[1] * z[2] - y[2] * z[1]; x[1] = -y[0] * z[2] + y[2] * z[0]; x[2] = y[0] * z[1] - y[1] * z[0]; /* Recompute Y = Z cross X */ y[0] = z[1] * x[2] - z[2] * x[1]; y[1] = -z[0] * x[2] + z[2] * x[0]; y[2] = z[0] * x[1] - z[1] * x[0]; /* mpichler, 19950515 */ /* cross product gives area of parallelogram, which is < 1.0 for * non-perpendicular unit-length vectors; so normalize x, y here */ mag = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]); if (mag) { x[0] /= mag; x[1] /= mag; x[2] /= mag; } mag = sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]); if (mag) { y[0] /= mag; y[1] /= mag; y[2] /= mag; } #define M(row,col) m[col*4+row] M(0, 0) = x[0]; M(0, 1) = x[1]; M(0, 2) = x[2]; M(0, 3) = 0.0; M(1, 0) = y[0]; M(1, 1) = y[1]; M(1, 2) = y[2]; M(1, 3) = 0.0; M(2, 0) = z[0]; M(2, 1) = z[1]; M(2, 2) = z[2]; M(2, 3) = 0.0; M(3, 0) = 0.0; M(3, 1) = 0.0; M(3, 2) = 0.0; M(3, 3) = 1.0; #undef M glMultMatrixf(m); /* Translate Eye to Origin */ glTranslatef(-eyex, -eyey, -eyez); } unsigned char *loadBMP(char *filename, BITMAPINFOHEADER *bmpInfo) { FILE *file; BITMAPFILEHEADER bmpFile; unsigned char *bmpImage = NULL; unsigned char tmpRGB; file = fopen(filename,"rb"); if (!file) { ::MessageBox(NULL, L"Can't Find Bitmap", L"Error", MB_OK); return NULL; } fread(&bmpFile,sizeof(BITMAPFILEHEADER),1,file); if (bmpFile.bfType != 0x4D42) { ::MessageBox(NULL, L"Incorrect texture type", L"Error", MB_OK); fclose(file); return NULL; } fread(bmpInfo,sizeof(BITMAPINFOHEADER),1,file); fseek(file,bmpFile.bfOffBits,SEEK_SET); bmpImage = new unsigned char[bmpInfo->biSizeImage]; if (!bmpImage) { ::MessageBox(NULL, L"Out of Memory", L"Error", MB_OK); delete[] bmpImage; fclose(file); return NULL; } fread(bmpImage,1,bmpInfo->biSizeImage,file); if (!bmpImage) { ::MessageBox(NULL, L"Error reading bitmap", L"Error", MB_OK); fclose(file); return NULL; } for (unsigned int i = 0; i < bmpInfo->biSizeImage; i+=3) { tmpRGB = bmpImage[i]; bmpImage[i] = bmpImage[i+2]; bmpImage[i+2] = tmpRGB; } fclose(file); return bmpImage; } BOOL LoadTexture(char *filename, GLuint *id) { BITMAPINFOHEADER info; unsigned char *bitmap; bitmap = loadBMP(filename, &info); if (!bitmap) return false; glGenTextures(1, id); glBindTexture(GL_TEXTURE_2D, *id); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, info.biWidth, info.biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, bitmap); return TRUE; }