All pastes #1489016 Raw Edit

Unnamed

public cpp v1 · immutable
#1489016 ·published 2009-07-09 00:06 UTC
rendered paste body
// http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=45#include <GL/glew.h>#include "SDL.h"#include "sdl-timer.hpp"#define SCREEN_WIDTH 1024#define SCREEN_HEIGHT 768#define SCREEN_BPP 32#define FRAMES_PER_SECOND 60#define MESH_RESOLUTION 4.0f#define MESH_HEIGHTSCALE 1.0f//#define GL_ARRAY_BUFFER_ARB 0x8892//#define GL_STATIC_DRAW_ARB 0x88E4class CVert{public:  float x;  float y;  float z;};typedef CVert CVec;class CTexCoord{public:  float u;  float v;};class CMesh{public:  int m_nVertexCount;  CVert * m_pVertices;  CTexCoord* m_pTexCoords;  GLuint m_nTextureId;    GLuint m_nVBOVertices;  GLuint  m_nVBOTexCoords;    SDL_Surface* m_pTextureImage;public:  CMesh();  ~CMesh();  bool LoadHeightmap(char* czPath, float flHeightScale, float flResolution);  float PtHeight(int nX, int nY);  void BuildVBOs();};bool g_fVGOSupported = true;CMesh* g_pMesh = NULL;bool g_fVBOSupported = false;float g_flYRot = 0.0f;bool CMesh :: LoadHeightmap(char* szPath, float flHeightScale, float flResolution){  SDL_Surface *surface;  Uint32 rmask, gmask, bmask, amask;#if SDL_BYTEORDER == SDL_BIG_ENDIAN             //Check Endianess and set rgba masks accordingly  rmask = 0xff000000;  gmask = 0x00ff0000;  bmask = 0x0000ff00;  amask = 0x00000000;#else  rmask = 0x000000ff;  gmask = 0x0000ff00;  bmask = 0x00ff0000;  amask = 0x00000000;#endif  m_pTextureImage = SDL_LoadBMP(szPath);  surface = SDL_CreateRGBSurface(SDL_SWSURFACE, m_pTextureImage->w,				 m_pTextureImage->h, 24,				 rmask, gmask, bmask, amask);  m_pTextureImage = SDL_ConvertSurface(m_pTextureImage, surface->format,				       SDL_SWSURFACE);  // generate vertex field  m_nVertexCount = (int) (m_pTextureImage->w * m_pTextureImage->h * 6/(flResolution * flResolution));  printf("vertex count=%d\n",m_nVertexCount);  printf("image width=%d, height=%d\n", m_pTextureImage->w, m_pTextureImage->h);  m_pVertices = new CVec[m_nVertexCount];  m_pTexCoords = new CTexCoord[m_nVertexCount];  int nX, nZ, nTri, nIndex = 0;  float flX, flZ;  for (nZ = 0; nZ < m_pTextureImage->h; nZ +=(int) flResolution)    {      for (nX = 0; nX < m_pTextureImage->w; nX +=(int) flResolution)	{	  for (nTri = 0; nTri < 6; nTri++)	    {	      flX=(float) nX + ((nTri == 1 || nTri == 2 || nTri == 5) ? flResolution : 0.0f);	      flZ=(float) nZ + ((nTri == 2 || nTri == 4 || nTri == 5) ? flResolution : 0.0f);	      m_pVertices[nIndex].x = flX - (m_pTextureImage->w/2);	      m_pVertices[nIndex].y = PtHeight((int) flX, (int) flZ)*flHeightScale;	      m_pVertices[nIndex].z = flZ - (m_pTextureImage->h/2);	      m_pTexCoords[nIndex].u = flX/m_pTextureImage->w;	      m_pTexCoords[nIndex].v = flZ/m_pTextureImage->h;#if 0	      printf("%d (%f,%f,%f) [%f %f]\n", nIndex,		     m_pVertices[nIndex].x, m_pVertices[nIndex].y,		     m_pVertices[nIndex].z, m_pTexCoords[nIndex].u,		     m_pTexCoords[nIndex].v);#endif	      nIndex++;	    }	}    }  glGenTextures(1, &m_nTextureId);  glBindTexture(GL_TEXTURE_2D, m_nTextureId);  glTexImage2D(GL_TEXTURE_2D, 0, 3, m_pTextureImage->w, m_pTextureImage->h,	       0, GL_RGB, GL_UNSIGNED_BYTE, m_pTextureImage->pixels);  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);  if(m_pTextureImage)    {      SDL_FreeSurface(m_pTextureImage);    }  if(surface)    {      SDL_FreeSurface(surface);    }  return true;}CMesh :: CMesh(){  // Set Pointers To NULL  m_pTextureImage = NULL;  m_pVertices = NULL;  m_pTexCoords = NULL;  m_nVertexCount = 0;  m_nVBOVertices = m_nVBOTexCoords = m_nTextureId = 0;}CMesh :: ~CMesh(){  // Delete VBOs  if( g_fVBOSupported )    {      GLuint nBuffers[2] = { m_nVBOVertices, m_nVBOTexCoords };      glDeleteBuffers( 2, nBuffers );                                              // Free The Memory    }  // Delete Data  if( m_pVertices )                                                                                       // Deallocate Vertex Data    delete [] m_pVertices;  m_pVertices = NULL;  if( m_pTexCoords )                                                                                      // Deallocate Texture Coord Data    delete [] m_pTexCoords;  m_pTexCoords = NULL;  if(m_nVBOTexCoords)                                                                     // Deallocate Vertex Buffer    glDeleteBuffers( 1, &m_nVBOTexCoords);  if(m_nVBOVertices)    glDeleteBuffers( 1, &m_nVBOVertices);}float CMesh :: PtHeight (int nX, int nY){  SDL_Color color;  Uint32 col=0;  char* offset = (char*) m_pTextureImage->pixels;  offset += (m_pTextureImage->pitch * nY);  offset += (m_pTextureImage->format->BytesPerPixel * nX);  memcpy(&col, offset, m_pTextureImage->format->BytesPerPixel);  SDL_GetRGB(col, m_pTextureImage->format, &color.r, &color.g, &color.b);  return (0.299f * color.r + 0.587f * color.g + 0.114f * color.b);}void CMesh::BuildVBOs(){  printf("building VBOs\n");  glGenBuffers(1, &m_nVBOVertices);  glBindBuffer(GL_ARRAY_BUFFER, m_nVBOVertices);  glBufferData(GL_ARRAY_BUFFER, m_nVertexCount * 3 * sizeof(float),		  m_pVertices, GL_STATIC_DRAW);  glGenBuffers(1, &m_nVBOTexCoords);  glBindBuffer(GL_ARRAY_BUFFER, m_nVBOTexCoords);  glBufferData(GL_ARRAY_BUFFER, m_nVertexCount * 2 * sizeof(float),		  m_pTexCoords, GL_STATIC_DRAW);  delete [] m_pVertices; m_pVertices = NULL;  delete [] m_pTexCoords; m_pTexCoords = NULL;}// straight from tutorial#if 0bool IsExtensionSupported( char* szTargetExtension ){  const unsigned char *pszExtensions = NULL;  const unsigned char *pszStart;  unsigned char *pszWhere, *pszTerminator;  // Extension names should not have spaces  pszWhere = (unsigned char *) strchr( szTargetExtension, ' ' );  if( pszWhere || *szTargetExtension == '\0' )    return false;  // Get Extensions String  pszExtensions = glGetString( GL_EXTENSIONS );  // Search The Extensions String For An Exact Copy  pszStart = pszExtensions;  for(;;)    {      pszWhere = (unsigned char *) strstr( (const char *) pszStart, szTargetExtension );      if( !pszWhere )	break;      pszTerminator = pszWhere + strlen( szTargetExtension );      if( pszWhere == pszStart || *( pszWhere - 1 ) == ' ' )	if( *pszTerminator == ' ' || *pszTerminator == '\0' )	  return true;      pszStart = pszTerminator;    }  return false;}#endifbool Initialize (void){  g_pMesh = new CMesh();  printf("loading data/terrain.bmp\n");  if(!g_pMesh->LoadHeightmap("data/terrain.bmp",			     MESH_HEIGHTSCALE, MESH_RESOLUTION))    {      fprintf(stderr, "failed to load data/terrain.bmp\n");      return false;    }#if 0  printf("checking for VBO support...");  g_fVBOSupported = glewIsExtensionSupported("GL_vertex_buffer_object");  if(g_fVBOSupported)    {      printf("supported!\n");      g_pMesh->BuildVBOs();    }else{    printf("NOT supported :(\n");  }#endif  printf("about to build VBOs\n");  g_pMesh->BuildVBOs();  printf("done building VBOs\n");  return true;}bool init_GL();SDL_Event event;GLuint texture[1];class Square{private:  int x, y, width, height;  int xVel, yVel;public:  Square();  void handle_input();  void move();};Square::Square(){  x = 5;  y = 5;  width = 256;  height = 256;  xVel = 0;  yVel = 0;}void Square::move(){  x += xVel;  if ((x < 0) || (x + width > SCREEN_WIDTH))    {      x -= xVel;    }  y += yVel;  if ((y < 0) || (y + width > SCREEN_HEIGHT))    {      y -= yVel;    }}void Square::handle_input(){  if (event.type == SDL_KEYDOWN) {    switch (event.key.keysym.sym) {    case SDLK_UP: yVel -= height / 2;      break;    case SDLK_DOWN: yVel += height / 2;      break;    case SDLK_LEFT: xVel -= width / 2;      break;    case SDLK_RIGHT: xVel += width / 2;      break;    default: break;    }  } else {    switch (event.key.keysym.sym) {    case SDLK_UP: yVel += height / 2; break;    case SDLK_DOWN: yVel -= height / 2; break;    case SDLK_LEFT: xVel += width / 2; break;    case SDLK_RIGHT: xVel -= width / 2; break;    default: break;    }  }}bool init(){  if (SDL_Init(SDL_INIT_EVERYTHING) < 0)    {      return false;    }  if (SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_OPENGL) == NULL)    {      return false;    }  if (init_GL() == false)    {      return false;    }  if (Initialize() == false)    {      return false;    }  SDL_WM_SetCaption("OpenGL Test", NULL);  return true;}bool init_GL(){  glEnable(GL_TEXTURE_2D);  glShadeModel(GL_SMOOTH);  glClearDepth(1.0f);  glDepthFunc(GL_LEQUAL);  glEnable(GL_DEPTH_TEST);  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);  glClearColor(0.0f, 0.5f, 1.0f, 0.5f);  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);  if (glGetError() != GL_NO_ERROR)    {      return false;    }  return true;}void clean_up(){  SDL_Quit();}void draw(void){  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    glLoadIdentity();  glTranslatef(0.0f, -220.0f, 0.0f);  glRotatef(10.0f, 1.0f, 0.0f, 0.0f);  glEnableClientState( GL_VERTEX_ARRAY );  glEnableClientState( GL_TEXTURE_COORD_ARRAY );  if(g_fVBOSupported)    {      glBindBuffer(GL_ARRAY_BUFFER, g_pMesh->m_nVBOVertices);      glVertexPointer(3, GL_FLOAT, 0, (char *) NULL);      glBindBuffer(GL_ARRAY_BUFFER, g_pMesh->m_nVBOTexCoords);      glTexCoordPointer(2, GL_FLOAT, 0, (char *) NULL);    }else    {      glVertexPointer(3, GL_FLOAT, 0, g_pMesh->m_pVertices);      glTexCoordPointer(2, GL_FLOAT, 0, g_pMesh->m_pTexCoords);    }  glDrawArrays(GL_TRIANGLES, 0, g_pMesh->m_nVertexCount);  glDisableClientState( GL_VERTEX_ARRAY );  glDisableClientState( GL_TEXTURE_COORD_ARRAY );    SDL_GL_SwapBuffers();}int main(int argc, char* args[]){  Square square;  Timer fps;  // make sure the program waits for a quit  bool quit = false;  if (init() == false) {    fprintf(stderr, "init failed\n");    return 1;  }  while (quit == false)    {      fps.start();      while (SDL_PollEvent(&event))	{	  //	  square.handle_input();	  	  if (event.type == SDL_QUIT)	    {	      quit = true;	    }	}      draw();      if (fps.get_ticks() < 1000 / FRAMES_PER_SECOND) {	SDL_Delay((1000/FRAMES_PER_SECOND) - fps.get_ticks());      }    }      clean_up();  return 0;}