GLSL Displacement Mapping

Started by
11 comments, last by sjaakiejj 12 years, 1 month ago

It samples based on glTexParameter, GL_NEAREST means texture2D returns the exact pixel, GL_LINEAR blends the pixel with its neighbors, and so on does more with other parameters.


Due to the fact that I was getting quite a few bugs in the system, and I was losing myself in the code, I have redone a lot of my code now. I still have to rewrite my QuadTree, which would be the last piece of functionality I'm giving a major overhaul.

Perhaps the bug was in the big mess of a system I had, with absolutely 0 software engineering principles, a large cluttered and far too general "GraphicsObject" class, and QuadNode's that performed operations that weren't even related to quadnodes. I'll update you once I've finished my redesign, which will likely be tomorrow. Good thing is that my code is now far more readable than before, and all the seperate bits of functionality are now logically seperated, which should make bug-tracking a lot easier.
Advertisement
Right, apologies that it took a bit longer. I now have the system (pretty much) back into the amount of progress I had made before, with roughly equivalent functionality, and much better designed.

Some of the code I re-used, including the texture-splitting code (though I modified it slightly to use one function, instead of two). That code I have attached below, and now I'm noticing segmentation in the duck picture at some of the edges. I would imagine this is partially what caused the previous issue, but it was possibly hidden by other bugs. I have attached the resulting picture as well. I have also attached a picture of a different, greyscale texture attached to the terrain, zoomed in to the closest position to the terrain. As is visible, the two different textures do line up, but become brighter/darker for the final row/column of pixels on the edge.



/******************************************************************************/
/** Splits the texture into four equally sized squares */
/******************************************************************************/
Texture * TextureManager::splitTexture( Texture * pTexture )
{
unsigned char * data = pTexture->data;
int width = pTexture->width;
int height = pTexture->height;
int n = 4;

/* First we have to correct the texture such that the borders of
the new textures align */
int horizontal = height / 2;
int vertical = width / 2;
unsigned char* nData = data;

for(int i = 0; i < width; i++)
{
nData[horizontal * width + i] = data[horizontal * width + i];
nData[(horizontal-1) * width + i] = nData[horizontal * width + i];
}

for(int i = 0; i < height; i++)
{

nData[width*i + vertical] = nData[width*i + vertical - n];
nData[width*i + vertical + 1] = nData[(width*i + vertical - n) + 1];
nData[width*i + vertical + 2] = nData[(width*i + vertical - n) + 2];
nData[width*i + vertical + 3] = nData[(width*i + vertical - n) + 3];
}

Texture * textures = new Texture[4];

textures[0].data = getRegion(nData, width*n, height, 0, height / 2);
textures[1].data = getRegion(nData, width*n, height, (width/2)*n, height / 2);
textures[2].data = getRegion(nData, width*n, height, 0, 0);
textures[3].data = getRegion(nData, width*n, height, (width / 2) * n, 0);

textures[0].width = textures[1].width = textures[2].width = textures[3].width = width / 2;
textures[0].height = textures[1].height = textures[2].height = textures[3].height = height / 2;

return textures;
}

unsigned char * TextureManager::getRegion(unsigned char* data, int width, int height,
int startX, int startY)
{
int nLength = (width/2) * (height/2);
int halfWidth = width / 2;
int addWidth = width / 2;

unsigned char *newData = new unsigned char[nLength];
int currentIndex = 0;
int dataIndex = 0;

for(int i = startX + startY * width; dataIndex < nLength; i++)
{
if(currentIndex >= halfWidth)
{
currentIndex = 0;
i += addWidth;
}
newData[dataIndex] = data;
currentIndex++; dataIndex++;
}

return newData;
}

I found the major problem... Finally. Afterwards I encountered some minor problems, but I solved them quickly (in fact, I realised what the bug was whilst typing this post). The last standing issue is one I'll have to solve myself, which is the "stitching" effect you get when there's a difference in LOD on the edge (e.g. more detail on one edge makes it misalign slightly with the other edge)

First off, the tiling issue was solved by adding

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);


instead of just using MIN_FILTER. That explains why I didn't see it before, as it was in my older code.

Secondly, I found the major problem that I started this thread for was the fact that OpenGL defaults to GL_REPEAT on GL_TEXTURE_WRAP_{S|T}, and I wasn't setting it to GL_CLAMP anywhere. So adding this solved that problem:

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);


I have attached a picture of the results

This topic is closed to new replies.

Advertisement