[Apologies for the length of this post and for not distilling the
problem to its essence.]

I'm doing some prototyping in preparation for preparing a demo of a
tile-based game in OpenGL. The aim is to render a tile map and then
have an animated sprite move around; we can forget the animation for
now.

So, I render the tile map. And then as a first try, I have a texture
move in a raster scan manner over the rendered tile map; we simply use
calls to 'display' as the 'animation' event.

My prototype is based on 'tilebind.c' from the Red Book.

What is below 'works', but I may have identified a(nother) blank in my
understanding of texturing.

If I render the tilemap first, and then attempt to replace one of the
tiles using texture, replacement does not occur; i.e. the case where
the code between //A and //B below is moved to //C.

If, as in the code below, I render the replacement, and then render the
tile map, I get the effect I desire. I suppose I'm thinking of the
optimisation of a once-off rendering of the tilemap and then some
trickery to display sprites (+ replacement of tiles as necessary); but,
now that I think about it, maybe that is silly and/or unnecessary?

In any case I appear to misunderstand some basic of texturing. Any
ideas?

TIA,

Jon C.

--------------------------------------------------------
#define NIM 32

void init(void){
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);

makeCheckImages(); // works
readImage(0); // works
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glGenTextures(NIM, texName);
int i;
for(i = 0; i< NIM; i++){
glBindTexture(GL_TEXTURE_2D, texName[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, IMNC,
IMNR, 0, GL_RGBA, GL_UNSIGNED_BYTE,
image[i]);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
}
//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glEnable(GL_TEXTURE_2D);
}

void raster(int * pr, int * pc, int nCols, int nRows){
++(*pc);
if(*pc == nCols){
*pc = 0;
++(*pr);
if(*pr == nRows){
*pr = 0;
}
}
}

void display(void){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

int r, c, dr = 10, dc = 10, rBegin = -55, cBegin= -55,
rEnd= 55, cEnd= 55;

//A
raster(&rPos, &cPos, 10, 10);
r= rPos*dr + rBegin, c= cPos*dc + cBegin;
printf("rPos, cPos, r, c = %d, %d, %d, %d\n", rPos, cPos, r, c);

glBindTexture(GL_TEXTURE_2D, texName[0]);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f((float)c, (float) r, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f((float)c, (float)(r+dr), 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f((float)(c + dc), (float)(r+dr),
0.0);
glTexCoord2f(1.0, 0.0); glVertex3f((float)(c + dc), (float)(r),
0.0);
glEnd();
//B

int iImage = 0;
for(r = rBegin; r< rEnd; r+= dr){
for(c = cBegin; c< cEnd; c+= dc, iImage++){
glBindTexture(GL_TEXTURE_2D, texName[iImage%NIM]);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f((float)c, (float) r, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f((float)c, (float)(r+dr),
0.0);
glTexCoord2f(1.0, 1.0); glVertex3f((float)(c + dc),
(float)(r+dr), 0.0)
glTexCoord2f(1.0, 0.0); glVertex3f((float)(c + dc), (float)(r),
0.0);
glEnd();
}
}

//C

glFlush();
}
void reshape(int w, int h){
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-60., 60., -60., 60., -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//glTranslatef(0.0, 0.0, -3.6);
}