I’m having problem figuring out how to generate texture coordinates because all the texture info I find on opengl tends to be a single quad with 0.1, 1.1, 1.0, 0.0… Which is not hard to understand but I’m trying to generate text coordinates for a heightmap terrain. How can I calculate these texture coords so i can test if my formula works?
Edit:
I figured if I just used (x / image width) and (z / image height) I could generate texture coordinates that would stretch the texture over the entire terrain but it’s not drawing texture at all.
This is how I store my data array, vertice, normals, texture coords, and indice.
img = SDL_Surface which is just a grayscale image I use for a heightmap. (I’m gonna change this to a different format soon so I can access the RGB values quicker.)
for(int z = 0; z < img->h; z++)
{
for(int x = 0; x < img->w; x++)
{
pixel = ((Uint32*)img->pixels)[z * img->pitch / 4 + x];
temp = pixel & fmt->Rmask;
temp = temp >> fmt->Rshift;
temp = temp << fmt->Rloss;
r = (Uint8)temp/255.0;
vec.x = x;
vec.y = r;
vec.z = z;
//Vertex data
heightMap.push_back(vec.x * tileSize);
heightMap.push_back(vec.y * maxHeight);
heightMap.push_back(vec.z * tileSize);
//Normals
vec.normalize();
heightMap.push_back(vec.x);
heightMap.push_back(vec.y);
heightMap.push_back(vec.z);
//Texture coordinates
heightMap.push_back((float)x / img->w);
heightMap.push_back((float)z / img->h);
//index
if(x < img->w-1 && z < img->h-1)
{
int top = z * img->w + x;
int bottom = top+img->w;//(z+1)*img->w + x;
index.push_back(top);
index.push_back(bottom);
index.push_back(top+1);
index.push_back(bottom);
index.push_back(bottom+1);
index.push_back(top+1);
}
}
}
I generate my texture.
unsigned int loadTexture(const char* name)
{
SDL_Surface* img = IMG_Load(name);
SDL_PixelFormat form={NULL,32,4,0,0,0,0,8,8,8,8,0xff000000,0x00ff0000,0x0000ff00,0x000000ff,0,255};
SDL_Surface* img2 = SDL_ConvertSurface(img,&form,SDL_SWSURFACE);
unsigned int texture;
glGenTextures(1,&texture);
glBindTexture(GL_TEXTURE_2D,texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img2->w, img2->h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, img2->pixels);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
SDL_FreeSurface(img);
SDL_FreeSurface(img2);
return texture;
}
I just call loadTexture when I create my terrain VBO and IBO. (I believe a GL_ELEMENT_ARRAY_BUFFER is called IBO (index buffer object), correct me if I’m wrong.)
glGenBuffers(1, &vboModel);
glBindBuffer(GL_ARRAY_BUFFER, vboModel);
glBufferData(GL_ARRAY_BUFFER, heightMap.size()*sizeof(float), heightMap.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glGenBuffers(1, &vboModelInd);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboModelInd);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, index.size()*sizeof(unsigned int), index.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
textureId = loadTexture("grass.bmp");//textureId is a member variable for my heightmap class unsigned int textureId;
This is how I draw the terrain. The vertex and normals are displayed fine but the texture does not show up.
glBindBuffer(GL_ARRAY_BUFFER, vboModel);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboModelInd);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 8*sizeof(float), NULL);
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 8*sizeof(float), (void*)(3*sizeof(float)));
glEnableClientState(GL_TEXTURE_2D_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 8*sizeof(float), (void*)(6*sizeof(float)));
glBindBuffer(GL_TEXTURE_2D, textureId);
glDrawElements(GL_TRIANGLES, index.size(), GL_UNSIGNED_INT, (void*)0);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_2D_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_TEXTURE_2D, 0);