Fan Zhang, Leilei Xu, Chenjun Tao, Hanqiu Sun. Generalized Linear Perspective Shadow Map Reparameterization. The Chinese University of Hong Kong.
Marc Stamminger and George Drettakis. Perspective Shadow Maps. REVES - INRIA Sophia-Antipolis, France.
Tobias Martin and Tiow-Seng Tan. Anti-aliasing and Continuity with Trapezoidal Shadow Maps. School of Computing, National University of Singapore. Eurographics Symposium on Rendering (2004).
Daniel Scherzer. Robust Shadow Maps for Large Environments. Institute of Computer Graphics. Vienna University of Technology. Austria.
Gary King. Shadow Mapping Algorithms. NVIDIA Corporation.
Cass Everitt. Shadow Mapping. NVIDIA Corporation.
Cass Everitt. Mathematics of Per-Pixel Lighting. NVIDIA Corporation.
Cass Everitt. Projective Texture Mapping. NVIDIA Corporation.
Kirill Dmitriev, Yury Uralsky. Soft shadows using hierarchical min-max shadow maps. NVIDIA Corporation. Game Developers Conference 2007.
Louis Bavoil. Advanced Soft Shadow Mapping Techniques. NVIDIA Corporation. Game Developers Conference 2008.
Simon Kozlov. Perspective Shadow Maps: Care and Feeding. GPU Gems.
William Donnelly, University of Waterloo. Per-Pixel Displacement Mapping with Distance Functions. GPU Gems 2.
Yury Uralsky, NVIDIA Corporation. Efficient Soft-Edged Shadows Using Pixel Shader Branching. GPU Gems 2.
Fabio Policarpo, Perpetual Entertainment; Manuel M. Oliveira, Instituto de Informática—UFRGS. Relaxed Cone Stepping for Relief Mapping. GPU Gems 3. Приложение 1
character.h
#pragma once
#include "ScalarTypes.h" struct character {
int *lines;
scalar *curves;
int numLines;
int numCurves;
}; extern scalar line_offset, curve_offset;
fonts.h
#pragma once
#include "ScalarTypes.h" struct character {
scalar *lines;
scalar *curves;
int numLines;
int numCurves;
};
FrameBuffer.h
#pragma once
#include
#include "fonts.h"
extern bool draw_curve, color_curve;
inline unsigned long RGBA(unsigned char R, unsigned char G, unsigned char B, unsigned char A=0) {
return B | G << 8 | R << 16 | A << 24;
}
inline unsigned char GetR(unsigned long color) {
return (unsigned char)(color >> 16 & 0x000000FF);
}
inline unsigned char GetG(unsigned long color) {
return (unsigned char)(color >> 8 & 0x000000FF);
}
inline unsigned char GetB(unsigned long color) {
return (unsigned char)(color & 0x000000FF);
}
inline unsigned char GetA(unsigned long color) {
return (unsigned char)(color >> 24 & 0x000000FF);
}
class FrameBuffer {
int width, height;
unsigned long *pImage;
BITMAPINFO bi;
public:
FrameBuffer() {
width=height=0;
pImage=NULL;
bi.bmiHeader.biSize=sizeof(BITMAPINFO);
bi.bmiHeader.biWidth=width;
bi.bmiHeader.biHeight=height;
bi.bmiHeader.biPlanes=1;
bi.bmiHeader.biBitCount=32;
bi.bmiHeader.biCompression=BI_RGB;
bi.bmiHeader.biSizeImage=0;
bi.bmiHeader.biXPelsPerMeter=0;
bi.bmiHeader.biYPelsPerMeter=0;
bi.bmiHeader.biClrUsed=0;
bi.bmiHeader.biClrImportant=0;
bi.bmiColors[0].rgbBlue=0;
bi.bmiColors[0].rgbGreen=0;
bi.bmiColors[0].rgbRed=0;
bi.bmiColors[0].rgbReserved=0;
}
void Init(int width, int height) {
FrameBuffer::width=bi.bmiHeader.biWidth=width;
FrameBuffer::height=bi.bmiHeader.biHeight=height;
if (pImage)
delete[] pImage;
pImage=new unsigned long[width*height];
}
inline int GetWidth() {
return width;
}
inline int GetHeight() {
return height;
}
unsigned long ReadPixel(int x, int y) {
return x >= 0 && x < width && y >=0 && y < height ? pImage[x+y*width] : 0;
}
void WritePixel(int x, int y, unsigned long color) {
if (x >= 0 && x < width && y >=0 && y < height)
pImage[x+y*width]=color;
}
void Line(int x0, int y0, int x1, int y1, unsigned long color) {
int
xerr=0, yerr=0,
dx=x1-x0, dy=y1-y0,
incX=dx >= 0 ? 1 : -1, incY=dy >= 0 ? 1 : -1,
d, half_d;
dx=abs(dx);
dy=abs(dy);
d=dx >= dy ? dx : dy;
half_d=d>>1;
for (int i=d; i > 0; i--) {
WritePixel(x0, y0, color);
xerr+=dx;
yerr+=dy;
if (xerr > half_d) {
xerr-=d;
x0+=incX;
}
if (yerr > half_d) {
yerr-=d;
y0+=incY;
}
}
WritePixel(x0, y0, color);
}
void Bezier(Vector p0, Vector p1, Vector p2, unsigned long color, unsigned depth = 4) {
if (depth-- > 0) {
Vector
r0=(p0+p1)/2,
r1=(p1+p2)/2,
s0=(r0+r1)/2;
Bezier(p0, r0, s0, color, depth);
Bezier(s0, r1, p2, color, depth);
}
else {
p0.homogenize3();
p2.homogenize3();
Line((int)floor(p0.X), (int)floor(p0.Y), (int)floor(p2.X), (int)floor(p2.Y), color);
}
}
void DrwaChar(character const *ch, unsigned long color, scalar scale_x, scalar scale_y) {
register int idx;
if (ch->lines)
for (idx = 0; idx < ch->numLines; idx++)
Line(int(ch->lines[idx*4+0]*scale_x), int(ch->lines[idx*4+1]*scale_y), int(ch->lines[idx*4+2]*scale_x), int(ch->lines[idx*4+3]*scale_y), color);
if (ch->curves && draw_curve)
for (idx = 0; idx < ch->numCurves; idx++)
Bezier(
Vector(floor(ch->curves[idx*0xf+0x0]*scale_x/ch->curves[idx*0xf+0x4])*ch->curves[idx*0xf+0x4]+ch->curves[idx*0xf+0x1], floor(ch->curves[idx*0xf+0x2]*scale_y/ch->curves[idx*0xf+0x4])*ch->curves[idx*0xf+0x4]+ch->curves[idx*0xf+0x3], 0.0, ch->curves[idx*0xf+0x4]),
Vector(floor(ch->curves[idx*0xf+0x5]*scale_x/ch->curves[idx*0xf+0x9])*ch->curves[idx*0xf+0x9]+ch->curves[idx*0xf+0x6], floor(ch->curves[idx*0xf+0x7]*scale_y/ch->curves[idx*0xf+0x9])*ch->curves[idx*0xf+0x9]+ch->curves[idx*0xf+0x8], 0.0, ch->curves[idx*0xf+0x9]),
Vector(floor(ch->curves[idx*0xf+0xa]*scale_x/ch->curves[idx*0xf+0xe])*ch->curves[idx*0xf+0xe]+ch->curves[idx*0xf+0xb], floor(ch->curves[idx*0xf+0xc]*scale_y/ch->curves[idx*0xf+0xe])*ch->curves[idx*0xf+0xe]+ch->curves[idx*0xf+0xd], 0.0, ch->curves[idx*0xf+0xe]),
color_curve ? RGBA(0, 255, 0, 0) : color
);
}
void BitBlt(HDC hdc) {
SetDIBitsToDevice(hdc, 0, 0, width, height, 0, 0, 0, height, pImage, &bi, DIB_RGB_COLORS);
}
void BitBlt(HDC hdc, RECT &rt) {
SetDIBitsToDevice(hdc, rt.left, rt.top, rt.right-rt.left, rt.bottom-rt.top, rt.left, rt.top, rt.top, rt.bottom-rt.top, pImage, &bi, DIB_RGB_COLORS);
}
void Clear(unsigned long color=0) {
register unsigned long *cur=pImage, *end=pImage+width*height;
while (cur != end)
*cur++=color;
}
friend FrameBuffer *Up(const FrameBuffer &fb, unsigned int X, unsigned int Y) {
FrameBuffer *UpBuffer=new FrameBuffer;
UpBuffer->Init(fb.width*X, fb.height*Y);
register int curY=UpBuffer->height;
while (curY--) {
register int curX=UpBuffer->width;
while (curX--)
UpBuffer->pImage[curX+curY*UpBuffer->width]=fb.pImage[curX/X+curY/Y*fb.width];
}
return UpBuffer;
}
friend void Down(const FrameBuffer &fb, unsigned int X, unsigned int Y){
}
friend void Copy(FrameBuffer &dst, const FrameBuffer &src,
int dstX, int dstY,
int srcX, int srcY,
int width, int height) {
register int curY=height;
while (curY--) {
register int curX=width;
while (curX--)
dst.pImage[dstX+curX+(dstY+curY)*dst.width]=src.pImage[srcX+curX+(srcY+curY)*src.width];
}
}
~FrameBuffer() {
width=height=0;
memset(&bi, 0, sizeof(bi));
if (pImage)
delete[] pImage;
}
};
ScalarTypes.h
#ifndef SCALAR_H
#define SCALAR_H
typedef double scalar;
typedef unsigned int IDX;
#endif
vector.h
#ifndef VECTOR_H
#define VECTOR_H
#include "ScalarTypes.h" struct Matrix;
union Vector {
scalar array[4];
struct {
scalar _0, _1, _2, _3;
};
struct {
scalar X, Y, Z, W;
};
struct {
scalar R, G, B, A;
};
Vector();// ? inline
Vector(const Vector &vec);
Vector(const scalar array[4]);
Vector(scalar _);
Vector(scalar _0, scalar _1, scalar _2);
Vector(scalar _0, scalar _1, scalar _2, scalar _3);
scalar sqr_norm3() const;
scalar norm3() const;
Vector &normalize3();
Vector &homogenize3();
Vector &homogenize4();
scalar &operator [] (IDX i);
const scalar &operator [] (IDX i) const;
Vector operator - () const;
Vector &operator += (scalar _);
Vector &operator -= (scalar _);
Vector &operator *= (scalar _);
Vector &operator /= (scalar _);
Vector &operator += (const Vector &vec);
Vector &operator -= (const Vector &vec);
Vector &operator *= (const Vector &vec);
Vector &operator /= (const Vector &vec);
Vector &operator *= (const Matrix &mat);
friend Vector operator + (const Vector &vec, scalar _);
friend Vector operator - (const Vector &vec, scalar _);
friend Vector operator * (const Vector &vec, scalar _);
friend Vector operator / (const Vector &vec, scalar _);
friend Vector operator + (const Vector &vec1, const Vector &vec2);
friend Vector operator - (const Vector &vec1, const Vector &vec2);
friend Vector operator * (const Vector &vec1, const Vector &vec2);
friend Vector operator / (const Vector &vec1, const Vector &vec2);
friend Vector operator * (const Vector &vec, const Matrix &mat);
scalar dot3(const Vector &vec) const;
scalar dot4(const Vector &vec) const;
Vector cross(const Vector &vec) const;
}; #endif
vector.cpp
#include "stdafx.h"
#include "ScalarTypes.h"
#include "vector.h"
#include "matrix.h" Vector::Vector() {} Vector::Vector(const Vector &vec) {
_0=vec._0;
_1=vec._1;
_2=vec._2;
_3=vec._3;
} Vector::Vector(const scalar array[4]):
_0(array[0]), _1(array[1]), _2(array[2]), _3(array[3]) {} Vector::Vector(scalar _):
_0(_), _1(_), _2(_), _3(1.0) {} Vector::Vector(scalar _0, scalar _1, scalar _2):
_0(_0), _1(_1), _2(_2), _3(1.0) {} Vector::Vector(scalar _0, scalar _1, scalar _2, scalar _3):
_0(_0), _1(_1), _2(_2), _3(_3) {} scalar Vector::sqr_norm3() const {
return _0*_0+_1*_1+_2*_2;
} scalar Vector::norm3() const {
return sqrt(this->sqr_norm3());
} Vector &Vector::normalize3() {
return *this/=this->norm3();//?
} Vector &Vector::homogenize3() {
this->X/=this->W;
this->Y/=this->W;
this->Z/=this->W;
return *this;
}
Vector &Vector::homogenize4() {
return *this/=this->W;//?
} scalar &Vector::operator [] (IDX i) {
return array[i];
} const scalar &Vector::operator [] (IDX i) const {
return array[i];
} Vector Vector::operator - () const {
return Vector(-_0, -_1, -_2, -_3);
} Vector &Vector::operator += (scalar _) {
_0+=_;
_1+=_;
_2+=_;
_3+=_;
return *this;
} Vector &Vector::operator -= (scalar _) {
_0-=_;
_1-=_;
_2-=_;
_3-=_;
return *this;
} Vector &Vector::operator *= (scalar _) {
_0*=_;
_1*=_;
_2*=_;
_3*=_;
return *this;
} Vector &Vector::operator /= (scalar _) {
_0/=_;
_1/=_;
_2/=_;
_3/=_;
return *this;
} Vector &Vector::operator += (const Vector &vec) {
_0+=vec._0;
_1+=vec._1;
_2+=vec._2;
_3+=vec._3;
return *this;
} Vector &Vector::operator -= (const Vector &vec) {
_0-=vec._0;
_1-=vec._1;
_2-=vec._2;
_3-=vec._3;
return *this;
} Vector &Vector::operator *= (const Vector &vec) {
_0*=vec._0;
_1*=vec._1;
_2*=vec._2;
_3*=vec._3;
return *this;
} Vector &Vector::operator /= (const Vector &vec) {
_0/=vec._0;
_1/=vec._1;
_2/=vec._2;
_3/=vec._3;
return *this;
} Vector &Vector::operator *= (const Matrix &mat) {
return *this=*this*mat;//?
} Vector operator + (const Vector &vec, scalar _) {
return Vector(vec)+=_;
} Vector operator - (const Vector &vec, scalar _) {
return Vector(vec)-=_;
} Vector operator * (const Vector &vec, scalar _) {
return Vector(vec)*=_;
} Vector operator / (const Vector &vec, scalar _) {
return Vector(vec)/=_;
} Vector operator + (const Vector &vec1, const Vector &vec2) {
return Vector(vec1)+=vec2;
} Vector operator - (const Vector &vec1, const Vector &vec2) {
return Vector(vec1)-=vec2;
} Vector operator * (const Vector &vec1, const Vector &vec2) {
return Vector(vec1)*=vec2;
} Vector operator / (const Vector &vec1, const Vector &vec2) {
return Vector(vec1)/=vec2;
} Vector operator * (const Vector &vec, const Matrix &mat) {
Vector product(0.0, 0.0, 0.0, 0.0);
for (IDX i=0; i < 4; i++)
for (IDX j=0; j < 4; j++)
product[i]+=vec[j]*mat(j, i);
return product;
} scalar Vector::dot3(const Vector &vec) const {
return this->X*vec.X+this->Y*vec.Y+this->Z*vec.Z;
} scalar Vector::dot4(const Vector &vec) const {
return this->X*vec.X+this->Y*vec.Y+this->Z*vec.Z+this->W*vec.W;
} Vector Vector::cross(const Vector &vec) const {
Vector product;
product.X=this->Y*vec.Z-vec.Y*this->Z;
product.Y=-(this->X*vec.Z-vec.X*this->Z);
product.Z=this->X*vec.Y-vec.X*this->Y;
|