// YLP 12/12/12 : transformation of a basic NeHe OpenGL code source sample (http://nehe.gamedev.net/tutorial/3d_shapes/10035/)
// for to handle chromadepth PGM pictures
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h> // Header File For The GLUT Library
#include <GL/gl.h> // Header File For The OpenGL32 Library
#include <GL/glu.h> // Header File For The GLu32 Library
#include <unistd.h> // needed to sleep
/* ASCII code for the escape key. */
#define ESCAPE 27
/* The number of our GLUT window */
int window;
/* specifics variables used for the PGM chromadepth */
int width = 0, height = 0, maxVal = 0;
int **gridData = NULL;
int *indicesArray = NULL;
float *verticesArray = NULL;
float *normalsArray = NULL;
int totalVertices = 0;
int totalIndices = 0;
int totalNormals = 0;
int vertexPositionAttr = 0;
GLuint indexBuffer = 0;
GLuint vertexBuffer = 0;
GLuint normalsBuffer = 0;
float rarray = 0;
/* A general OpenGL initialization function. Sets all of the initial parameters. */
void InitGL(int Width, int Height) // We call this right after our OpenGL window is created.
{
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
glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); // Reset The Projection Matrix
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f); // Calculate The Aspect Ratio Of The Window
glMatrixMode(GL_MODELVIEW);
}
/* The function called when our window is resized (which shouldn't happen, because we're fullscreen) */
void ReSizeGLScene(int Width, int Height)
{
if (Height==0) // Prevent A Divide By Zero If The Window Is Too Small
Height=1;
glViewport(0, 0, Width, Height); // Reset The Current Viewport And Perspective Transformation
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
}
/* Init into the drawing function. */
void InitGLScene()
{
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View
}
/* The function called whenever a key is pressed. */
void keyPressed(unsigned char key, int x, int y)
{
/* avoid thrashing this call */
usleep(100);
/* If escape is pressed, kill everything. */
if (key == ESCAPE)
{
/* shut down our window */
glutDestroyWindow(window);
/* exit the program...normal termination. */
exit(0);
}
}
// Here are located specifics Chromadepth funcs
double getNormalizedX(unsigned long x)
{
return ((double)x/((width-1)) * 2.0 - 1.0);
}
double getNormalizedY(unsigned long y)
{
return ((double)(height - 1 - y) /( (height - 1))* 2.0 - 1.0);
}
double getNormalizedZ(unsigned long x,unsigned long y)
{
unsigned long yPrime = (height - 1) - y;
// return (0.25 * gridData[yPrime][x]) / (double)maxVal;
return -fabs(gridData[yPrime][x]) / 20.0f;
}
void loadPGMFile(char *filename)
{
FILE *pgmFile;
int x, y;
char pgm_name[10000];
unsigned char temp[4];
// pgmFile = fopen("sample.pgm","r");
pgmFile = fopen(filename,"r");
if( pgmFile == NULL )
{
printf("Canot open the %s file :(\n", filename);
return;
}
fgets(pgm_name,10000,pgmFile);
fscanf(pgmFile,"%d", &width);
fscanf(pgmFile,"%d", &height);
fscanf(pgmFile,"%d", &maxVal);
printf("%s : width=%d height=%d maxVal=%d \n", filename, width, height, maxVal);
gridData = (int **)malloc(height * sizeof(int *));
for( y = 0; y < height; y++)
{
gridData[y] = malloc(width * sizeof(int));
for(x = 0; x < width; x++)
{
// fscanf(pgmFile, "%d", &gridData[y][x]);
fscanf(pgmFile, "%c", temp);
gridData[y][x] = temp[0];
// printf("gridData[%d][%d] = %d \n", y, x, gridData[y][x] );
}
}
}
void InitTerrain()
{
size_t x,y;
unsigned long vertexIndex = 0;
// XXX Change this allocation once everything is finished.
indicesArray = malloc(width * height * 6 * sizeof(GLuint));
verticesArray = malloc(width * height * 3 * sizeof(GLfloat));
normalsArray = malloc(width * height * 3 * sizeof(GLfloat));
int vertsI = 0, indicesI=0, normalsI = 0;
unsigned long i=0,j=0;
for(i = 0; i < width; i++)
{
if(i > 1)
{
indicesArray[indicesI++] = vertexIndex;
indicesArray[indicesI++] = vertexIndex;
}
for(j = 0; j < height; j++)
{
verticesArray[vertsI++] = getNormalizedX(i);
verticesArray[vertsI++] = getNormalizedY(j);
verticesArray[vertsI++] = getNormalizedZ(i,j);
if(i > 0)
{
indicesArray[indicesI++] = vertexIndex;
indicesArray[indicesI++] = vertexIndex - height;
}
vertexIndex++;
}
if(i > 0)
{
indicesArray[indicesI++] = vertexIndex - height -1;
indicesArray[indicesI++] = vertexIndex - height -1;
}
/**
** Trying to create Normals*
**/
}
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, verticesArray);
// glEnableClientState(GL_NORMAL_ARRAY);
// glVertexPointer(3, GL_FLOAT, 0, normalsArray);
totalVertices = vertsI / 3;
totalIndices = indicesI;
totalNormals = normalsI;
printf("%d vertices, %d indices, %d normals \n", totalVertices, totalIndices, totalNormals);
/*
for( i = 0 ; i < totalVertices ; i++)
{
printf("chromadepth(%f,%f) = %f \n", verticesArray[i*3], verticesArray[i*3+1], verticesArray[i*3+2]);
}
*/
}
void DrawTerrain()
{
glLoadIdentity();
// glRotatef(rarray, 0.0f,1.0f,0.0f); // Rotate The Terrain On The Y axis
glScalef(0.02f, 0.02f, 0.02f);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glColor3f(1.0f,1.0f,1.0f);
glDrawElements(GL_TRIANGLE_STRIP, totalIndices, GL_UNSIGNED_INT, indicesArray);
rarray += 1.0f;
}
void DrawGLScene()
{
InitGLScene();
DrawTerrain();
glutSwapBuffers();
}
int main(int argc, char **argv)
{
/* Initialize GLUT state - glut will take any command line arguments that pertain to it or
X Windows - look at its documentation at http://reality.sgi.com/mjk/spec3/spec3.html */
glutInit(&argc, argv);
/* Select type of Display mode:
Double buffer
RGBA color
Alpha components supported
Depth buffered for automatic clipping */
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
/* get a 640 x 480 window */
glutInitWindowSize(640, 480);
/* the window starts at the upper left corner of the screen */
glutInitWindowPosition(0, 0);
/* Open a window */
window = glutCreateWindow("Chromadepth PGM by YLP v0.0 (12/12/12) ");
/* Register the function to do all our OpenGL drawing. */
glutDisplayFunc(&DrawGLScene);
/* Go fullscreen. This is as soon as possible. */
// glutFullScreen();
/* Even if there are no events, redraw our gl scene. */
glutIdleFunc(&DrawGLScene);
/* Register the function called when our window is resized. */
glutReshapeFunc(&ReSizeGLScene);
/* Register the function called when the keyboard is pressed. */
glutKeyboardFunc(&keyPressed);
/* Initialize our window. */
InitGL(640, 480);
/* Chromadepth loading */
loadPGMFile("sample.pgm");
InitTerrain();
/* Start Event Processing Engine */
glutMainLoop();
return 1;
}