void Cube::InitDraw(){ // Initialize the data array on CPU m_Points[0] = Eigen::Vector4f( -0.5, -0.5, 0.5, 1.0 ); m_Points[1] = Eigen::Vector4f( -0.5, 0.5, 0.5, 1.0 ); m_Points[2] = Eigen::Vector4f( 0.5, 0.5, 0.5, 1.0 ); m_Points[3] = Eigen::Vector4f( 0.5, -0.5, 0.5, 1.0 ); m_Points[4] = Eigen::Vector4f( -0.5, -0.5, -0.5, 1.0 ); m_Points[5] = Eigen::Vector4f( -0.5, 0.5, -0.5, 1.0 ); m_Points[6] = Eigen::Vector4f( 0.5, 0.5, -0.5, 1.0 ); m_Points[7] = Eigen::Vector4f( 0.5, -0.5, -0.5, 1.0 ); m_Vertices = new Eigen::Vector4f[36]; m_Normals = new Eigen::Vector3f[36]; m_Index = 0; //generate the 6 faces with distinct colors GenFace( 5, 1, 0, 3, 2 ); GenFace( 1, 2, 3, 7, 6 ); GenFace( 2, 3, 0, 4, 7 ); GenFace( 3, 6, 5, 1, 2 ); GenFace( 4, 4, 5, 6, 7 ); GenFace( 0, 5, 4, 0, 1 ); //Create the Vertex Array and Buffers, bind them #ifdef __APPLE__ glGenVertexArraysAPPLE(1, &m_vertexArrayObject); glBindVertexArrayAPPLE(m_vertexArrayObject);//use as current vertex array #else glGenVertexArrays(1, &m_vertexArrayObject); glBindVertexArray(m_vertexArrayObject);//use as current vertex array #endif glGenBuffers(1, &m_vertexBufferObject);//generate buffer for current vertex array glBindBuffer(GL_ARRAY_BUFFER, m_vertexBufferObject);//use as current buffer //Send data from CPU to GPU glBufferData(GL_ARRAY_BUFFER, (sizeof(m_Vertices[0]) + sizeof(m_Normals[0]))*36, NULL, GL_STATIC_DRAW);//send data to current buffer glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(m_Vertices[0])*36, m_Vertices); glBufferSubData(GL_ARRAY_BUFFER, sizeof(m_Vertices[0])*36, sizeof(m_Normals[0])*36, m_Normals); //load and compile shaders on GPU, use current shader program m_shader = Util::InitShader( "vPhong.glsl", "fPhong.glsl" ); glUseProgram(m_shader); // Link the Shader with the buffer data // initialize the vertex position attribute from the vertex shader GLuint position = glGetAttribLocation( m_shader, "vPosition" ); glEnableVertexAttribArray( position ); glVertexAttribPointer(position, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); GLuint normal = glGetAttribLocation(m_shader, "vNormal"); glEnableVertexAttribArray(normal); glVertexAttribPointer(normal, 3, GL_FLOAT, GL_FALSE,0, BUFFER_OFFSET(sizeof(m_Vertices[0])*36)); }
BOOL BuildHeightMapMesh() { ///////////////////////////////////////////////////////////////////////////////////// // Open a dialog box to open the .bmp file ///////////////////////////////////////////////////////////////////////////////////// char fname[256]; if(!QueryBitmapFileName(fname)) return FALSE; ///////////////////////////////////////////////////////////////////////////////////// // Read the bitmap data (using the FreeImage library) ///////////////////////////////////////////////////////////////////////////////////// Bmp.ReadFromFile(fname); // Get he image width, height then calculate it's size int BmpWidth = Bmp.TellWidth(); int BmpHeight = Bmp.TellHeight(); int BmpSize = BmpWidth * BmpHeight; ///////////////////////////////////////////////////////////////////////////////////// // Get the values from the 3ds panel ///////////////////////////////////////////////////////////////////////////////////// float RealWidth = pHM->pblock2->GetFloat(pb_SpinWidth); float RealHeight = pHM->pblock2->GetFloat(pb_SpinHeight); float RealAlt = pHM->pblock2->GetFloat(pb_SpinAlt); BOOL UseTexVerts = pHM->pblock2->GetInt(pb_CheckGetTexMap); int FilterMode = pHM->pblock2->GetInt(pb_RadioFilterMode); int Radius = (int)pHM->pblock2->GetFloat(pb_SpinRadius); int TriangleMode = pHM->pblock2->GetInt(pb_TriangleMode); BOOL UseDispFilter = pHM->pblock2->GetInt(pb_CheckUseDisp); BOOL DispX = pHM->pblock2->GetInt(pb_CheckDispX); BOOL DispY = pHM->pblock2->GetInt(pb_CheckDispY); BOOL DispZ = pHM->pblock2->GetInt(pb_CheckDispZ); float Chaos = pHM->pblock2->GetFloat(pb_SpinChaos); ///////////////////////////////////////////////////////////////////////////////////// // Calculate the space between each vertices(in Real-World coord.) ///////////////////////////////////////////////////////////////////////////////////// float SpaceWidth = ((float)RealWidth /(float)(BmpWidth - 1)); float SpaceHeight = ((float)RealHeight/(float)(BmpHeight - 1)); float SpaceAlt = ((float)RealAlt / 255.0f); ///////////////////////////////////////////////////////////////////////////////////// // Find the number of vertices and faces ///////////////////////////////////////////////////////////////////////////////////// int NumOfVerts = BmpSize; int NumOfFaces = ((BmpWidth-1)*(BmpHeight-1)) * 2; ///////////////////////////////////////////////////////////////////////////////////// // Setup the mesh ///////////////////////////////////////////////////////////////////////////////////// msh->setNumVerts(NumOfVerts); msh->setNumFaces(NumOfFaces); if(UseTexVerts){ msh->setNumTVerts(NumOfVerts); msh->setNumTVFaces(NumOfFaces); } ///////////////////////////////////////////////////////////////////////////////////// // Usefull variables... ///////////////////////////////////////////////////////////////////////////////////// int x, y; float Alt = 0.0f; Cfloat3 VertBuf; Cfloat3 Disp = {0.0f, 0.0f, 0.0f}; ///////////////////////////////////////////////////////////////////////////////////// // Create the vertices ///////////////////////////////////////////////////////////////////////////////////// int Cpt = 0; //Here we read in the bitmap pixel and convert them into vertex for(Cpt = 0; Cpt < NumOfVerts; Cpt++){ //Convert Cpt in x,y coord x = Cpt % BmpWidth; y = Cpt / BmpHeight; // Calculate the vertex position switch(FilterMode) { case NO_FILTER: //No change is done to the pixel Alt = RGBMixer(Bmp(x, y)->Red, Bmp(x, y)->Green, Bmp(x, y)->Blue); break; case BILINEAR_FILTERING: //The Pixel are averaged with they're left, right, up and down neightbourgs Alt = BilinearFilter(x, y, Radius); break; case CUBIC_FILTERING: //The Pixel are averaged with the pixels surounding himself Alt = CubicFilter(x, y, Radius); break; } // Add displacement to the vertex position if(UseDispFilter) Disp = DisplacementGenerator(SpaceWidth, SpaceHeight, SpaceAlt, Chaos, DispX, DispY, DispZ); // Store and save the final vertex position VertBuf.x = Disp.x + ((0.0f - (RealWidth / 2.0f)) + (SpaceWidth * (float)x)); VertBuf.y = Disp.y + ((0.0f - (RealHeight / 2.0f)) + (SpaceHeight * (float)y)); VertBuf.z = Disp.z + 0.0f - (Alt * RealAlt);/*(0.0f - (Alt * RealAlt)) - (RealAlt / 2.0f);*/ msh->setVert(Cpt, VertBuf.x, VertBuf.y, VertBuf.z); // Generate and save the texture coordinates if(UseTexVerts){ VertBuf.x = (float)x / (float)BmpWidth; VertBuf.y = (float)y / (float)BmpHeight; VertBuf.z = 0.0f; msh->setTVert(Cpt, VertBuf.x, VertBuf.y, VertBuf.z); } } ///////////////////////////////////////////////////////////////////////////////////// // Create the index array ///////////////////////////////////////////////////////////////////////////////////// //This will keep track of the current face to update int FaceIndx = 0; int LineDone = 0; bool InitialMirrorState = TriangleMode == TRIMODE_FAN; bool Mirror = InitialMirrorState; //Here we set the faces Index data for(Cpt = 0; Cpt < (BmpSize-BmpWidth); Cpt++){ //Skip the last pixel of a row, if it's the case... if((Cpt+1) % BmpWidth == 0){ if(TriangleMode != TRIMODE_NORMAL){ LineDone++; Mirror = LineDone % 2 == 0 ? InitialMirrorState : !InitialMirrorState; } continue; } // Generate a quad switch(TriangleMode) { case TRIMODE_NORMAL: GenFace(FaceIndx++, Cpt, Cpt+1, Cpt+BmpWidth, UseTexVerts); GenFace(FaceIndx++, Cpt+BmpWidth, Cpt+1, Cpt+BmpWidth+1, UseTexVerts); break; case TRIMODE_FAN: case TRIMODE_DIAMOND: if(!Mirror){ GenFace(FaceIndx++, Cpt, Cpt+1, Cpt+BmpWidth, UseTexVerts); GenFace(FaceIndx++, Cpt+BmpWidth, Cpt+1, Cpt+BmpWidth+1, UseTexVerts); } else { GenFace(FaceIndx++, Cpt, Cpt+BmpWidth+1, Cpt+BmpWidth, UseTexVerts); GenFace(FaceIndx++, Cpt, Cpt+1, Cpt+BmpWidth+1, UseTexVerts); } Mirror = !Mirror; break; } } ///////////////////////////////////////////////////////////////////////////////////// // Generate normals and bounding box ///////////////////////////////////////////////////////////////////////////////////// //Build normals for us msh->buildNormals(); //Build the bounding box msh->buildBoundingBox(); //Update edge list msh->InvalidateEdgeList(); //RedrawViews(); return TRUE; }