Fix for bug #18228: OpenGL specular did not get the correct view

vector in perspective mode. This is default OpenGL behavior, but
by now this optimization is really insignificant. Works in both
the 3d view and game engine.
This commit is contained in:
Brecht Van Lommel 2009-02-06 19:21:24 +00:00
parent 09099111e3
commit e40803a5b3
14 changed files with 66 additions and 22 deletions

@ -82,7 +82,7 @@ int GPU_set_tpage(struct MTFace *tface);
int GPU_default_lights(void);
int GPU_scene_object_lights(struct Scene *scene, struct Object *ob,
int lay, float viewmat[][4]);
int lay, float viewmat[][4], int ortho);
/* Text render
* - based on moving uv coordinates */

@ -993,6 +993,8 @@ int GPU_default_lights(void)
U.light[2].spec[3]= 1.0;
}
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
glLightfv(GL_LIGHT0, GL_POSITION, U.light[0].vec);
glLightfv(GL_LIGHT0, GL_DIFFUSE, U.light[0].col);
glLightfv(GL_LIGHT0, GL_SPECULAR, U.light[0].spec);
@ -1030,7 +1032,7 @@ int GPU_default_lights(void)
return count;
}
int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[][4])
int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[][4], int ortho)
{
Base *base;
Lamp *la;
@ -1041,6 +1043,10 @@ int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[][4
for(count=0; count<8; count++)
glDisable(GL_LIGHT0+count);
/* view direction for specular is not compute correct by default in
* opengl, so we set the settings ourselfs */
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, (ortho)? GL_FALSE: GL_TRUE);
count= 0;
for(base=scene->base.first; base; base=base->next) {
@ -1127,9 +1133,6 @@ void GPU_state_init(void)
GPU_default_lights();
/* no local viewer, looks ugly in ortho mode */
/* glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, &one); */
glDepthFunc(GL_LEQUAL);
/* scaling matrices */
glEnable(GL_NORMALIZE);

@ -82,6 +82,7 @@ void viewmoveNDOF(int mode);
void view_zoom_mouseloc(float dfac, short *mouseloc);
int view_mouse_depth( float mouse_worldloc[3], short mval[2], int dist);
int get_view3d_ortho(struct View3D *v3d);
int get_view3d_viewplane(int winxi, int winyi, rctf *viewplane, float *clipsta, float *clipend, float *pixsize);
void setwinmatrixview3d(int winx, int winy, struct rctf *rect);

@ -75,6 +75,7 @@
#include "BDR_drawmesh.h"
#include "BSE_drawview.h"
#include "BSE_view.h"
#include "GPU_extensions.h"
#include "GPU_draw.h"
@ -351,9 +352,10 @@ static void draw_textured_begin(Object *ob)
solidtex= 1;
Gtexdraw.islit= -1;
}
else
else {
/* draw with lights in the scene otherwise */
Gtexdraw.islit= GPU_scene_object_lights(G.scene, ob, G.vd->lay, G.vd->viewmat);
Gtexdraw.islit= GPU_scene_object_lights(G.scene, ob, G.vd->lay, G.vd->viewmat, get_view3d_ortho(G.vd));
}
obcol[0]= CLAMPIS(ob->col[0]*255, 0, 255);
obcol[1]= CLAMPIS(ob->col[1]*255, 0, 255);

@ -1579,6 +1579,28 @@ void object_view_settings(Object *ob, float *lens, float *clipsta, float *clipen
}
}
int get_view3d_ortho(View3D *v3d)
{
Camera *cam;
if(v3d->persp==V3D_CAMOB) {
if(v3d->camera && v3d->camera->type==OB_CAMERA) {
cam= v3d->camera->data;
if(cam && cam->type==CAM_ORTHO)
return 1;
else
return 0;
}
else
return 0;
}
if(v3d->persp==V3D_ORTHO)
return 1;
return 0;
}
int get_view3d_viewplane(int winxi, int winyi, rctf *viewplane, float *clipsta, float *clipend, float *pixsize)
{

@ -80,7 +80,7 @@ void KX_BlenderRenderTools::EndFrame(RAS_IRasterizer* rasty)
* has a maximum of 8 lights (simultaneous), so 20 * 8 lights are possible in
* a scene. */
void KX_BlenderRenderTools::ProcessLighting(int layer, const MT_Transform& viewmat)
void KX_BlenderRenderTools::ProcessLighting(RAS_IRasterizer *rasty, int layer, const MT_Transform& viewmat)
{
if(m_lastlightlayer == layer)
return;
@ -101,12 +101,12 @@ void KX_BlenderRenderTools::ProcessLighting(int layer, const MT_Transform& viewm
}
if(enable)
EnableOpenGLLights();
EnableOpenGLLights(rasty);
else
DisableOpenGLLights();
}
void KX_BlenderRenderTools::EnableOpenGLLights()
void KX_BlenderRenderTools::EnableOpenGLLights(RAS_IRasterizer *rasty)
{
if(m_lastlighting == true)
return;
@ -115,7 +115,8 @@ void KX_BlenderRenderTools::EnableOpenGLLights()
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, true);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, (rasty->GetCameraOrtho())? GL_FALSE: GL_TRUE);
if (GLEW_EXT_separate_specular_color || GLEW_VERSION_1_2)
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);

@ -60,9 +60,9 @@ public:
void EndFrame(RAS_IRasterizer* rasty);
void BeginFrame(RAS_IRasterizer* rasty);
void EnableOpenGLLights();
void EnableOpenGLLights(RAS_IRasterizer *rasty);
void DisableOpenGLLights();
void ProcessLighting(int layer, const MT_Transform& viewmat);
void ProcessLighting(RAS_IRasterizer *rasty, int layer, const MT_Transform& viewmat);
void RenderText2D(RAS_TEXT_RENDER_MODE mode,
const char* text,

@ -85,7 +85,7 @@ void GPC_RenderTools::EndFrame(RAS_IRasterizer* rasty)
* has a maximum of 8 lights (simultaneous), so 20 * 8 lights are possible in
* a scene. */
void GPC_RenderTools::ProcessLighting(int layer, const MT_Transform& viewmat)
void GPC_RenderTools::ProcessLighting(RAS_IRasterizer *rasty, int layer, const MT_Transform& viewmat)
{
if(m_lastlightlayer == layer)
return;
@ -106,12 +106,12 @@ void GPC_RenderTools::ProcessLighting(int layer, const MT_Transform& viewmat)
}
if(enable)
EnableOpenGLLights();
EnableOpenGLLights(rasty);
else
DisableOpenGLLights();
}
void GPC_RenderTools::EnableOpenGLLights()
void GPC_RenderTools::EnableOpenGLLights(RAS_IRasterizer *rasty)
{
if(m_lastlighting == true)
return;
@ -120,7 +120,8 @@ void GPC_RenderTools::EnableOpenGLLights()
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, true);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, (rasty->GetCameraOrtho())? GL_FALSE: GL_TRUE);
if (GLEW_EXT_separate_specular_color || GLEW_VERSION_1_2)
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);

@ -65,9 +65,9 @@ public:
void EndFrame(RAS_IRasterizer* rasty);
void BeginFrame(RAS_IRasterizer* rasty);
void EnableOpenGLLights();
void EnableOpenGLLights(RAS_IRasterizer *rasty);
void DisableOpenGLLights();
void ProcessLighting(int layer, const MT_Transform& viewmat);
void ProcessLighting(RAS_IRasterizer *rasty, int layer, const MT_Transform& viewmat);
/* @attention mode is ignored here */
void RenderText2D(RAS_TEXT_RENDER_MODE mode,

@ -255,6 +255,8 @@ public:
/**
*/
virtual const MT_Point3& GetCameraPosition()=0;
virtual bool GetCameraOrtho()=0;
/**
*/
virtual void SetFog(float start,

@ -134,6 +134,7 @@ public:
virtual
void
ProcessLighting(
RAS_IRasterizer *rasty,
int layer,
const MT_Transform& trans
)=0;

@ -517,9 +517,9 @@ bool RAS_MaterialBucket::ActivateMaterial(const MT_Transform& cameratrans, RAS_I
return false;
if (m_material->UsesLighting(rasty))
rendertools->ProcessLighting(RAS_IRenderTools::RAS_LIGHT_OBJECT_LAYER, cameratrans);
rendertools->ProcessLighting(rasty, RAS_IRenderTools::RAS_LIGHT_OBJECT_LAYER, cameratrans);
else
rendertools->ProcessLighting(-1, cameratrans);
rendertools->ProcessLighting(rasty, -1, cameratrans);
return true;
}

@ -59,6 +59,8 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
m_2DCanvas(canvas),
m_fogenabled(false),
m_time(0.0),
m_campos(0.0f, 0.0f, 0.0f),
m_camortho(false),
m_stereomode(RAS_STEREO_NOSTEREO),
m_curreye(RAS_STEREO_LEFTEYE),
m_eyeseparation(0.0),
@ -756,8 +758,9 @@ void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat)
glMatrixMode(GL_PROJECTION);
double* matrix = &mat(0,0);
glLoadMatrixd(matrix);
}
m_camortho= (mat(3, 3) != 0.0f);
}
void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat)
{
@ -767,6 +770,8 @@ void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat)
mat.getValue(matrix);
/* Internally, MT_Matrix4x4 uses doubles (MT_Scalar). */
glLoadMatrixd(matrix);
m_camortho= (mat[3][3] != 0.0f);
}
MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
@ -883,6 +888,10 @@ const MT_Point3& RAS_OpenGLRasterizer::GetCameraPosition()
return m_campos;
}
bool RAS_OpenGLRasterizer::GetCameraOrtho()
{
return m_camortho;
}
void RAS_OpenGLRasterizer::SetCullFace(bool enable)
{

@ -80,6 +80,7 @@ class RAS_OpenGLRasterizer : public RAS_IRasterizer
MT_Matrix4x4 m_viewmatrix;
MT_Matrix4x4 m_viewinvmatrix;
MT_Point3 m_campos;
bool m_camortho;
StereoMode m_stereomode;
StereoEye m_curreye;
@ -168,6 +169,7 @@ public:
);
virtual const MT_Point3& GetCameraPosition();
virtual bool GetCameraOrtho();
virtual void SetFog(
float start,