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.)
Code :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.
Code :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.)
Code :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.
Code :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);