📄 psgl.cpp
字号:
#include "PsGL.h"
/*基 类* * * * * * * * * */
PsGL::PsGL(void)
{
}
PsGL::~PsGL(void)
{
}
//静态成员
const double PsGL::PI = 3.1415926;
void PsGL::mathVectorProductd(PsGL::PsVector3Dd& vector_1, PsGL::PsVector3Dd& vector_2, PsGL::PsPoint3Dd& result)
{
result.x = vector_1.y * vector_2.z - vector_1.z * vector_2.y;
result.y = vector_1.z * vector_2.x - vector_1.x * vector_2.z;
result.z = vector_1.x * vector_2.y - vector_1.y * vector_2.x;
}
void PsGL::mathRotated(GLdouble axis_x, GLdouble axis_y, GLdouble axis_z, GLfloat angle, PsGL::PsPoint3Dd& point)
{
PsGL::PsVector3Dd l_axis, m_axis, n_axis;
GLdouble r_point_proL, r_point_proN;
l_axis.x = axis_x;
l_axis.y = axis_y;
l_axis.z = axis_z;
PsGL::mathNormalizeVector(l_axis.x, l_axis.y, l_axis.z);
PsGL::mathVectorProductd(l_axis, point, m_axis);//计算另一个变换坐标轴m
if(fabs(m_axis.x) < 0.0001 && fabs(m_axis.y) < 0.0001 && fabs(m_axis.z) < 0.0001)
return;//点在旋转轴上的情况
PsGL::mathNormalizeVector(m_axis.x, m_axis.y, m_axis.z);
PsGL::mathVectorProductd(m_axis, l_axis, n_axis);//计算另一个变换坐标轴n
r_point_proL = point.x * l_axis.x + point.y * l_axis.y + point.z * l_axis.z;//向量在L上的投影长
r_point_proN = point.x * n_axis.x + point.y * n_axis.y + point.z * n_axis.z;//向量在N上的投影长
//旋转
point.x = r_point_proL * l_axis.x + r_point_proN * cos(_ToRad(angle)) * n_axis.x + r_point_proN * sin(_ToRad(angle)) * m_axis.x;
point.y = r_point_proL * l_axis.y + r_point_proN * cos(_ToRad(angle)) * n_axis.y + r_point_proN * sin(_ToRad(angle)) * m_axis.y;
point.z = r_point_proL * l_axis.z + r_point_proN * cos(_ToRad(angle)) * n_axis.z + r_point_proN * sin(_ToRad(angle)) * m_axis.z;
}
GLdouble PsGL::mathNormalizeVector(GLdouble& x, GLdouble& y, GLdouble& z)
{
GLdouble r = sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2));
x = x / r;
y = y / r;
z = z / r;
return r;
}
void PsGL::unProjectPoint(int screen_x, int screen_y, GLdouble &x, GLdouble &y, GLdouble &z)
{
GLint psgl_Viewport[4];
GLdouble psgl_Mvmatrix[16];
GLdouble psgl_Projmatrix[16];
//获得变换矩阵
glGetIntegerv(GL_VIEWPORT, psgl_Viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, psgl_Mvmatrix);
glGetDoublev(GL_PROJECTION_MATRIX, psgl_Projmatrix);
//反投影
gluUnProject((GLdouble) screen_x, (GLdouble) psgl_Viewport[3] - screen_y, 0,
psgl_Mvmatrix, psgl_Projmatrix, psgl_Viewport,
&x, &y, &z);
}
void PsGL::unProjectPoints(int screen_pos[][2], PsGL::PsPoint3Dd points[], int n)
{
GLint psgl_Viewport[4];
GLdouble psgl_Mvmatrix[16];
GLdouble psgl_Projmatrix[16];
//获得变换矩阵
glGetIntegerv(GL_VIEWPORT, psgl_Viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, psgl_Mvmatrix);
glGetDoublev(GL_PROJECTION_MATRIX, psgl_Projmatrix);
//反投影
for (int i = 0; i < n; ++i)
{
gluUnProject((GLdouble) screen_pos[i][0], (GLdouble) psgl_Viewport[3] - screen_pos[i][1], 0,
psgl_Mvmatrix, psgl_Projmatrix, psgl_Viewport,
&points[i].x, &points[i].y, &points[i].z);
}
}
/*光照类* * * * * * * * * */
//静态成员
int PsGLLight::MAX_LIGHT_NUMBER = 8;
int PsGLLight::light_number = 0;
bool PsGLLight::bLighting = false;
bool PsGLLight::bTwoSide = false;
bool PsGLLight::bLocalView = false;
bool PsGLLight::bSeparateSpecularColor = false;
GLenum PsGLLight::IDs[] = {
GL_LIGHT0,
GL_LIGHT1,
GL_LIGHT2,
GL_LIGHT3,
GL_LIGHT4,
GL_LIGHT5,
GL_LIGHT6,
GL_LIGHT7
};
PsGLLight* PsGLLight::light_pool[] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
GLfloat PsGLLight::light_model_ambient[] = {
0.2, 0.2, 0.2, 1.0
};
PsGLLight* PsGLLight::createLight()
{
if (light_number + 1 <= MAX_LIGHT_NUMBER)
{
int i;
for (i = 0; i < MAX_LIGHT_NUMBER && light_pool[i] != NULL; ++i);
PsGLLight* pLight = new PsGLLight();
pLight->nIndex = i;
pLight->nID = IDs[i];
light_pool[i] = pLight;
++light_number;
return pLight;
}
return NULL;
}
bool PsGLLight::deleteLight(int index)
{
if ((index >= 0 && index < MAX_LIGHT_NUMBER) && light_pool[index] != NULL)
{
delete light_pool[index];
light_pool[index] = NULL;
--light_number;
return true;
}
return false;
}
void PsGLLight::deleteAllLight()
{
for (int i = 0; i < MAX_LIGHT_NUMBER; ++i)
if (light_pool[i] != NULL)
{
delete light_pool[i];
light_pool[i] = NULL;
}
light_number = 0;
}
void PsGLLight::enableLighting(bool enable)
{
if (enable)
{
glEnable(GL_LIGHTING);
bLighting = true;
}
else
{
glDisable(GL_LIGHTING);
bLighting = false;
}
}
void PsGLLight::enableLMLocalViewer(bool enable)
{
if (enable)
{
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
PsGLLight::bLocalView = true;
}
else
{
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
PsGLLight::bLocalView = false;
}
}
void PsGLLight::enableLMTwoSide(bool enable)
{
if (enable)
{
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
PsGLLight::bTwoSide = true;
}
else
{
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
PsGLLight::bTwoSide = false;
}
}
void PsGLLight::enableLMSeparateSpecularColor(bool enable)
{
//if (enable)
//{
// glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
// PsGLLight::bSeparateSpecularColor = true;
//}
//else
//{
// glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
// PsGLLight::bSeparateSpecularColor = false;
//}
}
void PsGLLight::setLMAmbientColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
{
PsGLLight::light_model_ambient[0] = red;
PsGLLight::light_model_ambient[1] = green;
PsGLLight::light_model_ambient[2] = blue;
PsGLLight::light_model_ambient[3] = alpha;
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, PsGLLight::light_model_ambient);
}
void PsGLLight::getLMAmbientColor(PsGL::PsColor4f& color)
{
color.red = PsGLLight::light_model_ambient[0];
color.green = PsGLLight::light_model_ambient[1];
color.blue = PsGLLight::light_model_ambient[2];
color.alpha = PsGLLight::light_model_ambient[3];
}
//构造函数
PsGLLight::PsGLLight(void)
{
bEnable = false;
//default position
light_position[0] = 0.0;
light_position[1] = 0.0;
light_position[2] = 0.0;
//default orientation
light_orientation[0] = 0.0;
light_orientation[1] = 0.0;
light_orientation[2] = -1.0;
//default color : white
light_color[0] = 1.0;
light_color[1] = 1.0;
light_color[2] = 1.0;
light_color[3] = 1.0;
//default ambient color : none
light_ambient[0] = 0.0;
light_ambient[1] = 0.0;
light_ambient[2] = 0.0;
light_ambient[3] = 1.0;
//default specular color : white
light_specular[0] = 1.0;
light_specular[1] = 1.0;
light_specular[2] = 1.0;
light_specular[3] = 1.0;
//default cutoff angle
light_cutoff_angle = 180.0;
//default attenuation
light_attenuation[0] = 1.0;
light_attenuation[1] = 0.0;
light_attenuation[2] = 0.0;
//default exponent
light_exponent = 0.0;
}
PsGLLight::~PsGLLight(void)
{
}
//基类成员
void PsGLLight::enable(bool enable)
{
if (enable)
{
if (!bLighting)
PsGLLight::enableLighting(true);
glEnable(nID);
bEnable = true;
}
else
{
glDisable(nID);
bEnable = false;
}
}
/*相机类* * * * * * * * * */
PsGLCamera::PsGLCamera(void)
{
camera_ScaleFactor = 1.0;
camera_RotateSpeed = 0.3;
camera_Position.x = 1.0;
camera_Position.y = 1.0;
camera_Position.z = 1.0;
setViewPoint(0.0, 0.0, 0.0);//initial viewpoint and direction vector
camera_UpVector.x = -1.0;
camera_UpVector.y = 1.0;
camera_UpVector.z = -1.0;
}
PsGLCamera::~PsGLCamera(void)
{
}
void PsGLCamera::viewFromCamera()
{
gluLookAt(camera_Position.x, camera_Position.y, camera_Position.z,
camera_ViewPoint.x, camera_ViewPoint.y, camera_ViewPoint.z,
camera_UpVector.x, camera_UpVector.y, camera_UpVector.z);
}
void PsGLCamera::rotatePosition(GLdouble axis_x, GLdouble axis_y, GLdouble axis_z, GLfloat angle)
{
PsGL::PsPoint3Dd point;
point.x = - camera_DirectionVector.x;
point.y = - camera_DirectionVector.y;
point.z = - camera_DirectionVector.z;
PsGL::mathRotated(axis_x, axis_y, axis_z, angle, point);
PsGL::mathRotated(axis_x, axis_y, axis_z, angle, camera_UpVector);
setPosition(point.x + camera_ViewPoint.x,
point.y + camera_ViewPoint.y,
point.z + camera_ViewPoint.z);
}
//直接使用窗口坐标
void PsGLCamera::rotatePosition(int pre_x, int pre_y, int new_x, int new_y)
{
if (pre_x == new_x && pre_y == new_y)
return;
PsGL::PsPoint3Dd pre_Point, new_Point;
PsGL::PsVector3Dd move_Vector, rotate_Axis;
PsGL::unProjectPoint(pre_x, pre_y, pre_Point.x, pre_Point.y, pre_Point.z);
PsGL::unProjectPoint(new_x, new_y, new_Point.x, new_Point.y, new_Point.z);
move_Vector.x = new_Point.x - pre_Point.x;
move_Vector.y = new_Point.y - pre_Point.y;
move_Vector.z = new_Point.z - pre_Point.z;
PsGL::mathVectorProductd(move_Vector, camera_DirectionVector, rotate_Axis);
rotatePosition(rotate_Axis.x, rotate_Axis.y, rotate_Axis.z, camera_RotateSpeed);
}
void PsGLCamera::rotateViewPoint(GLdouble axis_x, GLdouble axis_y, GLdouble axis_z, GLfloat angle)
{
PsGL::mathRotated(axis_x, axis_y, axis_z, angle, camera_DirectionVector);
PsGL::mathRotated(axis_x, axis_y, axis_z, angle, camera_UpVector);
camera_ViewPoint.x = camera_DirectionVector.x + camera_Position.x;
camera_ViewPoint.y = camera_DirectionVector.y + camera_Position.y;
camera_ViewPoint.z = camera_DirectionVector.z + camera_Position.z;
}
//直接使用窗口坐标
void PsGLCamera::rotateViewPoint(int pre_x, int pre_y, int new_x, int new_y)
{
if (pre_x == new_x && pre_y == new_y)
return;
PsGL::PsPoint3Dd pre_Point, new_Point;
PsGL::PsVector3Dd move_Vector, rotate_Axis;
PsGL::unProjectPoint(pre_x, pre_y, pre_Point.x, pre_Point.y, pre_Point.z);
PsGL::unProjectPoint(new_x, new_y, new_Point.x, new_Point.y, new_Point.z);
move_Vector.x = new_Point.x - pre_Point.x;
move_Vector.y = new_Point.y - pre_Point.y;
move_Vector.z = new_Point.z - pre_Point.z;
PsGL::mathVectorProductd(camera_DirectionVector, move_Vector, rotate_Axis);
rotateViewPoint(rotate_Axis.x, rotate_Axis.y, rotate_Axis.z, camera_RotateSpeed);
}
void PsGLCamera::translateCamera(GLdouble vector_x, GLdouble vector_y, GLdouble vector_z)
{
camera_Position.x += vector_x;
camera_Position.y += vector_y;
camera_Position.z += vector_z;
camera_ViewPoint.x += vector_x;
camera_ViewPoint.y += vector_y;
camera_ViewPoint.z += vector_z;
}
void PsGLCamera::translateCamera(int pre_x, int pre_y, int new_x, int new_y)
{
PsGL::PsPoint3Dd pre_Point, new_Point;
PsGL::unProjectPoint(pre_x, pre_y, pre_Point.x, pre_Point.y, pre_Point.z);
PsGL::unProjectPoint(new_x, new_y, new_Point.x, new_Point.y, new_Point.z);
translateCamera(new_Point.x - pre_Point.x,
new_Point.y - pre_Point.y,
new_Point.z - pre_Point.z);
}
void PsGLCamera::rotateCamera(GLfloat degree)
{
PsGL::mathRotated(camera_DirectionVector.x,
camera_DirectionVector.y,
camera_DirectionVector.z,
degree,
camera_UpVector);
}
/*场景管理类 * * * * * * * */
PsGLSceneManager::PsGLSceneManager(void)
{
}
PsGLSceneManager::~PsGLSceneManager(void)
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -