   Interpolation function
  Hi all!I am trying to interpolate my mesh between two values. At the moment the function works but it won't interpolate. It just renders the final mesh. I hope someone can tell me what I have missed.Here is my function in the HeightMap class that does the calculation for interpolation:void HeightMap::generateDSFmoprh(float roughness){int p1, p2, p3;float t;float minH = 0.0f, maxH = 0.0f;generateDSFractal(roughness); // this function generates the mesh and stores the height value in the vector m_heightsfor (int x = 0; x < m_size; x++){for (int z = 0; z < m_size; z++){p1 = heightIndexAt(x, z);m_heights1[p1] = m_heights[p1]; // store the height values for the first call (start point of interpolation)}}generateDSFractal(roughness); // I then call the function again to generated the destination meshfor (int x1 = 0; x1 < m_size; x1++){for (int z1 = 0; z1 < m_size; z1++){p2 = heightIndexAt(x1, z1);m_heights2[p2] = m_heights[p2]; // store it in another vector (end point of interpolation)}}for (int x1 = 0; x1 < m_size; x1++){for (int z1 = 0; z1 < m_size; z1++){p3 = heightIndexAt(x1, z1);for(t=0; t<=1; t+=0.1) // did I do something wrong here?{m_heights[p3] = (1-t)*m_heights1[p3] + t*m_heights2[p3]; // set final value using linear interpolationminH = min(minH, m_heights[p3]);maxH = max(maxH, m_heights[p3]);}}}// Normalize height field so altitudes fall into range [0,255].for (int i = 0; i < m_size * m_size; ++i)m_heights = 255.0f * (m_heights - minH) / (maxH - minH); }generateDSFmoprh() will then be called by TerrainRender class which reads the m_heights values and generates the vertices and indices to render the mesh + textures. For example :void TerrainRender::GenVert();{heightmap.generateDSPMoprh(); //heightmap is an object of the Heightmap class abovegenerateVerts();}I will then call an instance of TerrainRender class in the main program each time I press Space Bar so for example:TerrainRender terrain;//if press space bar...terrain.GenVert(); // this will be called once every time space bar is pressed//and then in the main loop i will update terrain.draw(); every frameHowever, as I said, it only renders the final mesh value and not every the different interpolation values every frame. I know I am close but I can't really figure out what I have missed. I hope someone could give some advice.Thanks.   
  Remove the loop over t from the inside of the shown function (only the loop, not the loop's body). Instead, make t a parameter of the function. Then go into the rendering loop, and implement the varying t there. I don't know your rendering loop function, but you need to do something similar to this:float t; // current time, e.g. measured in secondsfloat t0 = 0; // the current time at the moment of starting an interpolation; 0 means "no interpolation now"const float T = 1.0f; // the duration of the interpolation, e.g. 1 seconddo { // start of the rendering loop...   // get the current moment of time in seconds   t = getCurrentTime();   // if an interpolation is running ...   if( t0 > 0) { // how long is the interpolation running float tDiff = t-t0; // if the interpolation is done ... if( tDiff >T ) {    // guarantee that the targeted mesh is yielded in    tDiff = T;    // mark that the interpolation has ended    t0 = 0; } // actually interpolate myHeighmap->generateDSFmorph(roughness, tDiff/T);   }...} while(notBreak);Here an event denoting the start of an interpolation would set t0 to the current t.The above code snippets does interpolation in real time. You may want to use frame counting instead, or something other. However, the principle is the same.BTW: Please wrap code longer than a few lines in source tags.   ;  Hi!Thanks for your reply. However , one question :How did you make the scrollable code box? I used "[.code] ... [./code]" tags but that doesn't seem to have the scrolling option.   ;Quote:Original post by jonathancHow did you make the scrollable code box? I used "[.code] ... [./code]" tags but that doesn't seem to have the scrolling option.Use "source" instead of "code". See the F.A.Q. for details.   ;  Thanks again! ;)Right, few more questions if you are so kind to oblige:Quote:Remove the loop over t from the inside of the shown function (only the loop, not the loop's body). Instead, make t a parameter of the functionDo you mean like this? void HeightMap::generateDSFmoprh(float roughness, float t){int p1, p2, p3;float t;float minH = 0.0f, maxH = 0.0f;generateDiamondSquareFractal(roughness);for (int x = 0; x < m_size; x++){for (int z = 0; z < m_size; z++){p1 = heightIndexAt(x, z);m_heights1[p1] = m_heights[p1];}}generateDiamondSquareFractal(roughness);for (int x1 = 0; x1 < m_size; x1++){for (int z1 = 0; z1 < m_size; z1++){p2 = heightIndexAt(x1, z1);m_heights2[p2] = m_heights[p2];}}for (int x1 = 0; x1 < m_size; x1++){for (int z1 = 0; z1 < m_size; z1++){p3 = heightIndexAt(x1, z1);m_heights[p3] = (1-t)*m_heights1[p3] + t*m_heights2[p3];minH = min(minH, m_heights[p3]);maxH = max(maxH, m_heights[p3]);}}// Normalize height field so altitudes fall into range [0,255].for (int i = 0; i < m_size * m_size; ++i)m_heights = 255.0f * (m_heights - minH) / (maxH - minH); }Also, here are the exact implementation of the said function in my code if you kindly could take a look :// generateDSFmorph is called herebool Terrain::generateUsingDiamondSquareFractal(float roughness){   m_heightMap.generateDSFmoprh(roughness);    return generateVertices(); // generates the vertices to be rendered in OpenGL}// This is what happens in main.cpp ://when space bar is pressed this is called:// this is called once during Init as well to render initial meshvoid GenerateTerrain(){if (!g_terrain.generateDSFMoprh(roughness))   throw std::runtime_error("Failed to generate terrain.");}}// this is called every frame:void RenderTerrain(){    // all the shader stuff    g_terrain.draw();  //more shader stuff}//g_terrain.draw() basically takes the vertices generated by call to g_terrain.generateDSFMorph(roughness) and renders them to screenAs you can see, I am not very sure of where I should implement the interpolation. Thanks for any help you can offer!   ;  Hmm, tried your suggestion but don't think it's working. It's not updating at all.Here's my main loop (whats called every frame):void RenderFrame(){//OpenGL update stuff for effectsRenderSkyBox(g_camera.getPosition().x,g_camera.getPosition().y, g_camera.getPosition().z, 1000, 1000, 1000);RenderText();    UpdateTerrainShaderParameters();    glEnable(GL_LIGHTING);    glEnable(GL_LIGHT0);    glLightfv(GL_LIGHT0, GL_POSITION, g_lightDir);BindTexture(g_regions[0].texture, 0);   BindTexture(g_regions[1].texture, 1);   BindTexture(g_regions[2].texture, 2);   BindTexture(g_regions[3].texture, 3); g_terrain.draw();  }I made this new function that will be called each time space bar is pressedvoid GenerateTerrainMorph(){ // get the current moment of time in seconds   t = GetElapsedTimeInSeconds();   // if an interpolation is running ...   if( t0 > 0) { // how long is the interpolation running float tDiff = t-t0; // if the interpolation is done ... if( tDiff >T ) {    // guarantee that the targeted mesh is yielded in    tDiff = T;    // mark that the interpolation has ended    t0 = 0; } // actually interpolate g_terrain.RunMorpha(1.2, tDiff/T);//g_terrain != heightmap//terrain class is the bit that does the rendering /opengl stuff//heightmap class generates the heightfield/map   }}// and this is the original GenerateTerrain() called on Space barvoid GenerateTerrain(){if(!faultline){if (!g_terrain.generateUsingDiamondSquareFractal(HEIGHTMAP_ROUGHNESS))   throw std::runtime_error("Failed to generate terrain.");}else{if (!g_terrain.generateUsingFaultline(ITER))   throw std::runtime_error("Failed to generate terrain.");}}I guess we will have to but the interpolation function inside the RenderFrame loop but I am unsure of how to apply it in this case.;  Also posted the relevant bit of my Terrain/Heightmap class for reference. Hopefully someone can spot what I am missing >< thanks!#include "terrain.h"HeightMap::HeightMap() : m_size(0), m_gridSpacing(0), m_heightScale(1.0f){}HeightMap::~HeightMap(){    destroy();}void HeightMap::generateDSFmoprh(float roughness, float time){int p1, p2, p3;float t;float minH = 0.0f, maxH = 0.0f;generateDSfractal(roughness);for (int x = 0; x < m_size; x++){for (int z = 0; z < m_size; z++){p1 = heightIndexAt(x, z);m_heights1[p1] = m_heights[p1];}}generateDSfractal(roughness);for (int x1 = 0; x1 < m_size; x1++){for (int z1 = 0; z1 < m_size; z1++){p2 = heightIndexAt(x1, z1);m_heights2[p2] = m_heights[p2];}}for (int x1 = 0; x1 < m_size; x1++){for (int z1 = 0; z1 < m_size; z1++){p3 = heightIndexAt(x1, z1);for(t=0; t<=1; t+=0.1){m_heights[p3] = (1-t)*m_heights1[p3] + t*m_heights2[p3];minH = min(minH, m_heights[p3]);maxH = max(maxH, m_heights[p3]);}}}// Normalize height field so altitudes fall into range [0,255].for (int i = 0; i < m_size * m_size; ++i)m_heights = 255.0f * (m_heights - minH) / (maxH - minH); }void HeightMap::generateDSfractal(float roughness){    srand(static_cast<unsigned int>(time(0)));    std::fill(m_heights.begin(), m_heights.end(), 0.0f);    int p1, p2, p3, p4, mid;    float dH = m_size * 0.5f;    float dHFactor = powf(2.0f, -roughness);    float minH = 0.0f, maxH = 0.0f;    for (int w = m_size; w > 0; dH *= dHFactor, w /= 2)    {   // Diamond Step.   for (int z = 0; z < m_size; z += w)   {  for (int x = 0; x < m_size; x += w)  { p1 = heightIndexAt(x, z); p2 = heightIndexAt(x + w, z); p3 = heightIndexAt(x + w, z + w); p4 = heightIndexAt(x, z + w); mid = heightIndexAt(x + w / 2, z + w / 2); m_heights[mid] = Math::random(-dH, dH) + (m_heights[p1] + m_heights[p2] + m_heights[p3] + m_heights[p4]) * 0.25f; minH = min(minH, m_heights[mid]); maxH = max(maxH, m_heights[mid]);  }   }   // Square step.   for (int z = 0; z < m_size; z += w)   {  for (int x = 0; x < m_size; x += w)  { p1 = heightIndexAt(x, z); p2 = heightIndexAt(x + w, z); p3 = heightIndexAt(x + w / 2, z - w / 2); p4 = heightIndexAt(x + w / 2, z + w / 2); mid = heightIndexAt(x + w / 2, z); m_heights[mid] = Math::random(-dH, dH) + (m_heights[p1] + m_heights[p2] + m_heights[p3] + m_heights[p4]) * 0.25f; minH = min(minH, m_heights[mid]); maxH = max(maxH, m_heights[mid]); p1 = heightIndexAt(x, z); p2 = heightIndexAt(x, z + w); p3 = heightIndexAt(x + w / 2, z + w / 2); p3 = heightIndexAt(x - w / 2, z + w / 2); mid = heightIndexAt(x, z + w / 2); m_heights[mid] = Math::random(-dH, dH) + (m_heights[p1] + m_heights[p2] + m_heights[p3] + m_heights[p4]) * 0.25f; minH = min(minH, m_heights[mid]); maxH = max(maxH, m_heights[mid]);  }   }    }    smooth();    // Normalize height field so altitudes fall into range [0,255].    for (int i = 0; i < m_size * m_size; ++i)   m_heights = 255.0f * (m_heights - minH) / (maxH - minH);}// Terrain.//-----------------------------------------------------------------------------Terrain::Terrain(){    m_vertexBuffer = 0;    m_indexBuffer = 0;    m_totalVertices = 0;    m_totalIndices = 0;}Terrain::~Terrain(){    destroy();}bool Terrain::create(int size, int gridSpacing, float scale){    if (!m_heightMap.create(size, gridSpacing, scale))   return false;    return terrainCreate(size, gridSpacing, scale);}void Terrain::destroy(){    m_heightMap.destroy();    terrainDestroy();}void Terrain::draw(){    terrainDraw();}void Terrain::RunMorpha(float roughness, float time){ m_heightMap.generateDSFmoprh(roughness, time);    return generateVertices();}bool Terrain::terrainCreate(int size, int gridSpacing, float scale){    // Initialize the vertex buffer object.// OpenGL code here    return generateIndices();}void Terrain::terrainDraw(){    //OpenGL drawing code that makes use of values generated from generateIndices and generateVertices};  I understood your intention so that you want to have a time dependent interpolation (be it real-time or frames or whatever): At the moment of t0 (using the variable names of my previous post) the 1st mesh should be displayed. At t0+T the 2nd mesh should be displayed. Inbetween an interpolation should be displayed, e.g. at t0+0.5T "half" of the 1st and "half" of the 2nd mesh.If so, then you want to compute the interpolation once per frame, and obviously need a couple of consecutive frames to render the sequence of interpolated meshes until tha target mesh is yielded in. Hence you need a single time moment inside the shown function but not a loop over the time.Next you need to isolate the generation of the raw (i.e. not interpolated) meshes from their rendering. Store a mesh as a member variable. This is the mesh the terrain should render normally, and it renders it "as is". Then, if the event of key pressing occurs, generate another mesh (outside the whown routine) and store it in a second member variable. Also store the moment of time. E.g. so:HeightMap::HeightMap : m_firstMesh(0), m_secondMesh(0), m_resultMesh(0), m_tick(0) { ... }void HeightMap::createNewMesh(float roughness) {   if( m_firstMesh ) { m_tick = getCurrentTime(); m_secondMesh = generateDSFractal(roughness); // more stuff to do; you know it better then I do   }   else { m_tick = 0; m_firstMesh = generateDSFractal(roughness); // more stuff to do; you know it better then I do   }}Notice please that I've defined m_tick as a member variable; in the coarse overview in my previous post I've used t0 as a (more or less) global variable. The above approach is more OOP like, of course.Now, the morph routine can examine the state by looking at m_secondMesh (only do interpolation if one is available) and m_tick (to compute the intermediates). E.g. so:void HeightMap::generateDSFmorph(float time) {   float diff;   if( m_secondMesh ) { m_resultMesh = new int[]; // however you store the heights // compute the interpolation factor float diff = time - m_tick; assert( diff >= 0 ); // make the 2nd mesh the new 1st mesh for the case that the interpoaltion is completed if( diff >= duration) { // duration is the formerly T    delete[] m_firstMesh;    m_firstMesh = m_secondMesh;    m_secondMesh = 0;    m_tick = 0; }   }   // now either interpolate or declare the active mesh being the result   if( m_secondMesh ) { diff /= duration; // iterate over the vertices of the mesh and interpolate for (int x1 = 0; x1 < m_size; x1++) {    for (int z1 = 0; z1 < m_size; z1++) {  int index = heightIndexAt(x1, z1);  m_result[index] = (1.0f-diff)*m_firstMesh[index] + diff*m_secondMesh[index];  // other stuff follows here (like the minH, maxH)    } }   }   else { // no morph target; using the active mesh as result m_resultMesh = m_firstMesh;   }}And finally, the draw method:void HeightMap::draw() {   // use m_result to draw   ...}If you render only on key press (and not on a time based loop), you may test the above by invoking generateDSFmorph(...) with parameters dependent on the pressed key. E.g. for using '0' to '9', you may try something like generateDSFmorph(float(key-'0')/10) and fix m_tick to 0. If you have a time based loop, then look at my previous post.Notice please that I've written the above snippets out of my head without any testing. They may contain mistakes, but I think they show what I mean.   ;  Hi again,I think I found a good youtube clip on what I want to achieve.">Youtube example and the morph can best be viewed at around 1:36-1:42Thanks again for any help you guys can offer!   