// Lab 4, terrain generation // uses framework Cocoa // uses framework OpenGL #define MAIN #include "MicroGlut.h" #include "GL_utilities.h" #include "VectorUtils4.h" #include "LittleOBJLoader.h" #include "LoadTGA.h" mat4 projectionMatrix; Model* GenerateTerrain(TextureData *tex) { int vertexCount = tex->width * tex->height; int triangleCount = (tex->width-1) * (tex->height-1) * 2; unsigned int x, z; vec3 *vertexArray = (vec3 *)malloc(sizeof(GLfloat) * 3 * vertexCount); vec3 *normalArray = (vec3 *)malloc(sizeof(GLfloat) * 3 * vertexCount); vec2 *texCoordArray = (vec2 *)malloc(sizeof(GLfloat) * 2 * vertexCount); GLuint *indexArray = (GLuint *) malloc(sizeof(GLuint) * triangleCount*3); printf("bpp %d\n", tex->bpp); for (x = 0; x < tex->width; x++) for (z = 0; z < tex->height; z++) { // Vertex array. You need to scale this properly vertexArray[(x + z * tex->width)].x = x / 1.0; vertexArray[(x + z * tex->width)].y = tex->imageData[(x + z * tex->width) * (tex->bpp/8)] / 100.0; vertexArray[(x + z * tex->width)].z = z / 1.0; // Normal vectors. You need to calculate these. normalArray[(x + z * tex->width)].x = 0.0; normalArray[(x + z * tex->width)].y = 1.0; normalArray[(x + z * tex->width)].z = 0.0; // Texture coordinates. You may want to scale them. texCoordArray[(x + z * tex->width)].x = x; // (float)x / tex->width; texCoordArray[(x + z * tex->width)].y = z; // (float)z / tex->height; } for (x = 0; x < tex->width-1; x++) for (z = 0; z < tex->height-1; z++) { // Triangle 1 indexArray[(x + z * (tex->width-1))*6 + 0] = x + z * tex->width; indexArray[(x + z * (tex->width-1))*6 + 1] = x + (z+1) * tex->width; indexArray[(x + z * (tex->width-1))*6 + 2] = x+1 + z * tex->width; // Triangle 2 indexArray[(x + z * (tex->width-1))*6 + 3] = x+1 + z * tex->width; indexArray[(x + z * (tex->width-1))*6 + 4] = x + (z+1) * tex->width; indexArray[(x + z * (tex->width-1))*6 + 5] = x+1 + (z+1) * tex->width; } // End of terrain generation // Create Model and upload to GPU: Model* model = LoadDataToModel( vertexArray, normalArray, texCoordArray, NULL, indexArray, vertexCount, triangleCount*3); return model; } // vertex array object Model *m, *m2, *tm; // Reference to shader program GLuint program; GLuint tex1, tex2; TextureData ttex; // terrain void init(void) { // GL inits glClearColor(0.2,0.2,0.5,0); glEnable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); printError("GL inits"); projectionMatrix = frustum(-0.1, 0.1, -0.1, 0.1, 0.2, 50.0); // Load and compile shader program = loadShaders("terrain.vert", "terrain.frag"); glUseProgram(program); printError("init shader"); glUniformMatrix4fv(glGetUniformLocation(program, "projMatrix"), 1, GL_TRUE, projectionMatrix.m); glUniform1i(glGetUniformLocation(program, "tex"), 0); // Texture unit 0 LoadTGATextureSimple("maskros512.tga", &tex1); // Load terrain data LoadTGATextureData("44-terrain.tga", &ttex); tm = GenerateTerrain(&ttex); printError("init terrain"); printf("Note: The call to DrawModel will report warnings about inNormal not existing. This is because inNormal is not used in the shader yet so it is optimized away.\n"); } void display(void) { // clear the screen glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); mat4 total, modelView, camMatrix; printError("pre display"); glUseProgram(program); // Build matrix vec3 cam = vec3(0, 5, 8); vec3 lookAtPoint = vec3(2, 0, 2); camMatrix = lookAt(cam.x, cam.y, cam.z, lookAtPoint.x, lookAtPoint.y, lookAtPoint.z, 0.0, 1.0, 0.0); modelView = IdentityMatrix(); total = camMatrix * modelView; glUniformMatrix4fv(glGetUniformLocation(program, "mdlMatrix"), 1, GL_TRUE, total.m); glBindTexture(GL_TEXTURE_2D, tex1); // Bind Our Texture tex1 DrawModel(tm, program, "inPosition", "inNormal", "inTexCoord"); printError("display 2"); glutSwapBuffers(); } void mouse(int x, int y) { // This function is included in case you want some hints about using passive mouse movement. // Uncomment to see mouse coordinates: // printf("%d %d\n", x, y); } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH); glutInitContextVersion(3, 2); glutInitWindowSize (600, 600); glutCreateWindow ("TSBK07 Lab 4"); glutDisplayFunc(display); init (); glutRepeatingTimer(20); glutPassiveMotionFunc(mouse); glutMainLoop(); exit(0); }