2011-03-10 82 views
0
// 
// This code was created by Lionel Brits/Jeff Molofee '99 
// 
// If you've found this code useful, please let me know. 
// 
// Visit NeHe Productions at www.demonews.com/hosted/nehe 
// 
/**************************************************************/ 
// This code was ported to MacOS by Tony Parker. 
// I'd also appreciate it if you could drop me a line if you found 
// this code useful. 
// 
// Tony Parker - [email protected] 
// 
// Have a nice day. 

#include <stdio.h>   // Header File For Standard Input/Output 
#include <stdarg.h>   // Header File For Variable Argument Routines 
#include <string.h>   // Header File For String Management 
#include <stdlib.h> 
#include <stdbool.h> 
#include <OpenGL/gl.h>    // Header File For The OpenGL32 Library 
#include <OpenGL/glu.h>   // Header File For The GLu32 Library 
#include <GLUT/glut.h>   // Header File For The GLUT Library 

#include "math.h" 

#include "model.h" 

// Constants ---------------------------------------------------------------------- 

#define kWindowHeight 400 
#define kWindowWidth 400 

// Structures ---------------------------------------------------------------- 

typedef struct    // Create A Structure 
{ 
    GLubyte *imageData;  // Image Data (Up To 32 Bits) 
    GLuint bpp;   // Image Color Depth In Bits Per Pixel. 
    GLuint width;   // Image Width 
    GLuint height;   // Image Height 
    GLuint texID;   // Texture ID Used To Select A Texture 
} TextureImage;    // Structure Name 

// Function Prototypes ------------------------------------------------------- 

bool LoadTGA(TextureImage *texture, char *filename); 
float rad(float angle); 
void readstr(FILE *f,char *string); 
void SetupWorld(void); 

GLvoid InitGL(GLvoid); 
GLvoid DrawGLScene(GLvoid); 
GLvoid ReSizeGLScene(int Width, int Height); 
GLvoid Idle(GLvoid); 
GLvoid LoadGLTextures(void); 
GLvoid Keyboard(unsigned char key, int x, int y); 

// Global Variables ---------------------------------------------------------- 

char  *worldfile = "world.txt"; 
bool  light;      // Lighting ON/OFF 
bool  gBlend;      // Blending ON/OFF 

GLfloat  xrot;      // X Rotation 
GLfloat  yrot;      // Y Rotation 
GLfloat  xspeed;      // X Rotation Speed 
GLfloat  yspeed;      // Y Rotation Speed 

GLfloat  walkbias = 0; 
GLfloat  walkbiasangle = 0; 

GLfloat  lookupdown = 0.0f; 
const float piover180 = 0.0174532925f; 

float  heading, xpos, zpos; 

GLfloat  camx=0, camy=0, camz=0;  // Camera Location 
GLfloat  therotate; 

GLfloat  z=0.0f;      // Depth Into The Screen 

GLfloat  LightAmbient[] = { 0.5f, 0.5f, 0.5f, 1.0f };  // Ambient Light 
GLfloat  LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };  // Diffuse Light 
GLfloat  LightPosition[] = { 0.0f, 0.0f, 2.0f, 1.0f };  // Light Position 

GLuint  filter;   // Which Filter To Use 
TextureImage texture[3];  // Storage for 3 textures 

// Our Model Goes Here: 
SECTOR  sector1; 

// rad ----------------------------------------------------------------------- 
// Converts Degrees To Radians. There Are 2 PI Radians In 360 Degrees. 

float rad(float angle) 
{ 
    return angle * piover180; 
} 

// readstr ------------------------------------------------------------------- 

void readstr(FILE *f,char *string) 
{ 
    do 
    { 
     fgets(string, 255, f); 
    } while ((string[0] == '/') || (string[0] == '\n')); 
    return; 
} 

// SetupWorld ---------------------------------------------------------------- 

void SetupWorld(void) 
{ 
    float x, y, z, u, v; 
    int numtriangles; 
    FILE *filein; 
    char oneline[255]; 
    filein = fopen(worldfile, "rt"); 

    readstr(filein,oneline); 
    sscanf(oneline, "NUMPOLLIES %d\n", &numtriangles); 

    sector1.triangle = new TRIANGLE[numtriangles]; 
    sector1.numtriangles = numtriangles; 
    int loop; 
    for (loop = 0; loop < numtriangles; loop++) 
    { 
     int vert; 
     for (vert = 0; vert < 3; vert++) 
     { 
      readstr(filein,oneline); 
      sscanf(oneline, "%f %f %f %f %f", &x, &y, &z, &u, &v); 
      sector1.triangle[loop].vertex[vert].x = x; 
      sector1.triangle[loop].vertex[vert].y = y; 
      sector1.triangle[loop].vertex[vert].z = z; 
      sector1.triangle[loop].vertex[vert].u = u; 
      sector1.triangle[loop].vertex[vert].v = v; 
     } 
    } 
    fclose(filein); 
    return; 
} 


#pragma mark - 

// Main ---------------------------------------------------------------------- 

int main(int argc, char** argv) 
{ 

    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); 
    glutInitWindowSize(kWindowWidth, kWindowHeight); 
    glutInitWindowPosition (100, 100); 
    glutCreateWindow (argv[0]); 

    SetupWorld(); 
    InitGL(); 

    glutDisplayFunc(DrawGLScene); 
    glutReshapeFunc(ReSizeGLScene); 

    glutKeyboardFunc(Keyboard); 

    glutMainLoop(); 

    return 0; 
} 

// InitGL --------------------------------------------------------------------- 

GLvoid InitGL(GLvoid) 
{ 

    LoadGLTextures();         // Load The Texture (ADD) 
    glEnable(GL_TEXTURE_2D);       // Enable Texture Mapping (ADD) 

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);    // This Will Clear The Background Color To Black 
    glClearDepth(1.0);         // Enables Clearing Of The Depth Buffer 

    glShadeModel(GL_SMOOTH);       // Enables Smooth Color Shading 

    glMatrixMode(GL_PROJECTION);      // Select The Projection Matrix 
    glLoadIdentity();         // Reset The Projection Matrix 

    gluPerspective(45.0f, (GLfloat) kWindowWidth/(GLfloat) kWindowHeight, 0.1f, 100.0f); 
                 // Calculate The Aspect Ratio Of The Window 

    glMatrixMode(GL_MODELVIEW);       // Select The Modelview Matrix 

    glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); 
    glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); 
    glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); 
    glEnable(GL_LIGHT1); 
} 

// Idle --------------------------------------------------------------------- 

GLvoid Idle(GLvoid) 
{ 
    glutPostRedisplay(); 
} 

// Keyboard ----------------------------------------------------------------- 

void Keyboard(unsigned char key, int x, int y) 
{ 
#pragma unused (x, y) 

    switch(key) 
    { 

     case 'b':  // turn blending on/off 
     gBlend = !gBlend; 
     if (!gBlend) 
     { 
      glDisable(GL_BLEND); 
      glEnable(GL_DEPTH_TEST); 
     } 
     else 
     { 
      glEnable(GL_BLEND); 
      glDisable(GL_DEPTH_TEST); 
     } 
     break; 

     case 'f':  
     filter+=1; 
     if (filter > 2) 
     { 
      filter = 0; 
     } 
     break; 

     case 'l': 
     light = !light; 
     if (!light) 
      glDisable(GL_LIGHTING); 
     else 
      glEnable(GL_LIGHTING); 
     break; 

     case 'w':  // walk forward 
     xpos -= (float)sin(heading*piover180) * 0.05f; 
     zpos -= (float)cos(heading*piover180) * 0.05f; 

     if (walkbiasangle >= 359.0f) 
      walkbiasangle = 0.0f; 
     else 
      walkbiasangle+= 10; 

     walkbias = (float)sin(walkbiasangle * piover180)/20.0f; 

     //lookupdown -= 1.0f; 

     break; 

     case 'x':  // walk back 
     xpos += (float)sin(heading*piover180) * 0.05f; 
     zpos += (float)cos(heading*piover180) * 0.05f; 
     if (walkbiasangle <= 1.0f) 
      walkbiasangle = 359.0f; 
     else 
      walkbiasangle-= 10; 

     walkbias = (float)sin(walkbiasangle * piover180)/20.0f; 

     //lookupdown += 1.0f; 

     break; 

     case 'd':  // turn right 
     heading -= 1.0f; 
     yrot = heading; 
     break; 

     case 'a':  // turn left 
     heading += 1.0f;  
     yrot = heading; 
     break; 

     case 'q': 
     z += 0.02f; 
     break; 

     case 'z': 
     z += 0.02f; 
     break; 

     default: 
     break; 
    } 

    glutPostRedisplay(); 
} 


// DrawGLScene ------------------------------------------------------------- 

GLvoid DrawGLScene(GLvoid) 
{  

    GLfloat x_m, y_m, z_m, u_m, v_m; 
    GLfloat xtrans, ztrans, ytrans; 
    GLfloat sceneroty; 

    xtrans = -xpos; 
    ztrans = -zpos; 
    ytrans = -walkbias-0.25f; 

    sceneroty = 360.0f- yrot; 


    int numtriangles; 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  // Clear The Screen And The Depth Buffer 
    glLoadIdentity();          // Reset The View 

    glRotatef(lookupdown,1.0f,0,0); 
    glRotatef(sceneroty,0,1.0f,0); 

    glTranslatef(xtrans, ytrans, ztrans); 
    glBindTexture(GL_TEXTURE_2D, texture[filter].texID); 


    numtriangles = sector1.numtriangles; 

    // Process Each Triangle 
    int loop_m; 
    for (loop_m = 0; loop_m < numtriangles; loop_m++) 
    { 
     glBegin(GL_TRIANGLES); 
      glNormal3f(0.0f, 0.0f, 1.0f); 
      x_m = sector1.triangle[loop_m].vertex[0].x; 
      y_m = sector1.triangle[loop_m].vertex[0].y; 
      z_m = sector1.triangle[loop_m].vertex[0].z; 
      u_m = sector1.triangle[loop_m].vertex[0].u; 
      v_m = sector1.triangle[loop_m].vertex[0].v; 
      glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m); 

      x_m = sector1.triangle[loop_m].vertex[1].x; 
      y_m = sector1.triangle[loop_m].vertex[1].y; 
      z_m = sector1.triangle[loop_m].vertex[1].z; 
      u_m = sector1.triangle[loop_m].vertex[1].u; 
      v_m = sector1.triangle[loop_m].vertex[1].v; 
      glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m); 

      x_m = sector1.triangle[loop_m].vertex[2].x; 
      y_m = sector1.triangle[loop_m].vertex[2].y; 
      z_m = sector1.triangle[loop_m].vertex[2].z; 
      u_m = sector1.triangle[loop_m].vertex[2].u; 
      v_m = sector1.triangle[loop_m].vertex[2].v; 
      glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m); 
     glEnd(); 
    } 


    glutSwapBuffers(); 
    glFlush(); 
} 

// ReSizeGLScene ------------------------------------------------------------ 

GLvoid ReSizeGLScene(int Width, int Height) 
{ 
    glViewport (0, 0, (GLsizei) Width, (GLsizei) Height); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 

    gluPerspective(45.0, (GLfloat) Width/(GLfloat) Height, 0.1, 100.0); 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
} 


// LoadGLTextures ------------------------------------------------------------ 

GLvoid LoadGLTextures(GLvoid) 
{ 

    //load texture 

    LoadTGA(&texture[0], "mud.tga"); 
    LoadTGA(&texture[1], "mud.tga"); 
    LoadTGA(&texture[2], "mud.tga"); 


    // Create Nearest Filtered Texture 

    glBindTexture(GL_TEXTURE_2D, texture[0].texID); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); 
    //glTexImage2D(GL_TEXTURE_2D, 0, 3, texture1->sizeX, texture1->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, texture1->data); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture[0].width, texture[0].height, 0, GL_RGB, GL_UNSIGNED_BYTE, texture[0].imageData); 

    // Create Linear Filtered Texture 
    glBindTexture(GL_TEXTURE_2D, texture[1].texID); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
    //glTexImage2D(GL_TEXTURE_2D, 0, 3, texture1->sizeX, texture1->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, texture1->data); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture[1].width, texture[1].height, 0, GL_RGB, GL_UNSIGNED_BYTE, texture[1].imageData); 

    // Create MipMapped Texture 
    glBindTexture(GL_TEXTURE_2D, texture[2].texID); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); 
    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, texture[2].width, texture[2].height, GL_RGB, GL_UNSIGNED_BYTE, texture[2].imageData); 

} 


/********************> LoadTGA() <*****/ 
bool LoadTGA(TextureImage *texture, char *filename)   // Loads A TGA File Into Memory 
{  
    GLubyte  TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0}; // Uncompressed TGA Header 
    GLubyte  TGAcompare[12];        // Used To Compare TGA Header 
    GLubyte  header[6];         // First 6 Useful Bytes From The Header 
    GLuint  bytesPerPixel;        // Holds Number Of Bytes Per Pixel Used In The TGA File 
    GLuint  imageSize;         // Used To Store The Image Size When Setting Aside Ram 
    GLuint  temp;          // Temporary Variable 
    GLuint  type=GL_RGBA;        // Set The Default GL Mode To RBGA (32 BPP) 

    FILE *file = fopen(filename, "rb");      // Open The TGA File 

    if(file==NULL ||          // Does File Even Exist? 
     fread(TGAcompare,1,sizeof(TGAcompare),file)!=sizeof(TGAcompare) || // Are There 12 Bytes To Read? 
     memcmp(TGAheader,TGAcompare,sizeof(TGAheader))!=0    || // Does The Header Match What We Want? 
     fread(header,1,sizeof(header),file)!=sizeof(header))    // If So Read Next 6 Header Bytes 
    { 
     fclose(file);          // If Anything Failed, Close The File 
     return false;          // Return False 
    } 

    texture->width = header[1] * 256 + header[0];   // Determine The TGA Width (highbyte*256+lowbyte) 
    texture->height = header[3] * 256 + header[2];   // Determine The TGA Height (highbyte*256+lowbyte) 

    if(texture->width <=0 ||        // Is The Width Less Than Or Equal To Zero 
     texture->height <=0 ||        // Is The Height Less Than Or Equal To Zero 
     (header[4]!=24 && header[4]!=32))     // Is The TGA 24 or 32 Bit? 
    { 
     fclose(file);          // If Anything Failed, Close The File 
     return false;          // Return False 
    } 

    texture->bpp = header[4];       // Grab The TGA's Bits Per Pixel (24 or 32) 
    bytesPerPixel = texture->bpp/8;      // Divide By 8 To Get The Bytes Per Pixel 
    imageSize  = texture->width*texture->height*bytesPerPixel; // Calculate The Memory Required For The TGA Data 

    texture->imageData=(GLubyte *)malloc(imageSize);  // Reserve Memory To Hold The TGA Data 

    if(texture->imageData==NULL ||       // Does The Storage Memory Exist? 
     fread(texture->imageData, 1, imageSize, file)!=imageSize) // Does The Image Size Match The Memory Reserved? 
    { 
     if(texture->imageData!=NULL)      // Was Image Data Loaded 
      free(texture->imageData);      // If So, Release The Image Data 

     fclose(file);          // Close The File 
     return false;          // Return False 
    } 

    GLuint i; 
    for(i=0; i<imageSize; i= i + bytesPerPixel)  // Loop Through The Image Data 
    {              // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue) 
     temp=texture->imageData[i];       // Temporarily Store The Value At Image Data 'i' 
     texture->imageData[i] = texture->imageData[i + 2]; // Set The 1st Byte To The Value Of The 3rd Byte 
     texture->imageData[i + 2] = temp;     // Set The 3rd Byte To The Value In 'temp' (1st Byte Value) 
    } 

    fclose (file);           // Close The File 

    if (texture[0].bpp==24)         // Was The TGA 24 Bits 
    { 
     type=GL_RGB;          // If So Set The 'type' To GL_RGB 
    } 

    // Build A Texture From The Data 
    // We're doing this in a different function in this tutorial 

    glGenTextures(1, &texture[0].texID);     // Generate OpenGL texture IDs 
    /* 
    glBindTexture(GL_TEXTURE_2D, texture[0].texID);   // Bind Our Texture 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Filtered 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtered 

    glTexImage2D(GL_TEXTURE_2D, 0, type, texture[0].width, texture[0].height, 0, type, GL_UNSIGNED_BYTE, texture[0].imageData); 
    */ 

    return true;           // Texture Building Went Ok, Return True 
} 

需要帮助。 我得到这个错误:OpenGL程序错误。需要帮助

/Users//Desktop/XcodeGLUT/../gora.cs.illinois.edu:display:cs418sp11:Home/Lesson 10 Folder/main.c:126:0 /Users//Desktop/XcodeGLUT/../gora.cs.illinois.edu:display:cs418sp11:Home/Lesson 10 Folder/main.c:126: error: 'new' undeclared (first use in this function)

+0

程序的扩展名是'.c'。在'C'中没有关键字叫'new'。看起来'TRIANGLE'是一个类,所以尝试将程序重命名为'main.cc'并构建它。 – Mahesh 2011-03-10 03:50:32

回答

1

重命名为Main.cpp的文件,似乎文件中使用C编译器,而不是C++编译器,其中新是在堆上分配(而不是malloc的关键字编译/ calloc)