How to simplify these redundancy statements? say light.....

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_direction);

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_direction);

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);

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

[QUOTE=GClements;1265919]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[/QUOTE]

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.

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.

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);

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.

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.

[QUOTE=Alfonse Reinheart;1265926]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.[/QUOTE]
I see you are correct. but regulation is made by man, why not be changed by man if we endeavor?

[QUOTE=Alfonse Reinheart;1265926]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.[/QUOTE]

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

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).

[QUOTE=GClements;1265930]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).[/QUOTE]
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.

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/////////////
[b]void lightsource(int i, struct light lit)[/b] {
	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);  
 }

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.

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;

[QUOTE=mbentrup;1265954]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;

[/QUOTE]

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

[QUOTE=reader1;1265956]why is it also able to get through vompilr?
what is 48,50…?[/QUOTE]

Those are the character codes of ‘0’, ‘1’ and ‘2’. Try

printf("%d
", '0');

[QUOTE=mbentrup;1265957]Those are the character codes of ‘0’, ‘1’ and ‘2’. Try

printf("%d
", '0');

[/QUOTE]
why ave to pass 48, 49 and 50 for light 0, light 1 or light 2.
it is light0, not light 0.

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

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, but C doesn’t require that. The ASCII character code for ‘0’ is 48.

If you do [var]int i = ‘0’;[/var], 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.

[QUOTE=Alfonse Reinheart;1265960]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, but C doesn’t require that. The ASCII character code for ‘0’ is 48.

If you do [var]int i = ‘0’;[/var], 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.[/QUOTE]
mbenrup has already explain at #16 in only a line.
well, I have use no 0,1,… they a only an index