All pastes #241497 Raw Edit

Miscellany

public text v1 · immutable
·published 2006-11-06 07:10 UTC
rendered paste body
/*
 * James Steven Supancic III
 */

#include <iostream>
#include <complex>
#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>

using namespace std;

double mandelbrot(int x, int y)
{
  /* The point value is the numbre of iterations it takes for
   * the algorithm to meet the escape condition
   */
  int x0 = x, y0 = y, x2 = x*x, y2 = y*y;
  int itr = 0, most = 500;

  while(x2+y2 < 4 and itr < most)
    {
      y = 2 * x * y + y0;
      x = x2 - y2 + x0;

      x2 = x*x;
      y2 = y*y;

      itr++;
    }

  /* I want values between 0 and 1*/
  return itr/500;
}

int vertexFromXY(int x, int y, int max_x)
{
  //C++ is row major?
  return x*max_x+y;
}

int main(int argc, char** argv)
{
  int win_width = 800, win_height = 600; //dimensions of output window

  /* SDL code, sets up the output for any platform
   * Because some people refuse to use X11...
   */

  SDL_Surface *screen;

  if(SDL_Init(SDL_INIT_VIDEO))
    {
      cout << "Error seting up video" << endl;
      return 1;
    }
  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);

  screen = SDL_SetVideoMode( win_width, win_height, 16, SDL_OPENGL ); 

  /* introduce ourself to the graphics computer */
  glEnableClientState(GL_COLOR_ARRAY);
  glEnableClientState(GL_VERTEX_ARRAY);
  glEnableClientState(GL_INDEX_ARRAY);
  glClearColor(.2,.2,1,0); //blue background (sky)
  glViewport(0,0,win_width, win_height); //inform the video computer of output.

  /* generate the data for drawing*/
  const int range_x = 500, range_y = 500;
  double (*vertex_data)[range_y][6] = new double[range_x][range_y][6];
  //Going to use GL_QUADS
  GLint (*index_data)[range_y-1][4] = new GLint[range_x-1][range_y-1][4];

  for(int xtr = 0; xtr < range_x;xtr++)
    {
      for(int ytr = 0; ytr < range_y; ytr++)
	{
	  /* Fill the Vertex array*/
	  double thisMan = mandelbrot(xtr,ytr);

	  vertex_data[xtr][ytr][0] = xtr; //x coord;
	  vertex_data[xtr][ytr][1] = ytr; //y coord;
	  vertex_data[xtr][ytr][2] = thisMan*500; //value in [0,500]

	  vertex_data[xtr][ytr][3] = thisMan; //r
	  vertex_data[xtr][ytr][4] = thisMan; //g
	  vertex_data[xtr][ytr][5] = thisMan; //b

	  /* Fill the Index Array */
	  if(xtr == range_x-1 or ytr == range_y -1)
	    {
	      continue;
	    }
	  index_data[xtr][ytr][0] = vertexFromXY(xtr,ytr,range_x);
	  index_data[xtr][ytr][1] = vertexFromXY(xtr,ytr+1,range_x);
	  index_data[xtr][ytr][2] = vertexFromXY(xtr+1,ytr+1,range_x);
	  index_data[xtr][ytr][3] = vertexFromXY(xtr+1,ytr,range_x);
	}
    }// O[n^3]!!!

  //get the address of the VBO functions.
  //native VBO support is fairly recent, so to support older machines we need to do this
  void (*glGenBuffers)(GLsizei,GLuint*) = (void (*)(GLsizei,GLuint*))SDL_GL_GetProcAddress("glGenBuffers");
  void (*glBindBuffer)(GLenum,GLuint) = (void (*)(GLenum,GLuint))SDL_GL_GetProcAddress("glBindBuffer");
  void (*glBufferData)(GLenum,GLsizeiptr,const GLvoid*,GLenum) = (void (*)(GLenum,GLsizeiptr,const GLvoid*,GLenum))SDL_GL_GetProcAddress("glBufferData");

  if(glGenBuffers == NULL || glBindBuffer == NULL || glBufferData == NULL)
    {
      cout << "Your machine doesn't support VBOs" << endl;
      cout << "good bye" << endl;
    }

  //get vertex buffers and upload data to the graphics computer
  GLuint buffers[2];
  glGenBuffers(2,buffers);
  glBindBuffer(GL_ARRAY_BUFFER,buffers[0]);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,buffers[1]);
  
  glBufferData(GL_ARRAY_BUFFER,range_x*range_y*6,vertex_data,GL_STATIC_DRAW);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER,range_x*range_y*4,index_data,GL_STATIC_DRAW);

  //now tell the graphics machine what the data means...
  glVertexPointer(3,GL_DOUBLE,3,vertex_data);
  glColorPointer(3,GL_DOUBLE,3,vertex_data+3);

  /* enter a input polling loop with SDL 
  * Normally I would use xlib, but some people
  * still insist on use non x11 based hosts...
  */
  SDL_Event ev;
  while(true)
    {
      /* clear the frame */
      glClear(GL_COLOR_BUFFER_BIT);

      /* setup the camera */
      glLoadIdentity();
      gluLookAt(range_x/2,range_y/2,800,
		range_x/2,range_y/2,0,
		0,1,0);

      /*draw the frame*/
      cout << "Drawing " << range_x*range_y*4 << " vertex" << endl;
      glDrawElements(GL_QUADS,range_x*range_y*4,GL_UNSIGNED_INT,index_data);

      /* show the frame*/
      glFlush();
      SDL_GL_SwapBuffers();

      /* Check for Input
      * exit the application on escape
      */
      SDL_PollEvent(&ev);
      switch(ev.type)
	{
	case SDL_KEYUP:
	  switch(ev.key.keysym.sym)
	    {
	    case SDLK_ESCAPE:
	      cout << "you hit escape! " << endl;
	      return 0;
	    }
	default:
	  continue;
	}
    }

  return 0;
}