PDA

View Full Version : Light Position&Textures Mapping



Sam Kovalev
11-11-2004, 10:00 AM
Problems will kill me oneday, but not today.
2 questions:
1. I have a room. The 3d coordinates of its two opposite corners are:
(-1,-1.5,0)&(1,1.5,2).How to create point light in the (-0.9,-1.4.0.1)
I need full help.
2. I cant use plenty of textures.I have some texture objects and <Image>(AUX_RGBImageRec* e.g.)
which stores data of pixels(Files-.bmp).I am sending data to <Image> and then create
2DMipmap to the target of my texture object.Then Send new data to <Image> and create
2DMipmap to the target of another tex_object_2D. In the Display unit I am
enabling texture objects using <tex_object_2D>.enable()&<tex_object_2D>.disable().But
the program is mapping all 3D-objects with first(!) texture.What is wrong?
I suppose, my descriptions are full enough.Please help!

iznogoud
11-11-2004, 12:40 PM
Here is how to put a point light in the scene:




glEnable(GL_LIGHTING);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, p->ambient);

...

glLightfv(GL_LIGHT0, GL_POSITION, lights->pos);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, diffuse);

Read the manual pages for the gl functions above
to see the arguments types for the "vectors"
representing the colours and position.

There is a simple way to texture objects and it
is one of two ways -- the first way is to simply
specify the raw texture data every time you render,
and the second way to make a glList of the
texture and call it everytime you need it.
The first way is something like this:



glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, 4, txp->mi, txp->mj, 0, GL_RGBA, GL_UNSIGNED_BYTE, txp->data);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable(GL_TEXTURE_2D);

draw_polygons();

glDisable(GL_TEXTURE_2D);
It does not get much simpler than that! This kind
of stuff works for me, so good luck.

Sam Kovalev
11-11-2004, 01:02 PM
Iznogoud, thanks for help.By the way ,as i understood, in your code #2 mipmaps are created every frame repaint. Yes, its really works. But I want to create mipmaps ones in the program an then only choose texture that i need.Is it possible?

iznogoud
11-11-2004, 07:25 PM
There are no mipmaps in the code fragment I posted.

You can create mipmaps yourself, but I never really
bothered doing it. I know that GLU has functions that
let you automatically generate mipmaps.

Worry about geting your program working first, and
consider mipmaps to be a detail or refinement.

Sam Kovalev
11-11-2004, 09:42 PM
Iznogoud, sorry.I meant you suggestion is based on transfering data to GL_TEXTURE_2D and then enabling it, so if i want another texture to be mapped i have to transfer new data to GL_TEXTURE_2D.I am right!(Is it using video memory of the card)??

iznogoud
11-13-2004, 09:48 AM
Yes. A new texture would imply giving new data to
the pipeline, the new texture data. If you do it
my way, you are simply giving "new" data to the
pipeline for the texture, even if it is the same
texture all the time (this should be obvious).

The way to take advantage of the card's memory is
to specify the texture data initially and "bind"
the texture to some internal OpenGL structure
using the appropriate commands. So the precedure
is as follows:
1) initially, in your initialization routine, while
setting up the texture environment, let OpenGL
know that you need memory for a texture by issuing:
glGenTextures(1, &tex_id);
and then bind the texture id:
glBindTexture(GL_TEXTURE_2D, tex_id);

2) now issue all the above commands to specify all
there is to specify about your texture and how it
will be handled (dump all the commands I wrote
above).

3) In your code, while you render, simply activate
the texture that you want to use for each set of
polygons using:
glBindTexture(GL_TEXTURE_2D, tex_id);
Do not forget the glEnable()/glDisable(); texture
stuff...

Try doing it both ways, piping the data everytime
and using the Bind business. You should see a
difference in performance.

Have you "googled" amy of this at all? Try that:
http://www.geocities.com/SiliconValley/Park/5625/opengl/

SoccerboyO7
11-14-2004, 02:06 PM
I had sort of a related question, so I thought I'd post it in here. Could anyone show me the code to load an image file so I can use it to be textured. I don't need any error checking, I just need the lines that actually load it.

11-14-2004, 05:58 PM
1. For point light on the walls of room, if the a wall is just a polygon, the point light won't work. You need to divide the wall into many small polygons.

iznogoud
11-17-2004, 11:21 AM
Soccerboy (good name),
I use an external program to make my own textures
from images. Basically, because I want to use as
general a texture as I can with regard to the alpha
channel, I take two images, one has the RGB values,
and one has the alpha channel stored in the R value.
I do it with .ppm (P6) files, which are binary raw
data with a small header indicating the size (mi,mj).
The final final that the OpenGL program loads is a
"four channel .ppm-type file" and by this I mean that
there are 4 GLubytes per pixel. I hope you can figure
it out from the declaration and the routine below:

struct my_texture {
GLsizei mi,mj;
GLubyte *data; /* This is really a rank 3 array */
GLuint id; /* the id for binding */
};

/*
* Function to load a texture from a file
*/

int load_texture(struct my_texture *tex, char *file)
{
int fd, len, size;

file[strlen(file)-1] = '\0';

if((fd=open(file,O_RDONLY,0)) < 0) {
fprintf(stderr," e Could not open texture file \"%s\"",file);
return(-1);
}

size = 2*sizeof(tex->mi);

if((len=read(fd,tex,size)) != size) {
fprintf(stderr," e Unexpected EOF 1 (%s). Aborting...",file);
close(fd);
return(1);
/*
} else {
fprintf(stderr," i Loading [%dx%d] texture.\n",tex->mi,tex->mj);
*/
}


size = (tex->mi)*(tex->mj)*4*sizeof(GLubyte);

tex->data = (GLubyte *) malloc(size);
if(tex->data == NULL) {
fprintf(stderr," e Could not allocate %d bytes for texture...",size);
close(fd);
return(-2);
}

//if((len=read(fd,&amp;((tex->data)[0][0][0]),size)) != size) {
if((len=read(fd,tex->data,size)) != size) {
fprintf(stderr," e Unexpected EOF 2 (%s). Aborting...",file);
close(fd);
return(1);
}

close(fd);

return(0);
}If you do not care about using GL_RGBA and want
simple GL_RGB texture data, change all 4's the 3's
in the code. You will still need to read the image
from any file format in which you have it to memory
and dump it out ina form my function can read. This
is left as an exercise to the reader!

The nice thing about how I have set up things is
that you can call glTexImage with the data argument
as texture->data. Simple eh? Good luck.