AGK T2 heightmap loader by The Zoq216th Mar 2013 11:39
|
---|
Summary This code will take a 2d heightmap and generate a .obj file from it. Then it will load the file and apply textures as well as a detail shader to it. The code was originaly created Description The function takes 7 arguments, one heightmap which will be what the map is generated from. One texture which will be added as a normal texture. The hdTexture is used by the shader to add more detail to the texture. The detailX and detailY are parameters for the shader which I believe are used to specify how small the details will be. The max height specifys how high the mesh will become. And finaly stepSize determines the detail of the map. A step size of one will create a mesh with just as many vertices as the heightmap, 2 will use every second pixel, 4 every fourth and so on. Use what you feel gives the most detail without compromising the quality to much. Code ` This code was downloaded from The Game Creators ` It is reproduced here with full permission ` http://www.thegamecreators.com ////////////////////////////////////////////////////////////// // Original code created by mike max // // Ported to T2 by TheZoq2 // ////////////////////////////////////////////////////////////// int Terrain::loadTerrain(char heightMap[128], char sdTexture[128], char hdTexture[128], float detailX, float detailY, float MaxHeight,int stepSize){ int heightMapImg = agk::LoadImage(heightMap); std::vector<Vertex> v; //Getting the size of the heightmap int x = agk::GetImageWidth(heightMapImg) - 2; int y = agk::GetImageHeight(heightMapImg) - 2; std::vector< std::vector<Vertex> > vertices; for (int i = 0; i <= x; i++) { //v = std::vector<Vertex*> (y, new Vertex()); vertices.push_back(v); for(int j = 0; j <= y; j++){ Vertex tempVertex; vertices[i].push_back(tempVertex); } } int memblockID = agk::CreateMemblockFromImage(heightMapImg); //Checking if the object file exists and deleting it if it does if(agk::GetFileExists("Map.obj")){agk::DeleteFile("Map.obj");} int ObjFile = agk::OpenToWrite("Map.obj"); int VertNumber = 1; //Generation loop for(int ly = 0; ly <= y; ly = ly + stepSize){ agk::PrintC("Generating: "); agk::Print(ly); agk::Render2DFront(); agk::Swap(); for(int lx = 0; lx <= x; lx = lx + stepSize){ int offsetPix=12+(((lx)+(ly*(x+2))))*4; int r = agk::GetMemblockByte(memblockID, offsetPix + 0); int g = agk::GetMemblockByte(memblockID, offsetPix + 1); int b = agk::GetMemblockByte(memblockID, offsetPix + 2); int a = agk::GetMemblockByte(memblockID, offsetPix + 3); float h = ((r+g+b)/3.0f)/255.0f; vertices[lx][ly].x = lx; vertices[lx][ly].y = h*MaxHeight; vertices[lx][ly].z = y - ly; //UV cordinates vertices[lx][ly].u = float(lx)/ float(x); vertices[lx][ly].v = (float(y - ly)/float(y)); //Vertex number vertices[lx][ly].vertexNumber = VertNumber; //Getting the line to write to the file char line[128]; sprintf(line, "v %f %f %f",vertices[lx][ly].x, vertices[lx][ly].y, vertices[lx][ly].z); //Writing the lines to the file agk::WriteLine(ObjFile, line); //Getting the uv file char line2[128]; sprintf(line2, "vt %f %f", vertices[lx][ly].u, vertices[lx][ly].v); agk::WriteLine(ObjFile, line2); VertNumber = VertNumber + 1; } } //Creating the faces for(int ly = 0; ly <= y; ly = ly + stepSize){ //Printing the progress agk::PrintC("Generating faces: "); agk::Print(ly); agk::Render2DFront(); agk::Swap(); for(int lx = 0; lx <= y; lx = lx + stepSize){ // if (lx>stepSize-1 && ly>stepSize-1){ //Converting indexes to form faces int v1 = vertices[lx][ly].vertexNumber; int v2 = vertices[lx - stepSize][ly].vertexNumber; int v3 = vertices[lx][ly - stepSize].vertexNumber; int v4 = vertices[lx][ly-stepSize].vertexNumber; int v5 = vertices[lx-stepSize][ly].vertexNumber; int v6 = vertices[lx-stepSize][ly-stepSize].vertexNumber; // VT indexes are the same as vertices ones. int vt1 = v1; int vt2=v2; int vt3=v3; int vt4=v4; int vt5=v5; int vt6=v6; char line[128]; sprintf(line, "f %i/%i %i/%i %i/%i", v1, vt1, v2, vt2, v3, vt3); char line2[128]; sprintf(line2, "f %i/%i %i/%i %i/%i", v4, vt4, v5, vt5, v6, vt6); agk::WriteLine(ObjFile, line); agk::WriteLine(ObjFile, line2); } } } agk::CloseFile(ObjFile); int terrainID = agk::LoadObject("Map.obj"); if(agk::GetFileExists(sdTexture)){ int colorMap = agk::LoadImage(sdTexture); agk::SetObjectImage(terrainID, colorMap, 0); agk::SetImageWrapU(colorMap, 1); agk::SetImageWrapV(colorMap, 1); } if(agk::GetFileExists(hdTexture)){ int detailMap = agk::LoadImage(hdTexture); agk::SetImageWrapU(detailMap, 1); agk::SetImageWrapV(detailMap, 1); agk::SetObjectImage(terrainID, detailMap, 1); //Loading the shader int detailShader = agk::LoadShader("media/vertexDetail.vs", "media/pixelDetail.ps"); agk::SetShaderConstantByName(detailShader, "ScaleDetailMap", detailX, detailY, 0, 0); agk::SetObjectShader(terrainID, detailShader); } return terrainID; } |