Files
commandergenius/project/jni/gl4es/src/gl/light.c
T
2017-05-13 13:42:21 +03:00

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