Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9428c7c
commit 76ba02e
Showing
196 changed files
with
66,709 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
#include "stdafx.h" | ||
#include "3DGlyph.h" | ||
#include "3DProjector.h" | ||
|
||
#ifndef GGO_UNHINTED | ||
#define GGO_UNHINTED 0x0100 | ||
#endif | ||
|
||
static inline double fx_to_dbl(const FIXED& p) | ||
{ | ||
return double(p.value) + double(p.fract) * (1.0 / 65536.0); | ||
} | ||
|
||
|
||
C3DGlyph::C3DGlyph() | ||
{ | ||
} | ||
|
||
|
||
C3DGlyph::~C3DGlyph() | ||
{ | ||
} | ||
|
||
void C3DGlyph::Clear() | ||
{ | ||
__super::Clear(); | ||
m_vecFaces.clear(); | ||
} | ||
|
||
glm::dvec3 C3DGlyph::GetBoundingBox() const | ||
{ | ||
ATLASSERT(!m_vecVertices.empty()); | ||
return m_vecVertices[1] - m_vecVertices[0]; | ||
} | ||
|
||
void C3DGlyph::Draw(C3DProjector* pProjector) | ||
{ | ||
ATLASSERT(pProjector); | ||
|
||
vector<PIXEL2D> vecPoints(m_vecVertices.size()); | ||
|
||
size_t i = 0; | ||
|
||
bool bIsVisible = false; | ||
|
||
for each(auto& v in m_vecVertices) | ||
{ | ||
pProjector->VertexToPixel(v, vecPoints[i]); | ||
|
||
if (!bIsVisible && pProjector->IsVisible(vecPoints[i])) | ||
bIsVisible = true; | ||
++i; | ||
} | ||
if (bIsVisible) | ||
{ | ||
size_t n = m_vecFaces.size(); | ||
|
||
vector<PIXEL2D> vecPolyPoints(n); | ||
vector<BYTE> vecPolyTypes(n); | ||
|
||
i = 0; | ||
|
||
for each(auto&f in m_vecFaces) | ||
{ | ||
vecPolyPoints[i] = vecPoints[f.first]; | ||
vecPolyTypes[i++] = f.second; | ||
} | ||
pProjector->PolyDraw(&vecPolyPoints.front(), &vecPolyTypes.front(), n, m_colR, m_colG, m_colB, m_alpha); | ||
} | ||
} | ||
|
||
bool C3DGlyph::Create(WCHAR c, const LOGFONT* pLogFont, bool bHinted /*= false*/) | ||
{ | ||
Clear(); | ||
|
||
CClientDC hdc(NULL); | ||
|
||
ATLASSERT(pLogFont); | ||
|
||
// create font and select it | ||
CFont newFont; | ||
|
||
if (!newFont.CreateFontIndirect(pLogFont)) | ||
return false; | ||
|
||
double lfScale = 25.0; | ||
|
||
bool bResult = false; | ||
auto pOldFont = hdc.SelectFont(newFont); | ||
|
||
GLYPHMETRICS gm = { 0 }; | ||
|
||
MAT2 mat2 = { 0 }; | ||
|
||
mat2.eM11.value = 1; | ||
mat2.eM22.value = 1; | ||
|
||
ULONG buf_size = 16384 - 32; | ||
CTempBuffer<BYTE> gbuf(buf_size); | ||
|
||
int total_size = ::GetGlyphOutlineW(hdc, c, GGO_NATIVE | (bHinted ? 0 : GGO_UNHINTED), &gm, buf_size, gbuf, &mat2); | ||
|
||
if (total_size > 0) | ||
{ | ||
bResult = true; | ||
|
||
// store bounding box (lower-left, upper-right) | ||
m_vecVertices.push_back(glm::dvec4(0, 0, 0, 1)); | ||
m_vecVertices.push_back(glm::dvec4((double)((gm.gmBlackBoxX > (UINT)gm.gmCellIncX) ? gm.gmBlackBoxX : (UINT)gm.gmCellIncX) / lfScale, ((double)gm.gmBlackBoxY) / lfScale * (-1.0), 0, 1)); | ||
|
||
const BYTE* cur_glyph = gbuf; | ||
const BYTE* end_glyph = gbuf + total_size; | ||
|
||
while (cur_glyph < end_glyph) | ||
{ | ||
const TTPOLYGONHEADER* th = (const TTPOLYGONHEADER*)cur_glyph; | ||
|
||
const BYTE* end_poly = cur_glyph + th->cb; | ||
const BYTE* cur_poly = cur_glyph + sizeof(TTPOLYGONHEADER); | ||
|
||
m_vecVertices.push_back(glm::dvec4(fx_to_dbl(th->pfxStart.x) / lfScale, -fx_to_dbl(th->pfxStart.y) / lfScale, 0, 1)); | ||
m_vecFaces.push_back(face_t(m_vecVertices.size()-1, PT_MOVETO)); | ||
|
||
while (cur_poly < end_poly) | ||
{ | ||
const TTPOLYCURVE* pc = (const TTPOLYCURVE*)cur_poly; | ||
|
||
if (pc->wType == TT_PRIM_LINE) | ||
{ | ||
for (int i = 0; i < pc->cpfx; i++) | ||
{ | ||
m_vecVertices.push_back(glm::dvec4(fx_to_dbl(pc->apfx[i].x) / lfScale, -fx_to_dbl(pc->apfx[i].y) / lfScale, 0, 1)); | ||
m_vecFaces.push_back(face_t(m_vecVertices.size() - 1, PT_LINETO)); | ||
} | ||
} | ||
else if (pc->wType == TT_PRIM_QSPLINE) | ||
{ | ||
for (int u = 0; u < pc->cpfx - 1; u++) | ||
{ | ||
// B is always the current point | ||
POINTFX pnt_b = pc->apfx[u]; | ||
POINTFX pnt_c = pc->apfx[u + 1]; | ||
|
||
// if not on last spline, compute C | ||
if (u < pc->cpfx - 2) | ||
{ | ||
// midpoint (x,y) | ||
*(int*)&pnt_c.x = (*(int*)&pnt_b.x + *(int*)&pnt_c.x) / 2; | ||
*(int*)&pnt_c.y = (*(int*)&pnt_b.y + *(int*)&pnt_c.y) / 2; | ||
} | ||
|
||
m_vecVertices.push_back(glm::dvec4(fx_to_dbl(pnt_b.x) / lfScale, -fx_to_dbl(pnt_b.y) / lfScale, 0, 1)); | ||
m_vecFaces.push_back(face_t(m_vecVertices.size() - 1, PT_BEZIERTO)); | ||
|
||
m_vecVertices.push_back(glm::dvec4(fx_to_dbl(pnt_c.x) / lfScale, -fx_to_dbl(pnt_c.y) / lfScale, 0, 1)); | ||
m_vecFaces.push_back(face_t(m_vecVertices.size() - 1, PT_BEZIERTO)); | ||
} | ||
} | ||
cur_poly += sizeof(WORD) * 2 + sizeof(POINTFX) * pc->cpfx; | ||
} | ||
cur_glyph += th->cb; | ||
|
||
m_vecVertices.push_back(glm::dvec4(0, 0, 0, 1)); | ||
m_vecFaces.push_back(face_t(m_vecVertices.size() - 1, PT_CCW_EX)); | ||
} | ||
m_vecVertices.push_back(glm::dvec4(0, 0, 0, 1)); | ||
m_vecFaces.push_back(face_t(m_vecVertices.size() - 1, PT_STOP)); | ||
} | ||
// put back the old font | ||
hdc.SelectFont(pOldFont); | ||
|
||
return bResult; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#pragma once | ||
|
||
#include "3DObject.h" | ||
|
||
class C3DGlyph : public C3DObject | ||
{ | ||
public: | ||
C3DGlyph(); | ||
~C3DGlyph(); | ||
|
||
bool Create(WCHAR c, const LOGFONT* pLogFont, bool bHinted = false); | ||
|
||
virtual void Clear(); | ||
virtual void Draw(C3DProjector* pProjector); | ||
|
||
glm::dvec3 GetBoundingBox() const; | ||
|
||
private: | ||
vector<face_t> m_vecFaces; | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
#include "stdafx.h" | ||
#include "3DObject.h" | ||
#include "3DProjector.h" | ||
|
||
C3DObject::C3DObject() | ||
{ | ||
m_colR = 0.0; | ||
m_colG = 1.0; | ||
m_colB = 0.0; | ||
m_alpha = 1.0; | ||
} | ||
|
||
|
||
C3DObject::~C3DObject() | ||
{ | ||
} | ||
|
||
void C3DObject::Clear() | ||
{ | ||
m_vecVertices.clear(); | ||
} | ||
|
||
bool C3DObject::IsVisible(C3DProjector* pProjector) | ||
{ | ||
ATLASSERT(pProjector); | ||
|
||
vector<PIXEL2D> vecPoints(m_vecVertices.size()); | ||
|
||
size_t i = 0; | ||
|
||
bool bIsVisible = false; | ||
|
||
for each(auto& v in m_vecVertices) | ||
{ | ||
pProjector->VertexToPixel(v, vecPoints[i]); | ||
|
||
if (!bIsVisible && pProjector->IsVisible(vecPoints[i])) | ||
{ | ||
bIsVisible = true; | ||
break; | ||
} | ||
++i; | ||
} | ||
return bIsVisible; | ||
} | ||
|
||
void C3DObject::RotateX(double lfDegree) | ||
{ | ||
glm::dvec3 myRotationAxis(1, 0, 0); | ||
|
||
glm::dmat4 c = glm::rotate((glm::dvec3::value_type)glm::radians(lfDegree), myRotationAxis); | ||
|
||
for (auto v = m_vecVertices.begin(); v != m_vecVertices.end(); ++v) | ||
*v = c * (*v); | ||
} | ||
|
||
void C3DObject::MoveX(double lfTrans) | ||
{ | ||
glm::dvec3 vecTrans(lfTrans, 0, 0); | ||
Move(vecTrans); | ||
} | ||
|
||
void C3DObject::MoveZ(double lfTrans) | ||
{ | ||
glm::dvec3 vecTrans(0, 0, lfTrans); | ||
Move(vecTrans); | ||
} | ||
|
||
void C3DObject::Move(const glm::dvec3& vecTrans) | ||
{ | ||
glm::dmat4 c = glm::translate(vecTrans); | ||
|
||
for (auto v = m_vecVertices.begin(); v != m_vecVertices.end(); ++v) | ||
*v = c * (*v); | ||
} | ||
|
||
void C3DObject::Move(const glm::dmat4& matTrans) | ||
{ | ||
for (auto v = m_vecVertices.begin(); v != m_vecVertices.end(); ++v) | ||
*v = matTrans * (*v); | ||
} | ||
|
||
void C3DObject::Scale(double lfFactor) | ||
{ | ||
glm::mat4 matScaling = glm::scale(glm::dvec3(lfFactor, lfFactor, lfFactor)); | ||
|
||
for (auto v = m_vecVertices.begin(); v != m_vecVertices.end(); ++v) | ||
*v = matScaling * (*v); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/////////////////////////////////////////////////////////////////////// | ||
// 3DObject.h | ||
|
||
#pragma once | ||
|
||
#define PT_CCW_EX 0x08 | ||
#define PT_STOP 0x10 | ||
|
||
typedef pair<size_t, BYTE> face_t; | ||
|
||
class C3DProjector; | ||
|
||
class C3DObject | ||
{ | ||
public: | ||
C3DObject(); | ||
virtual ~C3DObject(); | ||
|
||
virtual void Clear(); | ||
virtual void Draw(C3DProjector* pProjector) = 0; | ||
virtual bool IsVisible(C3DProjector* pProjector); | ||
|
||
void RotateX(double lfDegree); | ||
|
||
void Move(const glm::dmat4& matTrans); | ||
void Move(const glm::dvec3& vecTrans); | ||
void MoveX(double lfTrans); | ||
void MoveZ(double lfTrans); | ||
|
||
void Scale(double lfFactor); | ||
|
||
inline void SetColor(double r, double g, double b) | ||
{ | ||
m_colR = r; | ||
m_colG = g; | ||
m_colB = b; | ||
} | ||
inline glm::dvec3 GetBoundingBox() const | ||
{ | ||
glm::dvec3 r(1); | ||
return r; | ||
|
||
} | ||
inline void SetAlpha(double value) | ||
{ | ||
if (value >= 0.0 && value <= 1.0) | ||
m_alpha = value; | ||
} | ||
inline double GetAlpha() const | ||
{ | ||
return m_alpha; | ||
} | ||
public: | ||
vector<glm::dvec4> m_vecVertices; | ||
double m_colR; | ||
double m_colG; | ||
double m_colB; | ||
protected: | ||
double m_alpha; | ||
}; | ||
|
Oops, something went wrong.