⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 constants.cpp

📁 S.C.O.U.R.G.E.是一款类似Rogue的游戏
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// This returns the cross product between 2 vectorsCVector3 Cross(CVector3 vVector1, CVector3 vVector2){    CVector3 vCross;                                // The vector to hold the cross product                                                // Get the X value    vCross.x = ((vVector1.y * vVector2.z) - (vVector1.z * vVector2.y));                                                // Get the Y value    vCross.y = ((vVector1.z * vVector2.x) - (vVector1.x * vVector2.z));                                                // Get the Z value    vCross.z = ((vVector1.x * vVector2.y) - (vVector1.y * vVector2.x));    return vCross;                              // Return the cross product}// This returns the normal of a vectorCVector3 Normalize(CVector3 vNormal){    double Magnitude;                           // This holds the magitude              Magnitude = Mag(vNormal);                   // Get the magnitude    vNormal.x /= (float)Magnitude;              // Divide the vector's X by the magnitude    vNormal.y /= (float)Magnitude;              // Divide the vector's Y by the magnitude    vNormal.z /= (float)Magnitude;              // Divide the vector's Z by the magnitude    return vNormal;                             // Return the normal}///////////////////////////////// COMPUTER NORMALS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*//////////   This function computes the normals and vertex normals of the objects////////////////////////////////////// COMPUTER NORMALS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*void ComputeNormals(t3DModel *pModel){    CVector3 vVector1, vVector2, vNormal, vPoly[3];    // If there are no objects, we can skip this part    if(pModel->numOfObjects <= 0)        return;    // What are vertex normals?  And how are they different from other normals?    // Well, if you find the normal to a triangle, you are finding a "Face Normal".    // If you give OpenGL a face normal for lighting, it will make your object look    // really flat and not very round.  If we find the normal for each vertex, it makes    // the smooth lighting look.  This also covers up blocky looking objects and they appear    // to have more polygons than they do.    Basically, what you do is first    // calculate the face normals, then you take the average of all the normals around each    // vertex.  It's just averaging.  That way you get a better approximation for that vertex.    // Go through each of the objects to calculate their normals    for(int index = 0; index < pModel->numOfObjects; index++)    {        // Get the current object        t3DObject *pObject = &(pModel->pObject[index]);        // Here we allocate all the memory we need to calculate the normals        CVector3 *pNormals      = new CVector3 [pObject->numOfFaces];        CVector3 *pTempNormals  = new CVector3 [pObject->numOfFaces];        pObject->pNormals       = new CVector3 [pObject->numOfVerts];		pObject->shadingColorDelta = new float [pObject->numOfVerts];        // Go though all of the faces of this object        for(int i=0; i < pObject->numOfFaces; i++)        {                                                           // To cut down LARGE code, we extract the 3 points of this face            vPoly[0] = pObject->pVerts[pObject->pFaces[i].vertIndex[0]];            vPoly[1] = pObject->pVerts[pObject->pFaces[i].vertIndex[1]];            vPoly[2] = pObject->pVerts[pObject->pFaces[i].vertIndex[2]];            // Now let's calculate the face normals (Get 2 vectors and find the cross product of those 2)            vVector1 = Vector(vPoly[0], vPoly[2]);      // Get the vector of the polygon (we just need 2 sides for the normal)            vVector2 = Vector(vPoly[2], vPoly[1]);      // Get a second vector of the polygon            vNormal  = Cross(vVector1, vVector2);       // Return the cross product of the 2 vectors (normalize vector, but not a unit vector)            pTempNormals[i] = vNormal;                  // Save the un-normalized normal for the vertex normals            vNormal  = Normalize(vNormal);              // Normalize the cross product to give us the polygons normal            pNormals[i] = vNormal;                      // Assign the normal to the list of normals        }        //////////////// Now Get The Vertex Normals /////////////////        CVector3 vSum = {0.0, 0.0, 0.0};        CVector3 vZero = vSum;        int shared=0;        for (int i = 0; i < pObject->numOfVerts; i++)           // Go through all of the vertices        {            for (int j = 0; j < pObject->numOfFaces; j++)   // Go through all of the triangles            {                                               // Check if the vertex is shared by another face                if (pObject->pFaces[j].vertIndex[0] == i ||                     pObject->pFaces[j].vertIndex[1] == i ||                     pObject->pFaces[j].vertIndex[2] == i)                {                    vSum = AddVector(vSum, pTempNormals[j]);// Add the un-normalized normal of the shared face                    shared++;                               // Increase the number of shared triangles                }            }                              // Get the normal by dividing the sum by the shared.  We negate the shared so it has the normals pointing out.            pObject->pNormals[i] = DivideVectorByScaler(vSum, float(-shared));            // Normalize the normal for the final vertex normal            pObject->pNormals[i] = Normalize(pObject->pNormals[i]);             vSum = vZero;                                   // Reset the sum            shared = 0;                                     // Reset the shared        }            // Free our memory and start over on the next object        delete [] pTempNormals;        delete [] pNormals;    }}///////////////////////////////////////      SWAP      \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*//////////  This swaps 2 elements we pass to it (swaps bytes)///////////////////////////////////////////       SWAP      \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*void swap(unsigned char & a, unsigned char & b) {    unsigned char temp;    temp = a;    a    = b;    b    = temp;    return;}/////////////////////////////////// CREATE TEXTURE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*//////////  This creates a texture in OpenGL that we can texture map//////////////////////////////////////// CREATE TEXTURE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*void CreateTexture(GLuint textureArray[],char *strFileName,int textureID) {    SDL_Surface *pBitmap[1];    if( strFileName == NULL )                           // Return from the function if no file name was passed in        return ;    // We need to load the texture data, so we use a cool function that SDL offers.    pBitmap[0] = SDL_LoadBMP(strFileName);              // Load the bitmap and store the data    if(pBitmap[0] == NULL)                                // If we can't load the file, quit!    {	  textureArray[textureID] = 0;	  	  cerr << " Failed loading " << strFileName << " : " << SDL_GetError() << endl;	  //exit(0);	  return;    }    // Generate a texture with the associative texture ID stored in the array    glGenTextures(1, &textureArray[textureID]);    // Bind the texture to the texture arrays index and init the texture    glBindTexture(GL_TEXTURE_2D, textureArray[textureID]);    // WARNING   : GO THROUGH THESE FEW LINES FOR SWAPPING ROWS ONLY IF YOU REALLY NEED TO, OR ELSE SKIP    // THE LINES MARKED BELOW. Just take it for granted that these lines of code swap rows in the texture    // as required by us.    // <SKIP> <SKIP> <SKIP> <SKIP>   (FROM HERE)        -------------------    //    // IMPORTANT : SDL loads Bitmaps differently when compared to the default windows loader. The row 0    // corresponds to the top row and NOT the bottom row. Therefore if we don't invert the order of the rows,    // then the textures will appear (vertically) inverted.    // Therefore we must reverse the ordering of the rows in the data of the loaded surface ( the member    //  'pixels' of the structure)    // Rearrange the pixelData    int width  = pBitmap[0] -> w;    int height = pBitmap[0] -> h;    unsigned char * data = (unsigned char *) (pBitmap[0] -> pixels);         // the pixel data    int BytesPerPixel = pBitmap[0] -> format -> BytesPerPixel;    //////////// This is how we swap the rows :    // For half the rows, we swap row 'i' with row 'height - i -1'. (if we swap all the rows    // like this and not the first half or the last half, then we get the same texture again !    //    // Now these rows are not stored as 2D arrays, instead they are stored as a long 1D array.    // So each row is concatenated after the previous one to make this long array. Our swap    // function swaps one byte at a time and therefore we swap BytesPerPixel (= total bits per pixel)    // bytes succesively.    //    // so the three loops below are :    // for the first half of the rows    //   for all the width (which is width of image * BytesPerPixel, where BytesPerPixel = total bits per pixel).    //   (Here, for each pixel, we have to increment j by total bits per pixel (to get to next pixel to swap))    //      for(each byte in this pixel i.e k = 0 to BytesPerPixel - 1, i.e BytesPerPixel bytes.    //        swap the byte with the corresponding byte in the 'height -i -1'th row ('i'th row from bottom)    for( int i = 0 ; i < (height / 2) ; ++i )        for( int j = 0 ; j < width * BytesPerPixel; j += BytesPerPixel )            for(int k = 0; k < BytesPerPixel; ++k)                swap( data[ (i * width * BytesPerPixel) + j + k], data[ ( (height - i - 1) * width * BytesPerPixel ) + j + k]);    unsigned char *pixels = new unsigned char[width * height * 3];    int count = 0;    // the following lines extract R,G and B values from any bitmap    for(int i = 0; i < (width * height); ++i)    {        byte r,g,b;                                                // R,G and B that we will put into pImage        Uint32 pixel_value = 0;                                    // 32 bit unsigned int (as dictated by SDL)        // the following loop extracts the pixel (however wide it is 8,16,24 or 32) and        // creates a long with all these bytes taken together.        for(int j = BytesPerPixel - 1 ; j >=0; --j)                // for each byte in the pixel (from the right)        {            pixel_value = pixel_value << 8;                        // left shift pixel value by 8 bits            pixel_value = pixel_value | data[ (i * BytesPerPixel) + j ];  // then make the last 8 bits of pixel value  =        }                                                                 // the byte that we extract from pBitmap's data        SDL_GetRGB(pixel_value, pBitmap[0] -> format, (Uint8 *)&r, (Uint8 *)&g, (Uint8 *)&b);     // here we get r,g,b from pixel_value which is stored in the form specified by pBitmap->format        pixels[count++] = r;          // in our tImage classes we store r first        pixels[count++] = g;          // then g        pixels[count++] = b;          // and finally b (for bmps - three channels only)        /*pixels[(i * BytesPerPixel) + 0] = r;          // in our tImage classes we store r first        pixels[(i * BytesPerPixel) + 1] = g;          // then g        pixels[(i * BytesPerPixel) + 2] = b;          // and finally b (for bmps - three channels only)*/        pixel_value = 0;                                           // reset pixel , else we get incorrect values of r,g,b    }    // </SKIP> </SKIP> </SKIP> </SKIP>    (TO HERE)   -------------------    // Build Mipmaps (builds different versions of the picture for distances - looks better)    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pBitmap[0]->w, pBitmap[0]->h, GL_RGB, GL_UNSIGNED_BYTE, pixels);    // Lastly, we need to tell OpenGL the quality of our texture map.  GL_LINEAR is the smoothest.    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);    // Now we need to free the bitmap data that we loaded since openGL stored it as a texture    SDL_FreeSurface(pBitmap[0]);                        // Free the texture data we dont need it anymore}float Constants::distance(float x1, float y1, float w1, float h1, 					 float x2, float y2, float w2, float h2) {  // the distance between their centers  float rx1 = x1 + (w1 / 2.0f);  float rx2 = x2 + (w2 / 2.0f);  float ry1 = y1 - (h1 / 2.0f);  float ry2 = y2 - (h2 / 2.0f);  float d = sqrt(((rx2 - rx1) * (rx2 - rx1)) + 				 ((ry2 - ry1) * (ry2 - ry1)));  // remove the shapes' radius from the distance  float d1 = sqrt(((w1 / 2.0f) * (w1 / 2.0f)) + 				  ((h1 / 2.0f) * (h1 / 2.0f)));  float d2 = sqrt(((w2 / 2.0f) * (w2 / 2.0f)) + 				  ((h2 / 2.0f) * (h2 / 2.0f)));    float ret = d - (d1 + d2);  return (ret < 0 ? 0 : ret);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -