#include "..\..\..\OpenGL\include\WindowsViewer\WinRenderer.h"
#include "..\..\..\Common\include\OAGVector3f.h"
#include <gl\glu.h>
oag::WinRenderer::WinRenderer(void)
:m_prglWinGC(NULL)
,m_prglScene(NULL)
,m_bIs3dMode(false)
{
SetBackGroundColor(0, 0, 0);
ResetTransform();
}
oag::WinRenderer::WinRenderer(oag::WinGraphicContext* Win32GC, bool b3DMode)
{
m_prglWinGC = Win32GC;
m_bIs3dMode = b3DMode;
m_prglScene = NULL;
SetBackGroundColor(0, 0, 0);
ResetTransform();
}
oag::WinRenderer::~WinRenderer(void)
{
}
//Operations
void oag::WinRenderer::DeleteCurrentScene()
{
if( m_prglScene )
delete m_prglScene;
m_prglScene = NULL;
}
void oag::WinRenderer::GetOGLPos(const int nXScreenCoordinate, const int nYScreenCoordinate, oag::OAGVector3d *ptOut)
{
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
GLint dims[2];
oag::OAGVector3d res1;
oag::OAGVector3d res2;
m_prglWinGC->MakeCurrent();
glGetDoublev (GL_MODELVIEW_MATRIX, modelview);
glGetDoublev (GL_PROJECTION_MATRIX, projection);
glGetIntegerv (GL_VIEWPORT, viewport );
glGetIntegerv (GL_MAX_VIEWPORT_DIMS, dims);
GLint glnWinX, glnWinY;
GLfloat glfWinZ;
glnWinX = (GLint)nXScreenCoordinate;
glnWinY = viewport[3] - (GLint)nYScreenCoordinate;
glReadPixels((GLint)nXScreenCoordinate, glnWinY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &glfWinZ);
gluUnProject(glnWinX, glnWinY, 0, modelview, projection, viewport, &ptOut->m_X, &ptOut->m_Y, &ptOut->m_Z);
res1.SetVertex(ptOut->m_X, ptOut->m_Y, ptOut->m_Z);
gluUnProject(glnWinX, glnWinY, 5.0, modelview, projection, viewport, &ptOut->m_X, &ptOut->m_Y, &ptOut->m_Z);
res2.SetVertex(ptOut->m_X, ptOut->m_Y, ptOut->m_Z);
oag::OAGVector3d resOut = res2 - res1;
resOut.Normalize(); //VectorNormalize(&resOut);
ptOut->m_X = ptOut->m_X * ((float)(viewport[2]/2)) / 3.14 * (-1);
ptOut->m_Y = resOut.m_Y * 7.28;
ptOut->m_Z = res2.m_Z - res1.m_Z;
}
void oag::WinRenderer::ScreenToWorld(oag::OAGVector3f ptIn[], oag::OAGVector3d* ptOut, int count)
{
if( m_prglWinGC == NULL )
return;
GLint glnViewport[4];
GLdouble gldModelview[16];
GLdouble gldProjection[16];
GLint glnWinX, glnWinY;
GLfloat glfWinZ;
m_prglWinGC->MakeCurrent();
glGetDoublev (GL_MODELVIEW_MATRIX, gldModelview);
glGetDoublev (GL_PROJECTION_MATRIX, gldProjection);
glGetIntegerv (GL_VIEWPORT, glnViewport );
for (int i = 0; i < count; ++i)
{
glnWinX = (GLint)ptIn[i].m_X;
glnWinY = glnViewport[3] - (GLint)ptIn[i].m_Y;
glReadPixels((GLint)ptIn[i].m_X, glnWinY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &glfWinZ);
gluUnProject(glnWinX
, glnWinY
, glfWinZ
, gldModelview
, gldProjection
, glnViewport
, &ptOut->m_X
, &ptOut->m_Y
, &ptOut->m_Z);
}
m_prglWinGC->DeleteCurrent();
}
void oag::WinRenderer::GetMatrices(GLdouble *gldModelview, GLdouble *gldProjection)
{
m_prglWinGC->MakeCurrent();
glGetDoublev (GL_MODELVIEW_MATRIX, gldModelview);
glGetDoublev (GL_PROJECTION_MATRIX, gldProjection);
m_prglWinGC->DeleteCurrent();
}
void oag::WinRenderer::ScreenToWorld(const int nXScreenCoordinate, const int nYScreenCoordinate, double& fXWorldCoordinate, double& fYWorldCoordinate)
{
oag::OAGVector3f pointCoordinate(nXScreenCoordinate, nYScreenCoordinate, 0);
oag::OAGVector3d centerPoint;
ScreenToWorld(&pointCoordinate, ¢erPoint, 1);
fXWorldCoordinate = centerPoint.m_X;
fYWorldCoordinate = centerPoint.m_Y;
}
void oag::WinRenderer::RenderScene()
{
if( m_prglWinGC == NULL )
return;
if( !m_prglWinGC->MakeCurrent() )
return;
glViewport( m_prglWinGC->X, m_prglWinGC->Y, m_prglWinGC->m_WindowWidth, m_prglWinGC->m_WindowHeight);
::glMatrixMode(GL_PROJECTION);
::glLoadIdentity();
float red = m_BackGroundColor.GetRed() / 255.f;
float green = m_BackGroundColor.GetGreen() / 255.f;
float blue = m_BackGroundColor.GetBlue() / 255.f;
float alpha = m_BackGroundColor.GetAlpha() / 255.f;
::glClearColor( red, green, blue, alpha );
::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if( !m_bIs3dMode )
{
::gluOrtho2D( m_prglWinGC->X, m_prglWinGC->m_WindowWidth, m_prglWinGC->Y, m_prglWinGC->m_WindowHeight);
::glTranslated(m_VecTranslation.m_X, m_VecTranslation.m_Y, m_VecTranslation.m_Z );
::glScaled(m_VecScale.m_X, m_VecScale.m_Y, m_VecScale.m_Z);
}
else
{
gluPerspective( 45.0f , ( 1.0 * m_prglWinGC->m_WindowWidth)/ (1.0 * m_prglWinGC->m_WindowHeight ) , 0.1f, 1000.0f);
::glTranslated(m_VecTranslation.m_X, m_VecTranslation.m_Y, m_VecTranslation.m_Z );
::glScaled(m_VecScale.m_X, m_VecScale.m_Y, m_VecScale.m_Z);
::glRotated(m_VecRotation.m_X, 1.0, 0.0, 0.0);
::glRotated(m_VecRotation.m_Y, 0.0, 1.0, 0.0);
::glRotated(m_VecRotation.m_Z, 0.0, 0.0, 1.0);
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
}
::glMatrixMode(GL_MODELVIEW);
::glLoadIdentity();
//***********[ Scene Objects ] **********/
if( m_prglScene )
{
vector<int>::size_type size = m_prglScene->GetObjectCount();
for( vector<int>::size_type i=0; i < size; i++ )
{
if( m_prglScene->GetObjectAt(i) != NULL )
{
m_prglScene->GetObjectAt(i)->Draw();
}
}
}
//***********[ Scene Objects ] **********/
if (!m_prglWinGC->m_pDC->IsPrinting() )
::SwapBuffers(m_prglWinGC->m_pDC->GetSafeHdc());
m_prglWinGC->DeleteCurrent();
}
void oag::WinRenderer::ResetTransform()
{
m_VecTranslation.SetVertex(0,0,0);
m_VecScale.SetVertex(1,1,1);
m_VecRotation.SetVertex(0,0,0);
if( Is3DMode() )
m_VecTranslation.m_Z = -5;
}