summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Martin Storsjo <martin@martin.st> 2009-08-11 18:01:14 +0200
committer Mathias Agopian <mathias@google.com> 2009-08-25 18:35:54 -0700
commite03eaa1551a644e9a13c327d16cc09bfd7649d78 (patch)
treeb38dd00e41613f1a80e22d6e403d21b7d6fec136
parentd914215edf600f811f7ad8cad2eab9049cf859a4 (diff)
Calculate specular lighting correctly
Since the lighting calculations are done in object space, the vector from the object to the viewer also needs to be transformed to object space.
-rw-r--r--include/private/opengles/gl_context.h1
-rw-r--r--opengl/libagl/light.cpp11
2 files changed, 9 insertions, 3 deletions
diff --git a/include/private/opengles/gl_context.h b/include/private/opengles/gl_context.h
index 523aed08e1..67c2dd8068 100644
--- a/include/private/opengles/gl_context.h
+++ b/include/private/opengles/gl_context.h
@@ -287,6 +287,7 @@ struct light_t {
vec4_t normalizedObjPosition;
vec4_t spotDir;
vec4_t normalizedSpotDir;
+ vec4_t objViewer;
GLfixed spotExp;
GLfixed spotCutoff;
GLfixed spotCutoffCosine;
diff --git a/opengl/libagl/light.cpp b/opengl/libagl/light.cpp
index 8ae32cc0f0..f211bcab32 100644
--- a/opengl/libagl/light.cpp
+++ b/opengl/libagl/light.cpp
@@ -216,6 +216,8 @@ static inline void light_picker(ogles_context_t* c)
static inline void validate_light_mvi(ogles_context_t* c)
{
uint32_t en = c->lighting.enabledLights;
+ // Vector from object to viewer, in eye coordinates
+ const vec4_t eyeViewer = { 0, 0, 0x1000, 0 };
while (en) {
const int i = 31 - gglClz(en);
en &= ~(1<<i);
@@ -223,6 +225,9 @@ static inline void validate_light_mvi(ogles_context_t* c)
c->transforms.mvui.point4(&c->transforms.mvui,
&l.objPosition, &l.position);
vnorm3(l.normalizedObjPosition.v, l.objPosition.v);
+ c->transforms.mvui.point4(&c->transforms.mvui,
+ &l.objViewer, &eyeViewer);
+ vnorm3(l.objViewer.v, l.objViewer.v);
}
}
@@ -379,9 +384,9 @@ void lightVertex(ogles_context_t* c, vertex_t* v)
// specular
if (ggl_unlikely(s && l.implicitSpecular.v[3])) {
vec4_t h;
- h.x = d.x;
- h.y = d.y;
- h.z = d.z + 0x10000;
+ h.x = d.x + l.objViewer.x;
+ h.y = d.y + l.objViewer.y;
+ h.z = d.z + l.objViewer.z;
vnorm3(h.v, h.v);
s = dot3(n.v, h.v);
s = (s<0) ? (twoSide?(-s):0) : s;