b23636c9 |
// 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);
}
|