Lighting updates:

Added specular after texture.
Added Light properties: Negative, No Diffuse, No Specular, Quad, Quad2
This commit is contained in:
Kester Maddock 2004-06-07 11:01:31 +00:00
parent 7d840a256e
commit b468bf726c
12 changed files with 146 additions and 45 deletions

@ -49,6 +49,7 @@
#include "RAS_IRasterizer.h"
#include "RAS_LightObject.h"
#include "RAS_ICanvas.h"
#include "RAS_GLExtensionManager.h"
// next two includes/dependencies come from the shadow feature
@ -297,6 +298,9 @@ void KX_BlenderRenderTools::EnableOpenGLLights()
glEnableClientState(GL_NORMAL_ARRAY);
#endif //SLOWPAINT
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, false);
if (bgl::QueryExtension(bgl::_GL_EXT_separate_specular_color) || bgl::QueryVersion(1, 2))
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
}
@ -352,22 +356,18 @@ int KX_BlenderRenderTools::applyLights(int objectlayer)
//std::vector<struct RAS_LightObject*> m_lights;
std::vector<struct RAS_LightObject*>::iterator lit = m_lights.begin();
glPushMatrix();
glLoadMatrixf(m_viewmat);
for (lit = m_lights.begin(), count = 0; !(lit==m_lights.end()) && count < m_numgllights; ++lit)
{
RAS_LightObject* lightdata = (*lit);
if (lightdata->m_layer & objectlayer)
{
glPushMatrix();
glLoadMatrixf(m_viewmat);
vec[0] = (*(lightdata->m_worldmatrix))(0,3);
vec[1] = (*(lightdata->m_worldmatrix))(1,3);
vec[2] = (*(lightdata->m_worldmatrix))(2,3);
vec[3] = 1;
if(lightdata->m_type==RAS_LightObject::LIGHT_SUN) {
vec[0] = (*(lightdata->m_worldmatrix))(0,2);
@ -384,9 +384,9 @@ int KX_BlenderRenderTools::applyLights(int objectlayer)
glLightfv((GLenum)(GL_LIGHT0+count), GL_POSITION, vec);
glLightf((GLenum)(GL_LIGHT0+count), GL_CONSTANT_ATTENUATION, 1.0);
glLightf((GLenum)(GL_LIGHT0+count), GL_LINEAR_ATTENUATION, lightdata->m_att1/lightdata->m_distance);
// without this next line it looks backward compatible.
//attennuation still is acceptable
// glLightf((GLenum)(GL_LIGHT0+count), GL_QUADRATIC_ATTENUATION, la->att2/(la->dist*la->dist));
// without this next line it looks backward compatible.
//attennuation still is acceptable
glLightf((GLenum)(GL_LIGHT0+count), GL_QUADRATIC_ATTENUATION, lightdata->m_att2/(lightdata->m_distance*lightdata->m_distance));
if(lightdata->m_type==RAS_LightObject::LIGHT_SPOT) {
vec[0] = -(*(lightdata->m_worldmatrix))(0,2);
@ -402,19 +402,33 @@ int KX_BlenderRenderTools::applyLights(int objectlayer)
else glLightf((GLenum)(GL_LIGHT0+count), GL_SPOT_CUTOFF, 180.0);
}
vec[0]= lightdata->m_energy*lightdata->m_red;
vec[1]= lightdata->m_energy*lightdata->m_green;
vec[2]= lightdata->m_energy*lightdata->m_blue;
vec[3]= 1.0;
if (lightdata->m_nodiffuse)
{
vec[0] = vec[1] = vec[2] = vec[3] = 0.0;
} else {
vec[0]= lightdata->m_energy*lightdata->m_red;
vec[1]= lightdata->m_energy*lightdata->m_green;
vec[2]= lightdata->m_energy*lightdata->m_blue;
vec[3]= 1.0;
}
glLightfv((GLenum)(GL_LIGHT0+count), GL_DIFFUSE, vec);
if (lightdata->m_nospecular)
{
vec[0] = vec[1] = vec[2] = vec[3] = 0.0;
} else if (lightdata->m_nodiffuse) {
vec[0]= lightdata->m_energy*lightdata->m_red;
vec[1]= lightdata->m_energy*lightdata->m_green;
vec[2]= lightdata->m_energy*lightdata->m_blue;
vec[3]= 1.0;
}
glLightfv((GLenum)(GL_LIGHT0+count), GL_SPECULAR, vec);
glEnable((GLenum)(GL_LIGHT0+count));
count++;
glPopMatrix();
}
}
glPopMatrix();
return count;

@ -359,7 +359,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
}
Material* ma = give_current_material(blenderobj, 1);
Material* ma = give_current_material(blenderobj, 1 /* mface->mat_nr */);
const char* matnameptr = (ma ? ma->id.name : "");
@ -372,8 +372,8 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
if (ma)
{
polymat->m_specular = MT_Vector3(ma->spec * ma->specr,ma->spec * ma->specg,ma->spec * ma->specb);
polymat->m_shininess = (float)ma->har;
polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec;
polymat->m_shininess = (float)ma->har/4.0; // 0 < ma->har <= 512
} else
{
@ -809,6 +809,7 @@ static KX_LightObject *gamelight_from_blamp(Lamp *la, unsigned int layerflag, KX
KX_LightObject *gamelight;
lightobj.m_att1 = la->att1;
lightobj.m_att2 = (la->mode & LA_QUAD)?la->att2:0.0;
lightobj.m_red = la->r;
lightobj.m_green = la->g;
lightobj.m_blue = la->b;
@ -818,6 +819,16 @@ static KX_LightObject *gamelight_from_blamp(Lamp *la, unsigned int layerflag, KX
lightobj.m_spotblend = la->spotblend;
lightobj.m_spotsize = la->spotsize;
lightobj.m_nodiffuse = (la->mode & LA_NO_DIFF) != 0;
lightobj.m_nospecular = (la->mode & LA_NO_SPEC) != 0;
if (la->mode & LA_NEG)
{
lightobj.m_red = -lightobj.m_red;
lightobj.m_green = -lightobj.m_green;
lightobj.m_blue = -lightobj.m_blue;
}
if (la->type==LA_SUN) {
lightobj.m_type = RAS_LightObject::LIGHT_SUN;
} else if (la->type==LA_SPOT) {

@ -52,6 +52,7 @@
#include "RAS_IRasterizer.h"
#include "RAS_LightObject.h"
#include "RAS_ICanvas.h"
#include "RAS_GLExtensionManager.h"
// next two includes/dependencies come from the shadow feature
// it needs the gameobject and the sumo physics scene for a raycast
@ -153,6 +154,15 @@ int GPC_RenderTools::ProcessLighting(int layer)
return result;
}
void GPC_RenderTools::EnableOpenGLLights()
{
glEnable(GL_LIGHTING);
glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
glEnableClientState(GL_NORMAL_ARRAY);
if (bgl::QueryExtension(bgl::_GL_EXT_separate_specular_color) || bgl::QueryVersion(1, 2))
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
}
void GPC_RenderTools::RenderText2D(RAS_TEXT_RENDER_MODE mode,
const char* text,
@ -368,9 +378,9 @@ int GPC_RenderTools::applyLights(int objectlayer)
glLightfv((GLenum)(GL_LIGHT0+count), GL_POSITION, vec);
glLightf((GLenum)(GL_LIGHT0+count), GL_CONSTANT_ATTENUATION, 1.0);
glLightf((GLenum)(GL_LIGHT0+count), GL_LINEAR_ATTENUATION, lightdata->m_att1/lightdata->m_distance);
// without this next line it looks backward compatible.
//attennuation still is acceptable
// glLightf((GLenum)(GL_LIGHT0+count), GL_QUADRATIC_ATTENUATION, la->att2/(la->dist*la->dist));
// without this next line it looks backward compatible.
//attennuation still is acceptable
glLightf((GLenum)(GL_LIGHT0+count), GL_QUADRATIC_ATTENUATION, lightdata->m_att2/(lightdata->m_distance*lightdata->m_distance));
if(lightdata->m_type==RAS_LightObject::LIGHT_SPOT) {
vec[0] = -(*(lightdata->m_worldmatrix))(0,2);
@ -386,11 +396,25 @@ int GPC_RenderTools::applyLights(int objectlayer)
else glLightf((GLenum)(GL_LIGHT0+count), GL_SPOT_CUTOFF, 180.0);
}
vec[0]= lightdata->m_energy*lightdata->m_red;
vec[1]= lightdata->m_energy*lightdata->m_green;
vec[2]= lightdata->m_energy*lightdata->m_blue;
vec[3]= 1.0;
if (lightdata->m_nodiffuse)
{
vec[0] = vec[1] = vec[2] = vec[3] = 0.0;
} else {
vec[0]= lightdata->m_energy*lightdata->m_red;
vec[1]= lightdata->m_energy*lightdata->m_green;
vec[2]= lightdata->m_energy*lightdata->m_blue;
vec[3]= 1.0;
}
glLightfv((GLenum)(GL_LIGHT0+count), GL_DIFFUSE, vec);
if (lightdata->m_nospecular)
{
vec[0] = vec[1] = vec[2] = vec[3] = 0.0;
} else if (lightdata->m_nodiffuse) {
vec[0]= lightdata->m_energy*lightdata->m_red;
vec[1]= lightdata->m_energy*lightdata->m_green;
vec[2]= lightdata->m_energy*lightdata->m_blue;
vec[3]= 1.0;
}
glLightfv((GLenum)(GL_LIGHT0+count), GL_SPECULAR, vec);
glEnable((GLenum)(GL_LIGHT0+count));

@ -67,13 +67,7 @@ public:
glDisableClientState(GL_NORMAL_ARRAY);
}
void EnableOpenGLLights()
{
glEnable(GL_LIGHTING);
glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
glEnableClientState(GL_NORMAL_ARRAY);
}
void EnableOpenGLLights();
int ProcessLighting(int layer);

@ -327,7 +327,7 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode)
return false;
// SYS_WriteCommandLineInt(syshandle, "fixedtime", 0);
SYS_WriteCommandLineInt(syshandle, "vertexarrays",1);
// SYS_WriteCommandLineInt(syshandle, "vertexarrays",1);
//bool properties = (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0);
//bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0);
bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0);

@ -98,6 +98,9 @@ PyObject* KX_LightObject::_getattr(const STR_String& attr)
if (attr == "lin_attenuation")
return PyFloat_FromDouble(m_lightobj.m_att1);
if (attr == "quad_attenuation")
return PyFloat_FromDouble(m_lightobj.m_att2);
if (attr == "spotsize")
return PyFloat_FromDouble(m_lightobj.m_spotsize);
@ -165,6 +168,12 @@ int KX_LightObject::_setattr(const STR_String& attr, PyObject *pyvalue)
return 0;
}
if (attr == "quad_attenuation")
{
m_lightobj.m_att2 = value;
return 0;
}
if (attr == "spotsize")
{
m_lightobj.m_spotsize = value;

@ -23,13 +23,19 @@ class KX_Light(KX_GameObject):
@ivar NORMAL: A point light source. See attribute 'type'
@ivar type: The type of light - must be SPOT, SUN or NORMAL
@ivar layer: The layer mask that this light affects object on. (bitfield)
@ivar energy: The brightness of this light. (float)
@ivar distance: The maximum distance this light can illuminate. (float) (SPOT and NORMAL lights only)
@ivar layer: The layer mask that this light affects object on.
@type layer: bitfield
@ivar energy: The brightness of this light.
@type energy: float
@ivar distance: The maximum distance this light can illuminate. (SPOT and NORMAL lights only)
@type distance: float
@ivar colour: The colour of this light. Black = [0.0, 0.0, 0.0], White = [1.0, 1.0, 1.0]
@type colour: list [r, g, b]
@ivar color: Synonym for colour.
@ivar lin_attenuation: The linear component of this lights attenuation. (SPOT and NORMAL lights only)
@ivar lin_attenuation: The linear component of this light's attenuation. (SPOT and NORMAL lights only)
@type lin_attenuation: float
@ivar quad_attenuation: The quadratic component of this light's attenuation (SPOT and NORMAL lights only)
@type quad_attenuation: float
@ivar spotsize: The cone angle of the spot light, in degrees. (float) (SPOT lights only)
0.0 <= spotsize <= 180.0. Spotsize = 360.0 is also accepted.
@ivar spotblend: Specifies the intensity distribution of the spot light. (float) (SPOT lights only)

@ -42,7 +42,7 @@ struct RAS_LightObject
LIGHT_NORMAL
};
bool m_modified;
int m_layer;
int m_layer;
float m_energy;
float m_distance;
@ -52,12 +52,15 @@ struct RAS_LightObject
float m_blue;
float m_att1;
float m_att2;
float m_spotsize;
float m_spotblend;
LightType m_type;
MT_CmMatrix4x4* m_worldmatrix;
bool m_nodiffuse;
bool m_nospecular;
};
#endif //__RAS_LIGHTOBJECT_H

@ -265,7 +265,10 @@ bool QueryVersion(int major, int minor)
if (gl_major == 0)
{
STR_String gl_version = STR_String((const char *) glGetString(GL_VERSION));
const char *gl_version_str = (const char *) glGetString(GL_VERSION);
if (!gl_version_str)
return false;
STR_String gl_version = STR_String(gl_version_str);
int i = gl_version.Find('.');
gl_major = gl_version.Left(i).ToInt();
gl_minor = gl_version.Mid(i+1, gl_version.FindOneOf(". ", i+1) - i - 1).ToInt();
@ -308,6 +311,11 @@ to their source. Cunning like a weasel.
******************************************************************************/
#if defined(GL_ATI_pn_triangles)
PFNGLPNTRIANGLESIATIPROC glPNTrianglesiATI;
PFNGLPNTRIANGLESFATIPROC glPNTrianglesfATI;
#endif
} // namespace bgl
@ -327,6 +335,28 @@ static void LinkExtensions()
static bool doDebugMessages = m_debug;
extensions = STR_String((const char *) glGetString(GL_EXTENSIONS)).Explode(' ');
#if defined(GL_ATI_pn_triangles)
if (QueryExtension("GL_ATI_pn_triangles"))
{
glPNTrianglesiATI = reinterpret_cast<PFNGLPNTRIANGLESIATIPROC>(bglGetProcAddress((const GLubyte *) "glPNTrianglesiATI"));
glPNTrianglesfATI = reinterpret_cast<PFNGLPNTRIANGLESFATIPROC>(bglGetProcAddress((const GLubyte *) "glPNTrianglesfATI"));
if (glPNTrianglesiATI && glPNTrianglesfATI) {
EnableExtension(_GL_ATI_pn_triangles);
if (doDebugMessages)
std::cout << "Enabled GL_ATI_pn_triangles" << std::endl;
} else {
std::cout << "ERROR: GL_ATI_pn_triangles implementation is broken!" << std::endl;
}
}
#endif
if (QueryExtension("GL_EXT_separate_specular_color"))
{
EnableExtension(_GL_EXT_separate_specular_color);
if (doDebugMessages)
std::cout << "Detected GL_EXT_separate_specular_color" << std::endl;
}
doDebugMessages = false;
}

@ -38,6 +38,7 @@
#include <GL/gl.h>
#endif
#include "EXT_separate_specular_color.h"
namespace bgl
{
@ -363,8 +364,12 @@ namespace bgl
*/
void InitExtensions(int debug);
#if defined(GL_ATI_pn_triangles)
extern PFNGLPNTRIANGLESIATIPROC glPNTrianglesiATI;
extern PFNGLPNTRIANGLESFATIPROC glPNTrianglesfATI;
#endif
} /* namespace bgl */
#endif /* __RAS_GLEXTENSIONMANAGER_H__ */

@ -48,6 +48,8 @@
#include "MT_CmMatrix4x4.h"
#include "RAS_IRenderTools.h" // rendering text
#include "RAS_GLExtensionManager.h"
RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
:RAS_IRasterizer(canvas),
@ -126,6 +128,7 @@ static void Myinit_gl_stuff(void)
}
glPolygonStipple(patc);
}
@ -264,6 +267,8 @@ void RAS_OpenGLRasterizer::Exit()
glBlendFunc(GL_ONE, GL_ZERO);
glDisable(GL_LIGHTING);
if (bgl::QueryExtension(bgl::_GL_EXT_separate_specular_color) || bgl::QueryVersion(1, 2))
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
EndFrame();
}

@ -468,7 +468,7 @@ for i in glext_h:
fns = []
fnlist = []
if (ext != ""):
line = re.search('.*(gl.*) \(.*\);', i)
line = re.search('.* (gl.*) \(.*\);', i)
if (line):
fns += [line.group(1)]
line = re.search('.*PFN(.*)PROC.*', i)
@ -501,7 +501,7 @@ for i in glext_h:
fns = []
fnlist = []
if (ext != ""):
line = re.search('.*(gl.*) \(.*\);', i)
line = re.search('.* (gl.*) \(.*\);', i)
if (line):
fns += [line.group(1)]
line = re.search('.*PFN(.*)PROC.*', i)
@ -534,7 +534,7 @@ for i in glext_h:
fns = []
fnlist = []
if (ext != ""):
line = re.search('.*(gl.*) \(.*\);', i)
line = re.search('.* (gl.*) \(.*\);', i)
if (line):
fns += [line.group(1)]
line = re.search('.*PFN(.*)PROC.*', i)
@ -578,7 +578,7 @@ for i in glext_h:
if (line):
defines += [(line.group(1), line.group(2))]
line = re.search('(.*)(gl.*)(\(.*\));', i) # GLAPI void APIENTRY glMultiTexCoord2f (GLenum, GLfloat, GLfloat);
line = re.search('(.* )(gl.*)(\(.*\));', i) # GLAPI void APIENTRY glMultiTexCoord2f (GLenum, GLfloat, GLfloat);
if (line):
fns += [(line.group(1), line.group(2), line.group(3))]