Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
glsmap/smap_rvec2st.c
/* Copyright (c) Mark J. Kilgard, 1998. */ |
/* This program is freely distributable without licensing fees |
and is provided without guarantee or warrantee expressed or |
implied. This program is -not- in the public domain. */ |
#include <math.h> |
#include "glsmapint.h" |
/* (x,y,z) reflection vector --> (s,t) sphere map coordinates */ |
int |
smapRvecToSt(float rvec[3], float st[2]) |
{ |
double m, recipm; |
/* In Section 2.10.4 ("Generating texture coordinates") |
of the OpenGL 1.1 specification, you will find the |
GL_SPHERE_MAP equations: |
n' = normal after transformation to eye coordinates |
u = unit vector from origin to vertex in eye coordinates |
(rx, ry, rz) = u - 2 * n' * transpose(n') * u |
m = 2 * sqrt(rx^2 + ry^2 + (rz + 1)^2)) |
s = rx/m + 0.5 |
t = ry/m + 0.5 |
The equation for calculating (rx, ry, rz) is the |
equation for calculating the reflection vector for |
a surface and observer. The explanation and |
derivation for this equation is found in Roger's |
"Procedural Elements for Computer Graphics" 2nd ed. |
in Section 5-5 ("Determining the Reflection Vector"). |
Note that Roger's convention has the Z axis in |
the opposite direction from the OpenGL convention. */ |
m = 2 * sqrt(rvec[0]*rvec[0] + |
rvec[1]*rvec[1] + |
(rvec[2]+1)*(rvec[2]+1)); |
if (m == 0.0) { |
/* Some point on the sphere map perimeter. */ |
st[0] = 0.0; |
st[1] = 0.5; |
return 0; |
} |
recipm = 1.0/m; |
st[0] = rvec[0]*recipm + 0.5; |
st[1] = rvec[1]*recipm + 0.5; |
return 1; |
} |
/* (s,t) sphere map coordinate --> reflection verctor (x,y,z) */ |
void |
smapStToRvec(float *st, float *rvec) |
{ |
double tmp1, tmp2; |
/* Using algebra to invert the sphere mapping equations |
shown above in smapRvecToSt, you get: |
rx = 2*sqrt(-4*s^2 + 4*s - 4*t^2 + 4*t - 1)*(2*s-1) |
ry = 2*sqrt(-4*s^2 + 4*s - 4*t^2 + 4*t - 1)*(2*t-1) |
rz = -8*s^2 + 8*s - 8*t^2 + 8*t - 3 |
The C code below eliminates common subexpressions. */ |
tmp1 = st[0]*(1-st[0]) + st[1]*(1-st[1]); |
tmp2 = 2 * sqrt(4*tmp1 - 1); |
rvec[0] = tmp2 * (2*st[0]-1); |
rvec[1] = tmp2 * (2*st[1]-1); |
rvec[2] = 8 * tmp1 - 3; |
} |
Copyright © 2008 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2008-02-08