PDA

View Full Version : How to simplify these redundancy statements? say light.....



reader1
04-20-2015, 08:37 AM
Are you bothered to type the below statements? or to see it. How to abridge them to please at seeng them?

glLightfv(light?n)...
How to simplify them in practice?

GLfloat light1_ambient[]={0.2,0.2,0.2,1.0};
GLfloat light1_diffuse[]={1.0,0.0,0.0,1.0};
GLfloat light1_specular[]={1.0,0.6,0.6,1.0};
GLfloat light1_position[]={-3.0,-3.0,3.0,1.0};
GLfloat spot_direction[]={1.0,1.0,-1.0};

GLfloat light2_ambient[]={0.2,0.6,0.2,1.0};
GLfloat light2_diffuse[]={0.0,1.0,0.0,1.0};
GLfloat light2_specular[]={0.0,1.0,0.0,1.0};
GLfloat light2_position[]={-3.0,-3.0,3.0,1.0};
GLfloat spot2_direction[]={1.0,1.0,-1.0};

glLightfv(GL_LIGHT0,GL_DIFFUSE,light0_diffuse);
glLightfv(GL_LIGHT0,GL_POSITION,light0_position);

glLightfv(GL_LIGHT1,GL_AMBIENT,light1_ambient);
glLightfv(GL_LIGHT1,GL_DIFFUSE,light1_diffuse);
glLightfv(GL_LIGHT1,GL_SPECULAR,light1_specular);
glLightfv(GL_LIGHT1,GL_POSITION,light1_position);

glLightf(GL_LIGHT1,GL_SPOT_CUTOFF,30.0);
glLightfv(GL_LIGHT1,GL_SPOT_DIRECTION,spot_directi on);

glLightfv(GL_LIGHT2,GL_AMBIENT,light2_ambient);
glLightfv(GL_LIGHT2,GL_DIFFUSE,light2_diffuse);
glLightfv(GL_LIGHT2,GL_SPECULAR,light2_specular);
glLightfv(GL_LIGHT2,GL_POSITION,light2_position);

glLightf(GL_LIGHT2,GL_SPOT_CUTOFF,30.0);
glLightfv(GL_LIGHT2,GL_SPOT_DIRECTION,spot2_direct ion);

glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient);
glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);
glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);
//////////////////

use struct light {...} light1.2...n;?
struct light {
GLfloat ambient[];
GLfloat diffuse[];
GLfloat specular[];
GLfloat position[];
GLfloat spot_direction[];
} light1, light2,...;
then

light1.ambient[]={....};
...
light2.ambient[]={...};
...
glLightfv(light10;
glLightfv(light2);
...

GClements
04-20-2015, 11:23 AM
How to simplify them in practice?

use struct light {...} light1.2...n;?
Use an array of structs:


struct light {
...
} lights[NUM_LIGHTS];



then

light1.ambient[]={....};
...
light2.ambient[]={...};

That isn't valid C. You need to provide an initialiser for the entire structure. Or for an array of structures, for the entire array.


lights = {
/* light 1 */
{{0.2,0.2,0.2,1.0}, /* ambient */
{1.0,0.0,0.0,1.0}, /* diffuse */
...
},
/* light 2 */
....
};




glLightfv(light1);
glLightfv(light2);

If you store the data in an array, you can use a loop:


for (i = 0; i < NUM_LIGHTS; i++) {
const struct light *l = &lights[i];
glLightfv(GL_LIGHT0+i,GL_DIFFUSE,l->diffuse);
glLightfv(GL_LIGHT0+i,GL_POSITION,l->position);
...
}

The GL_LIGHTn constants are guaranteed to be contiguous, i.e. GL_LIGHTn == GL_LIGHT0+n

reader1
04-20-2015, 06:34 PM
Use an array of structs:


struct light {
...
} lights[NUM_LIGHTS];


That isn't valid C. You need to provide an initialiser for the entire structure. Or for an array of structures, for the entire array.


lights = {
/* light 1 */
{{0.2,0.2,0.2,1.0}, /* ambient */
{1.0,0.0,0.0,1.0}, /* diffuse */
...
},
/* light 2 */
....
};



If you store the data in an array, you can use a loop:


for (i = 0; i < NUM_LIGHTS; i++) {
const struct light *l = &lights[i];
glLightfv(GL_LIGHT0+i,GL_DIFFUSE,l->diffuse);
glLightfv(GL_LIGHT0+i,GL_POSITION,l->position);
...
}

The GL_LIGHTn constants are guaranteed to be contiguous, i.e. GL_LIGHTn == GL_LIGHT0+n

glLightfv(GL_LIGHT0+i,GL_DIFFUSE,l->diffuse);
glLightfv(GL_LIGHT0+i,GL_POSITION,l->position);
The code is still complex, why can't simplify to
glLightfv(light1);
glLightfv(light2);
where lighti(macro or struct) represents all parameters of a light?
ight1.ambient={....};
...
light2.ambient={...};
assignment to each iterm of a struct.

Alfonse Reinheart
04-20-2015, 07:19 PM
Because that's how the API works. You're allowed to change each individual component individually. So if you want to change all of them at once, you have to go through each individual component and change it.

If it's that important to you, just make your own glLightStruct function and pass it structs.

reader1
04-20-2015, 07:39 PM
struct light {
GLfloat ambient[];
GLfloat diffuse[];
GLfloat specular[];
GLfloat position[];
GLfloat spot_direction[];
} light1, light2,...;

light1 = {
ambient = “1.0,0.2,0.3,1.0”,
diffuse = “…”,
speculate = “ … “,

};

Light2 = {
ambient = “1.0,0.2,0.3,1.0”,
diffuse = “…”,
speculate = “ … “,

};
Light3 = {
ambient = “1.0,0.2,0.3,1.0”,
diffuse = “…”,
speculate = “ … “,

};

glLightfv( light1);
glLightfv( light2);

This will not lose any information to wqual to

glLightfv(GL_LIGHT1,GL_AMBIENT,light1_ambient);
glLightfv(GL_LIGHT1,GL_DIFFUSE,light1_diffuse);
glLightfv(GL_LIGHT1,GL_SPECULAR,light1_specular);
glLightfv(GL_LIGHT1,GL_POSITION,light1_position);

glLightfv(GL_LIGHT2,GL_AMBIENT,light2_ambient);
glLightfv(GL_LIGHT2,GL_DIFFUSE,light2_diffuse);
glLightfv(GL_LIGHT2,GL_SPECULAR,light2_specular);
glLightfv(GL_LIGHT2,GL_POSITION,light2_position);

Alfonse Reinheart
04-20-2015, 07:45 PM
Look, I'm not going to try to justify why the OpenGL API is the way it is.

This is the API. That's how it works. Use it or don't, but complaining about it accomplishes nothing.

reader1
04-20-2015, 07:49 PM
Because that's how the API works. .

sO it is how it was.

You're allowed to change each individual component individually. So if you want to change all of them at once, you have to go through each individual component and change it.

I make no sense of this words, pls show me an example,


f it's that important to you, just make your own glLightStruct function and pass i..
I just wish it clear to read, simple to type. and easy to understand.

reader1
04-20-2015, 07:59 PM
Look, I'm not going to try to justify why the OpenGL API is the way it is.

This is the API. That's how it works. Use it or don't, but complaining about it accomplishes nothing.
I see you are correct. but regulation is made by man, why not be changed by man if we endeavor?

reader1
04-20-2015, 08:04 PM
Look, I'm not going to try to justify why the OpenGL API is the way it is.

This is the API. That's how it works. Use it or don't, but complaining about it accomplishes nothing.

To add a function in toolkit, like in glut... I suggest you may have a try. as you are fmiliar with this gl.

GClements
04-21-2015, 09:41 AM
I see you are correct. but regulation is made by man, why not be changed by man if we endeavor?
Because there's no point. The entire fixed-function pipeline is deprecated. If you add a new function which only affects the fixed-function pipeline, old code won't use it because it didn't exist when that code wasn't written and new code won't use it because new code will be using shaders and UBOs instead (and will probably be using per-fragment lighting rather than per-vertex lighting).

And for the most part, OpenGL has avoided adding functions which could easily be implemented by the application in terms of existing functions, unless there is a significant performance benefit to making it part of the implementation (which isn't the case here).

reader1
04-22-2015, 09:00 AM
Because there's no point. The entire fixed-function pipeline is deprecated. If you add a new function which only affects the fixed-function pipeline, old code won't use it because it didn't exist when that code wasn't written and new code won't use it because new code will be using shaders and UBOs instead (and will probably be using per-fragment lighting rather than per-vertex lighting).

And for the most part, OpenGL has avoided adding functions which could easily be implemented by the application in terms of existing functions, unless there is a significant performance benefit to making it part of the implementation (which isn't the case here).
correct. but I haven't yet make sense of their relationship. I wish I will as soon as possible.
befor that, I try a program, it seems work well, I shall poste below. pls check and comment.

reader1
04-22-2015, 09:56 AM
Here it is,


struct light { //light source define

GLfloat position[4];
GLfloat ambient[4];
GLfloat diffuse[4];
GLfloat specular[4];
GLfloat spot_direction[4];
GLfloat spot_cutoff;
};
void lightsource(int i, struct light);//annonc...

void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
GLfloat mat_specular[] = { 1.0, 1.0, 0.0, 1.0 };
GLfloat mat_shininess[] = { 50.0 };

GLfloat Light_Model_Ambient[] = { 0.5 , 0.3 , 0.0 , 1.0 };
glLightModelfv( GL_LIGHT_MODEL_AMBIENT , Light_Model_Ambient );
glShadeModel (GL_SMOOTH);

glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);//
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);

struct light light0 = {
//{0.0,1.0,1.0,1.0},
{0.0, 1.0, 1.0, 1.0}, //position
{0.5, 0.5, 0.5, 1.0}, // ambient
{0.0, 1.0, 1.0, 1.0}, // diffuse
{0.0, 1.0, 1.0, 1.0}, //specular
{0.0, 1.0, 1.0, 1.0}, //spot_light
36 //cut_off
};
struct light light1 = {
{0.0, 1.0, 1.0, 1.0}, //position
{0.6, 0.2, 0.3, 1.0 }, // ambient
{0.0, 1.0, 1.0, 1.0}, // diffuse
{0.3, 0.3, 1.0, 1.0 }, //specular
{1.0, 1.0, 1.0, 1.0}, //spot_light
60 //cut_off
};
struct light light2 = {
{0.0, 1.0, 1.0, 1.0}, //position
{0.6, 0.2, 0.3, 1.0}, // ambient
{0.5, 0.3, 0.5, 1.0}, // diffuse
{0.0, 1.0, 1.0, 1.0 }, //specular
{0.0, 1.0, 1.0, 1.0}, //spot_light
60 //cut_off
};

/////////this seems clear to read///////////it can also be simplified lighsource(light0)....////
lightsource(0,light0);
lightsource(1,light1);
lightsource(2,light2);
///////////////////////////////////

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glEnable(GL_LIGHT2);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
}

///////HERE si function define/////////////
void lightsource(int i, struct light lit) {
GLenum GL_LIGHTi=GL_LIGHT0;
switch(i) {
case '0':
GL_LIGHTi = GL_LIGHT0;
break;
case '1':
GL_LIGHTi = GL_LIGHT1;
break;
case '2':
GL_LIGHTi = GL_LIGHT2;
break;
}
glLightfv(GL_LIGHTi, GL_AMBIENT, lit.ambient);
glLightfv(GL_LIGHTi, GL_DIFFUSE, lit.diffuse);
glLightfv(GL_LIGHTi, GL_SPECULAR, lit.specular);
glLightfv(GL_LIGHTi, GL_POSITION, lit.position);
glLightfv(GL_LIGHTi, GL_SPOT_DIRECTION, lit.spot_direction);
glLightf(GL_LIGHT3,GL_SPOT_CUTOFF,85.0f);
}

reader1
04-22-2015, 07:26 PM
After this process, the panel looks like cleaner, less type, especially there are more lamps lighting.
This is also suit to material and texture, if they are more.
next, try them to be a vector? so that they can be mixed vbo, to keep step up with shader. after all, all is data.

mbentrup
04-23-2015, 06:37 AM
Your switch statement is incorrect, you compare the int i to the character constants '0', '1' and '2'. That way you'd have to pass 48, 49 and 50 for light 0, light 1 or light 2.

You should just do


GLenum GL_LIGHTi=GL_LIGHT0 + i;

reader1
04-23-2015, 07:48 AM
Your switch statement is incorrect, you compare the int i to the character constants '0', '1' and '2'. That way you'd have to pass 48, 49 and 50 for light 0, light 1 or light 2.

You should just do


GLenum GL_LIGHTi=GL_LIGHT0 + i;


why is it also able to get through compile?
what is 48,50....?

mbentrup
04-23-2015, 08:10 AM
why is it also able to get through vompilr?
what is 48,50....?

Those are the character codes of '0', '1' and '2'. Try
printf("%d\n", '0');

reader1
04-23-2015, 08:22 AM
Those are the character codes of '0', '1' and '2'. Try
printf("%d\n", '0');
why ave to pass 48, 49 and 50 for light 0, light 1 or light 2.
it is light0, not light 0.

reader1
04-23-2015, 08:26 AM
and odd enough, in rhe past days, I try GL_LIGHTi=GL_LIGHT0 + i; alwaya cannt get through compile, but, now, it sucess,

however, it gets quit different colors

Alfonse Reinheart
04-23-2015, 08:40 AM
why ave to pass 48, 49 and 50 for light 0, light 1 or light 2.

This is a C thing, not OpenGL. The integer 0 is not the same thing as the character '0'. The latter is a text character, encoded in... well, it's typically ASCII (https://en.wikipedia.org/wiki/ASCII), but C doesn't require that. The ASCII character code for '0' is 48.

If you do int i = '0';, C will happily compile that, storing the character code in 'i'. Whatever encoding your compiler uses, the character code for '0' is almost certainly not 0.

reader1
04-23-2015, 08:59 AM
This is a C thing, not OpenGL. The integer 0 is not the same thing as the character '0'. The latter is a text character, encoded in... well, it's typically ASCII (https://en.wikipedia.org/wiki/ASCII), but C doesn't require that. The ASCII character code for '0' is 48.

If you do int i = '0';, C will happily compile that, storing the character code in 'i'. Whatever encoding your compiler uses, the character code for '0' is almost certainly not 0.
mbenrup has already explain at #16 in only a line.
well, I have use no 0,1,... they a only an index

reader1
04-23-2015, 09:18 AM
This is a C thing, not OpenGL. The integer 0 is not the same thing as the character '0'. The latter is a text character, encoded in... well, it's typically ASCII (https://en.wikipedia.org/wiki/ASCII), but C doesn't require that. The ASCII character code for '0' is 48.

If you do int i = '0';, C will happily compile that, storing the character code in 'i'. Whatever encoding your compiler uses, the character code for '0' is almost certainly not 0.
Im completely out of this miracle things, and waiting to hearing your wonderful lecture next....
go on guy.....how about if use no o,0,1l,...? any influent?
Im listening