2 open gl questions

Jimmers

Newcomer
First Question: Unless I'm mistaken, when diffuse lighting hits a vertex, it's scattered evenly in all directions. This would seem to ignore normal vectors. When I use diffuse light though, a surface that is parallel to the viewing vector does not reflect at all. Here's the lighting display list I'm currently working with:

Code:
GLuint lighter(void)
{
	GLuint list = 2;
	const GLfloat diffu[] = {1,1,1,1};
	const GLfloat lpos[] = {0,10,40,1};
	const GLfloat attenu[] = {0.1};
	const GLfloat gamb[] = {0,0,0,0};
	glEnable(GL_LIGHT0);
	glNewList(list,GL_COMPILE);
		glLightModelfv(GL_LIGHT_MODEL_AMBIENT,gamb);
		glPushAttrib(GL_LIGHTING_BIT);
		glLightfv(GL_LIGHT0,GL_POSITION,lpos);
		glLightfv(GL_LIGHT0,GL_DIFFUSE,diffu);
		glLightfv(GL_LIGHT0,GL_CONSTANT_ATTENUATION,attenu);
		glPopAttrib();
	glEndList();
	return list;
}

..and the surface that's parallel to the viewing vector:

Code:
GLuint ground(void)
{
	GLuint list = 1;
	const GLfloat ambdiffu[] = {0.5,0.5,0.5,1.0};
	glNewList(list,GL_COMPILE);
		glPushAttrib(GL_LIGHTING_BIT);
		glVertexPointer(3,GL_INT,0,fl0verts);
		glColorPointer(4,GL_FLOAT,0,fl0colors);
		glNormalPointer(GL_FLOAT,0,fl0normals);
		glTexCoordPointer(2,GL_INT,0,fl0tcoords);
		glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,ambdiffu);
		glDrawArrays(GL_POLYGON,0,4);
		glPopAttrib();
	glEndList();
	return list;
}

Question 2: Can someone post up some working mipmapping code? I can't get mipmapping to work, either with explicitly define the mip layers with glTexImage2D() or glBuild2DMipmaps().

Thanks for any help in advance.
 
A1: you are a bit mistaken re diffuse lighting: its reflection vector disperses evenly in all directions, but the "power" of this reflection is determined by the incident angle. hence it's determined by the normal of the vertex.

A2: post your non-working code. you may be setting some state wrong.
 
Thanks for the replies. Here's the failed mipmapping code:

Code:
SDL_Surface *tex[__TEXTURE_NUM];
GLuint tx[__TEXTURE_NUM];

void texturefetch(void)
{
        glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_BLEND);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
        glGenTextures(__TEXTURE_NUM,&tx[0]);    /* gen textures */
        tex[0] = SDL_LoadBMP("./brick02.bmp");  /* fetch texture 1 */
        if(!tex[0])
        {
                fprintf(stderr,"Error: texture 'brick02' failed to load: %s\n",SDL_GetError());
        }
        glBindTexture(GL_TEXTURE_2D,tx[0]);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST_MIPMAP_NEAREST);
        glTexImage2D(GL_TEXTURE_2D,0,3,tex[0]->w,tex[0]->h,0,GL_BGR,GL_UNSIGNED_BYTE,tex[0]->pixels);
        SDL_FreeSurface(tex);
        tex[1] = SDL_LoadBMP("./bmip.bmp");     /* fetch texture 1 mip 1 */
        if(!tex[1])
        {
                fprintf(stderr,"Error: texture 'bmip' failed to load: %s\n",SDL_GetError());
        }
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST_MIPMAP_NEAREST);
        glTexImage2D(GL_TEXTURE_2D,1,3,tex[1]->w,tex[1]->h,0,GL_BGR,GL_UNSIGNED_BYTE,tex[1]->pixels);
        SDL_FreeSurface(tex);
        tex[2] = SDL_LoadBMP("./fig6.bmp");     /* fetch texture 2 */
        if(!tex[2])
        {
                fprintf(stderr,"Error: texture 'fig6' failed to load: %s\n",SDL_GetError());
        }
        glBindTexture(GL_TEXTURE_2D,tx[1]);
        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,3,tex[2]->w,tex[2]->h,0,GL_BGR,GL_UNSIGNED_BYTE,tex[2]->pixels);
        SDL_FreeSurface(tex);
}
 
You need to supply the complete mip chain:
opengl.org said:
If texturing is enabled (and TEXTURE_MIN_FILTER is one that requires a mipmap) at the time a primitive is rasterized and if the set of arrays 0 through p is incomplete, based on the dimensions of array 0, then it is as if texture mapping were disabled.
So if your base texture is 64x64, then you need to provide the base texture plus 6 mipmaps.
 
Like mentioned above you need to specify a complete mipmap stack, but I think you might have some other confusion because gluBuild2DMipmaps was not working either. One of the issues might be that you are confused about texture obects a bit. The texture and all the texture parameters are packed into a texture object, so the calls you have to glTexParameter before you bind a texture object are simply modifying the last bound texture object. The code really needs to be like this:

glBindTexture( GL_TEXTURE_2D, obj);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
...
glTexImage2D( GL_TEXTURE_2D, 0, ...); // base level
...
glTexImage2D( GL_TEXTURE_2D, n, ..); // lowest level, 1x1 in size

The set of glTexImage calls can be replaced by the glu call for mipmaps. Additionally, you might want to use the automatic mipmap generation parameter to OpenGL for simplicity. It would work like this:

glBindTexture( GL_TEXTURE_2D, obj);
// set the wrap and filter parameters as before
glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAMPS, GL_TRUE);
glTexImage2D( GL_TEXTURE_2D, 0, ...); //only need to load the base level


-Evan
 
Jimmers, what OGLguy and ehart said is essential and most likely comprises your original problem. i can only add to that that you're not really releasing your SDL surfaces by those SDL_FreeSurface() calls you do on your surface array. what you mean is SDL_FreeSurface(tex[n])

ed: actually let me add that your TexEnv() call is also most likely not meant to be where it is now.
 
Last edited by a moderator:
Thanks for all the replies. Here's my revised textureing function (mipmapping on texture 2):

Code:
SDL_Surface *tex;
GLuint tx[__TEXTURE_NUM];

void texturefetch(void)
{
	glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_BLEND);	/* set texture env */
	glGenTextures(__TEXTURE_NUM,&tx[0]);	/* gen textures */
	tex = SDL_LoadBMP("./brick02.bmp");	/* fetch texture 1 */
	if(!tex)
	{
		fprintf(stderr,"Error: texture 'brick02' failed to load: %s\n",SDL_GetError());
	};
	glBindTexture(GL_TEXTURE_2D,tx[0]);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexImage2D(GL_TEXTURE_2D,0,3,tex->w,tex->h,0,GL_BGR,GL_UNSIGNED_BYTE,tex->pixels);
	SDL_FreeSurface(tex);
	tex = SDL_LoadBMP("./drock055.bmp");	/* fetch texture 2 */
	if(!tex)
	{
		fprintf(stderr,"Error: texture 'drock055' failed to load: %s\n",SDL_GetError());
	};
	glBindTexture(GL_TEXTURE_2D,tx[2]);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR);
	/*glTexParameteri(GL_TEXTURE_2D,GL_GENERATE_MIPMAPS,GL_TRUE);
	glTexImage2D(GL_TEXTURE_2D,0,3,tex->w,tex->h,0,GL_BGR,GL_UNSIGNED_BYTE,tex->pixels);*/
	gluBuild2DMipmaps(GL_TEXTURE_2D,3,tex->w,tex->h,GL_BGR,GL_UNSIGNED_BYTE,tex->pixels);
	SDL_FreeSurface(tex);
	tex = SDL_LoadBMP("./fig6.bmp");	/* fetch texture 3 */
	if(!tex)
	{
		fprintf(stderr,"Error: texture 'fig6' failed to load: %s\n",SDL_GetError());
	}
	glBindTexture(GL_TEXTURE_2D,tx[1]);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexImage2D(GL_TEXTURE_2D,0,3,tex->w,tex->h,0,GL_BGR,GL_UNSIGNED_BYTE,tex->pixels);
	SDL_FreeSurface(tex);
}

@ehart:
GL_GENERATE_MIPMAPS isn't mentioned in the manpage for glTexParameteri(), and passing it causes errors in compilation.

I think gluBuild2DMipmaps worked this time around, since the texture was there instead of my earlier attempts, when just the bare polygon was drawn.
 
It sounds to me like you are likely using Windows. The headers and documentation on that platform are frozen in time at OpenGL 1.1. I believe generate mipmaps was added in OpenGL 1.4, and if your driver supports OpenGL 1.4, you can use it by just using a header file with the updated enumerant. Before OpenGL 1.4, the capability was available as an extension on some hardware. The extension can be found here.

It also looks like I misspelled the enum. It seems it should be GL_GENERATE_MIPMAP.

-Evan
 
I'm using linux here, and glGetString(GL_VERSION) gives me 2.0.0 on my desktop and 1.3 on my laptop (all in software though, no ppc binaries for ati drivers).

Should I look for updated headers, and how would I implement them? Just replace /usr/include/gl.h?

EDIT: I did get it to GL_GENERATE_MIPMAP to work. I guess I should ask where I could get gl 2.0 manpages.
 
Last edited by a moderator:
Looks to me like you have the Min and Mag filters the wrong way round.
This makes the texture inconsistent and therefore disables texturing on that layer.
You want GL_LINEAR on mag filter, and
GL_LINEAR_MIPMAP_LINEAR on min filter.
 
Back
Top