329 lines
13 KiB
C
Executable File
329 lines
13 KiB
C
Executable File
#include "light.h"
|
|
#include "../glx/hardext.h"
|
|
#include "matrix.h"
|
|
#include "matvec.h"
|
|
|
|
void gl4es_glLightModelf(GLenum pname, GLfloat param) {
|
|
//printf("%sglLightModelf(%04X, %.2f)\n", (state.list.compiling)?"list":"", pname, param);
|
|
ERROR_IN_BEGIN
|
|
if(glstate->list.active)
|
|
if ((glstate->list.compiling || glstate->gl_batch)) {
|
|
GLfloat dummy[4];
|
|
dummy[0]=param;
|
|
gl4es_glLightModelfv(pname, dummy);
|
|
return;
|
|
} else flush();
|
|
switch (pname) {
|
|
case GL_LIGHT_MODEL_TWO_SIDE:
|
|
errorGL();
|
|
glstate->light.two_side = param;
|
|
break;
|
|
case GL_LIGHT_MODEL_AMBIENT:
|
|
default:
|
|
errorShim(GL_INVALID_ENUM);
|
|
return;
|
|
}
|
|
LOAD_GLES(glLightModelf);
|
|
gles_glLightModelf(pname, param);
|
|
}
|
|
|
|
void gl4es_glLightModelfv(GLenum pname, const GLfloat* params) {
|
|
//printf("%sglLightModelfv(%04X, [%.2f, %.2f, %.2f, %.2f])\n", (state.list.compiling)?"list":"", pname, params[0], params[1], params[2], params[3]);
|
|
ERROR_IN_BEGIN
|
|
if(glstate->list.active)
|
|
if ((glstate->list.compiling || glstate->gl_batch)) {
|
|
NewStage(glstate->list.active, STAGE_LIGHTMODEL);
|
|
/* if (glstate->list.active->lightmodel)
|
|
glstate->list.active = extend_renderlist(glstate->list.active);*/
|
|
glstate->list.active->lightmodelparam = pname;
|
|
glstate->list.active->lightmodel = (GLfloat*)malloc(4*sizeof(GLfloat));
|
|
memcpy(glstate->list.active->lightmodel, params, 4*sizeof(GLfloat));
|
|
noerrorShim();
|
|
return;
|
|
} else flush();
|
|
switch (pname) {
|
|
case GL_LIGHT_MODEL_AMBIENT:
|
|
if(memcmp(glstate->light.ambient, params, 4*sizeof(GLfloat))==0) {
|
|
noerrorShim();
|
|
return;
|
|
}
|
|
errorGL();
|
|
memcpy(glstate->light.ambient, params, 4*sizeof(GLfloat));
|
|
break;
|
|
case GL_LIGHT_MODEL_TWO_SIDE:
|
|
if(glstate->light.two_side == params[0]) {
|
|
noerrorShim();
|
|
return;
|
|
}
|
|
errorGL();
|
|
glstate->light.two_side = params[0];
|
|
break;
|
|
default:
|
|
errorShim(GL_INVALID_ENUM);
|
|
return;
|
|
}
|
|
LOAD_GLES(glLightModelfv);
|
|
gles_glLightModelfv(pname, params);
|
|
}
|
|
|
|
void gl4es_glLightfv(GLenum light, GLenum pname, const GLfloat* params) {
|
|
//printf("%sglLightfv(%s, %s, %p=[%.2f, %.2f, %.2f, %.2f])\n", (glstate->list.compiling)?"list":"", PrintEnum(light), PrintEnum(pname), params, (params)?params[0]:0.0f, (params)?params[1]:0.0f, (params)?params[2]:0.0f, (params)?params[3]:0.0f);
|
|
const int nl = light-GL_LIGHT0;
|
|
if(nl<0 || nl>=hardext.maxlights) {
|
|
errorShim(GL_INVALID_ENUM);
|
|
return;
|
|
}
|
|
ERROR_IN_BEGIN
|
|
if(glstate->list.active)
|
|
if (glstate->list.compiling || glstate->gl_batch) {
|
|
NewStage(glstate->list.active, STAGE_LIGHT);
|
|
rlLightfv(glstate->list.active, light, pname, params);
|
|
noerrorShim();
|
|
return;
|
|
} else flush();
|
|
|
|
GLfloat tmp[4];
|
|
noerrorShim();
|
|
switch(pname) {
|
|
case GL_AMBIENT:
|
|
if(memcmp(glstate->light.lights[nl].ambient, params, 4*sizeof(GLfloat))==0)
|
|
return;
|
|
memcpy(glstate->light.lights[nl].ambient, params, 4*sizeof(GLfloat));
|
|
break;
|
|
case GL_DIFFUSE:
|
|
if(memcmp(glstate->light.lights[nl].diffuse, params, 4*sizeof(GLfloat))==0)
|
|
return;
|
|
memcpy(glstate->light.lights[nl].diffuse, params, 4*sizeof(GLfloat));
|
|
break;
|
|
case GL_SPECULAR:
|
|
if(memcmp(glstate->light.lights[nl].specular, params, 4*sizeof(GLfloat))==0)
|
|
return;
|
|
memcpy(glstate->light.lights[nl].specular, params, 4*sizeof(GLfloat));
|
|
break;
|
|
case GL_POSITION:
|
|
vector_matrix(params, getMVMat(), tmp);
|
|
if(memcmp(glstate->light.lights[nl].position, tmp, 4*sizeof(GLfloat))==0)
|
|
return;
|
|
memcpy(glstate->light.lights[nl].position, tmp, 4*sizeof(GLfloat));
|
|
break;
|
|
case GL_SPOT_DIRECTION:
|
|
memcpy(tmp, params, 3*sizeof(GLfloat));
|
|
tmp[3] = 0.0f;
|
|
vector_matrix(tmp, getMVMat(), tmp);
|
|
if(memcmp(glstate->light.lights[nl].spotDirection, tmp, 4*sizeof(GLfloat))==0)
|
|
return;
|
|
memcpy(glstate->light.lights[nl].spotDirection, tmp, 4*sizeof(GLfloat));
|
|
break;
|
|
case GL_SPOT_EXPONENT:
|
|
if(params[0]<0 || params[0]>128) {
|
|
errorShim(GL_INVALID_VALUE);
|
|
return;
|
|
}
|
|
if(glstate->light.lights[nl].spotExponent == params[0])
|
|
return;
|
|
glstate->light.lights[nl].spotExponent = params[0];
|
|
break;
|
|
case GL_SPOT_CUTOFF:
|
|
if(params[0]<0 || (params[0]>90 && params[0]!=180)) {
|
|
errorShim(GL_INVALID_VALUE);
|
|
return;
|
|
}
|
|
if(glstate->light.lights[nl].spotCutoff == params[0])
|
|
return;
|
|
glstate->light.lights[nl].spotCutoff = params[0];
|
|
break;
|
|
case GL_CONSTANT_ATTENUATION:
|
|
if(params[0]<0) {
|
|
errorShim(GL_INVALID_VALUE);
|
|
return;
|
|
}
|
|
if(glstate->light.lights[nl].constantAttenuation == params[0])
|
|
return;
|
|
glstate->light.lights[nl].constantAttenuation = params[0];
|
|
break;
|
|
case GL_LINEAR_ATTENUATION:
|
|
if(params[0]<0) {
|
|
errorShim(GL_INVALID_VALUE);
|
|
return;
|
|
}
|
|
if(glstate->light.lights[nl].linearAttenuation == params[0])
|
|
return;
|
|
glstate->light.lights[nl].linearAttenuation = params[0];
|
|
break;
|
|
case GL_QUADRATIC_ATTENUATION:
|
|
if(params[0]<0) {
|
|
errorShim(GL_INVALID_VALUE);
|
|
return;
|
|
}
|
|
if(glstate->light.lights[nl].quadraticAttenuation == params[0])
|
|
return;
|
|
glstate->light.lights[nl].quadraticAttenuation = params[0];
|
|
break;
|
|
}
|
|
LOAD_GLES(glLightfv);
|
|
gles_glLightfv(light, pname, params);
|
|
errorGL();
|
|
}
|
|
|
|
void gl4es_glLightf(GLenum light, GLenum pname, const GLfloat params) {
|
|
GLfloat dummy[4];
|
|
dummy[0]=params;
|
|
gl4es_glLightfv(light, pname, dummy);
|
|
errorGL();
|
|
}
|
|
|
|
void gl4es_glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) {
|
|
if(glstate->list.active)
|
|
if(glstate->list.begin) {
|
|
// if a glMaterialfv is called inside a glBegin/glEnd block
|
|
// then use rlMaterial to store in current list the material wanted
|
|
// as if the material was asked before the glBegin()
|
|
// It's not real behavour, but it's better then nothing
|
|
rlMaterialfv(glstate->list.active, face, pname, params);
|
|
noerrorShim();
|
|
return;
|
|
} else {
|
|
if (glstate->list.compiling || glstate->gl_batch) {
|
|
NewStage(glstate->list.active, STAGE_MATERIAL);
|
|
rlMaterialfv(glstate->list.active, face, pname, params);
|
|
noerrorShim();
|
|
return;
|
|
} else flush();
|
|
}
|
|
if(face!=GL_FRONT_AND_BACK && face!=GL_FRONT && face!=GL_BACK) {
|
|
errorShim(GL_INVALID_ENUM);
|
|
return;
|
|
}
|
|
switch(pname) {
|
|
case GL_AMBIENT:
|
|
if(face==GL_FRONT_AND_BACK || face==GL_FRONT)
|
|
memcpy(glstate->material.front.ambient, params, 4*sizeof(GLfloat));
|
|
if(face==GL_FRONT_AND_BACK || face==GL_BACK)
|
|
memcpy(glstate->material.back.ambient, params, 4*sizeof(GLfloat));
|
|
break;
|
|
case GL_DIFFUSE:
|
|
if(face==GL_FRONT_AND_BACK || face==GL_FRONT)
|
|
memcpy(glstate->material.front.diffuse, params, 4*sizeof(GLfloat));
|
|
if(face==GL_FRONT_AND_BACK || face==GL_BACK)
|
|
memcpy(glstate->material.back.diffuse, params, 4*sizeof(GLfloat));
|
|
break;
|
|
case GL_SPECULAR:
|
|
if(face==GL_FRONT_AND_BACK || face==GL_FRONT)
|
|
memcpy(glstate->material.front.specular, params, 4*sizeof(GLfloat));
|
|
if(face==GL_FRONT_AND_BACK || face==GL_BACK)
|
|
memcpy(glstate->material.back.specular, params, 4*sizeof(GLfloat));
|
|
break;
|
|
case GL_EMISSION:
|
|
if(face==GL_FRONT_AND_BACK || face==GL_FRONT)
|
|
memcpy(glstate->material.front.emission, params, 4*sizeof(GLfloat));
|
|
if(face==GL_FRONT_AND_BACK || face==GL_BACK)
|
|
memcpy(glstate->material.back.emission, params, 4*sizeof(GLfloat));
|
|
break;
|
|
case GL_AMBIENT_AND_DIFFUSE:
|
|
if(face==GL_FRONT_AND_BACK || face==GL_FRONT) {
|
|
memcpy(glstate->material.front.ambient, params, 4*sizeof(GLfloat));
|
|
memcpy(glstate->material.front.diffuse, params, 4*sizeof(GLfloat));
|
|
}
|
|
if(face==GL_FRONT_AND_BACK || face==GL_BACK) {
|
|
memcpy(glstate->material.back.ambient, params, 4*sizeof(GLfloat));
|
|
memcpy(glstate->material.back.diffuse, params, 4*sizeof(GLfloat));
|
|
}
|
|
break;
|
|
case GL_SHININESS:
|
|
if(face==GL_FRONT_AND_BACK || face==GL_FRONT)
|
|
glstate->material.front.shininess = *params;
|
|
if(face==GL_FRONT_AND_BACK || face==GL_BACK)
|
|
glstate->material.back.shininess = *params;
|
|
break;
|
|
case GL_COLOR_INDEXES:
|
|
if(face==GL_FRONT_AND_BACK || face==GL_FRONT) {
|
|
glstate->material.front.indexes[0] = params[0];
|
|
glstate->material.front.indexes[1] = params[1];
|
|
glstate->material.front.indexes[2] = params[2];
|
|
}
|
|
if(face==GL_FRONT_AND_BACK || face==GL_BACK) {
|
|
glstate->material.back.indexes[0] = params[0];
|
|
glstate->material.back.indexes[1] = params[1];
|
|
glstate->material.back.indexes[2] = params[2];
|
|
}
|
|
break;
|
|
}
|
|
|
|
if(face==GL_BACK) { // lets ignore GL_BACK in GLES 1.1
|
|
noerrorShim();
|
|
return;
|
|
}
|
|
LOAD_GLES(glMaterialfv);
|
|
gles_glMaterialfv(GL_FRONT_AND_BACK, pname, params);
|
|
errorGL();
|
|
}
|
|
|
|
void gl4es_glMaterialf(GLenum face, GLenum pname, const GLfloat param) {
|
|
ERROR_IN_BEGIN
|
|
if(glstate->list.active)
|
|
if (glstate->list.compiling || glstate->gl_batch) {
|
|
GLfloat params[4];
|
|
memset(params, 0, 4*sizeof(GLfloat));
|
|
params[0] = param;
|
|
NewStage(glstate->list.active, STAGE_MATERIAL);
|
|
rlMaterialfv(glstate->list.active, face, pname, params);
|
|
noerrorShim();
|
|
return;
|
|
} else flush();
|
|
|
|
if(face!=GL_FRONT_AND_BACK && face!=GL_FRONT && face!=GL_BACK) {
|
|
errorShim(GL_INVALID_ENUM);
|
|
return;
|
|
}
|
|
if(pname!=GL_SHININESS) {
|
|
errorShim(GL_INVALID_ENUM);
|
|
return;
|
|
}
|
|
if(face==GL_FRONT_AND_BACK || face==GL_FRONT)
|
|
glstate->material.front.shininess = param;
|
|
if(face==GL_FRONT_AND_BACK || face==GL_BACK)
|
|
glstate->material.back.shininess = param;
|
|
|
|
LOAD_GLES(glMaterialf);
|
|
if(face==GL_BACK) { // lets ignore GL_BACK in GLES 1.1
|
|
noerrorShim();
|
|
return;
|
|
}
|
|
gles_glMaterialf(GL_FRONT_AND_BACK, pname, param);
|
|
errorGL();
|
|
}
|
|
|
|
void gl4es_glColorMaterial(GLenum face, GLenum mode) {
|
|
ERROR_IN_BEGIN
|
|
if(glstate->list.active)
|
|
if (glstate->list.compiling || glstate->gl_batch) {
|
|
NewStage(glstate->list.active, STAGE_COLOR_MATERIAL);
|
|
glstate->list.active->colormat_face = face;
|
|
glstate->list.active->colormat_mode = mode;
|
|
noerrorShim();
|
|
return;
|
|
} else flush();
|
|
|
|
if(face!=GL_FRONT_AND_BACK && face!=GL_FRONT && face!=GL_BACK) {
|
|
errorShim(GL_INVALID_ENUM);
|
|
return;
|
|
}
|
|
if(mode!=GL_EMISSION && mode!=GL_AMBIENT && mode!=GL_DIFFUSE && mode!=GL_SPECULAR && mode!=GL_AMBIENT_AND_DIFFUSE) {
|
|
errorShim(GL_INVALID_ENUM);
|
|
return;
|
|
}
|
|
if(face==GL_FRONT_AND_BACK || face==GL_FRONT)
|
|
glstate->material.front.colormat = mode;
|
|
if(face==GL_FRONT_AND_BACK || face==GL_BACK)
|
|
glstate->material.back.colormat = mode;
|
|
noerrorShim();
|
|
}
|
|
|
|
void glLightModelf(GLenum pname, GLfloat param) AliasExport("gl4es_glLightModelf");
|
|
void glLightModelfv(GLenum pname, const GLfloat* params) AliasExport("gl4es_glLightModelfv");
|
|
void glLightfv(GLenum light, GLenum pname, const GLfloat* params) AliasExport("gl4es_glLightfv");
|
|
void glLightf(GLenum light, GLenum pname, const GLfloat params) AliasExport("gl4es_glLightf");
|
|
void glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) AliasExport("gl4es_glMaterialfv");
|
|
void glMaterialf(GLenum face, GLenum pname, const GLfloat param) AliasExport("gl4es_glMaterialf");
|
|
void glColorMaterial(GLenum face, GLenum mode) AliasExport("gl4es_glColorMaterial");
|