#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cmath>
#ifdef G_OS_WIN32
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
#endif
#include <GL/gl.h>
#include <GL/glu.h>
#include "shapes.h"
namespace Trackball {
extern "C" {
#include "trackball.h"
}
}
#define DIG_2_RAD (G_PI / 180.0)
#define RAD_2_DIG (180.0 / G_PI)
struct GLConfigUtil
{
static void print_gl_attrib(const Glib::RefPtr<const Gdk::GL::Config>& glconfig,
const char* attrib_str,
int attrib,
bool is_boolean);
static void examine_gl_attrib(const Glib::RefPtr<const Gdk::GL::Config>& glconfig);
};
void GLConfigUtil::print_gl_attrib(const Glib::RefPtr<const Gdk::GL::Config>& glconfig,
const char* attrib_str,
int attrib,
bool is_boolean)
{
int value;
if (glconfig->get_attrib(attrib, value))
{
std::cout << attrib_str << " = ";
if (is_boolean)
std::cout << (value == true ? "true" : "false") << std::endl;
else
std::cout << value << std::endl;
}
else
{
std::cout << "*** Cannot get "
<< attrib_str
<< " attribute value\n";
}
}
void GLConfigUtil::examine_gl_attrib(const Glib::RefPtr<const Gdk::GL::Config>& glconfig)
{
std::cout << "\nOpenGL visual configurations :\n\n";
std::cout << "glconfig->is_rgba() = "
<< (glconfig->is_rgba() ? "true" : "false")
<< std::endl;
std::cout << "glconfig->is_double_buffered() = "
<< (glconfig->is_double_buffered() ? "true" : "false")
<< std::endl;
std::cout << "glconfig->is_stereo() = "
<< (glconfig->is_stereo() ? "true" : "false")
<< std::endl;
std::cout << "glconfig->has_alpha() = "
<< (glconfig->has_alpha() ? "true" : "false")
<< std::endl;
std::cout << "glconfig->has_depth_buffer() = "
<< (glconfig->has_depth_buffer() ? "true" : "false")
<< std::endl;
std::cout << "glconfig->has_stencil_buffer() = "
<< (glconfig->has_stencil_buffer() ? "true" : "false")
<< std::endl;
std::cout << "glconfig->has_accum_buffer() = "
<< (glconfig->has_accum_buffer() ? "true" : "false")
<< std::endl;
std::cout << std::endl;
print_gl_attrib(glconfig, "Gdk::GL::USE_GL", Gdk::GL::USE_GL, true);
print_gl_attrib(glconfig, "Gdk::GL::BUFFER_SIZE", Gdk::GL::BUFFER_SIZE, false);
print_gl_attrib(glconfig, "Gdk::GL::LEVEL", Gdk::GL::LEVEL, false);
print_gl_attrib(glconfig, "Gdk::GL::RGBA", Gdk::GL::RGBA, true);
print_gl_attrib(glconfig, "Gdk::GL::DOUBLEBUFFER", Gdk::GL::DOUBLEBUFFER, true);
print_gl_attrib(glconfig, "Gdk::GL::STEREO", Gdk::GL::STEREO, true);
print_gl_attrib(glconfig, "Gdk::GL::AUX_BUFFERS", Gdk::GL::AUX_BUFFERS, false);
print_gl_attrib(glconfig, "Gdk::GL::RED_SIZE", Gdk::GL::RED_SIZE, false);
print_gl_attrib(glconfig, "Gdk::GL::GREEN_SIZE", Gdk::GL::GREEN_SIZE, false);
print_gl_attrib(glconfig, "Gdk::GL::BLUE_SIZE", Gdk::GL::BLUE_SIZE, false);
print_gl_attrib(glconfig, "Gdk::GL::ALPHA_SIZE", Gdk::GL::ALPHA_SIZE, false);
print_gl_attrib(glconfig, "Gdk::GL::DEPTH_SIZE", Gdk::GL::DEPTH_SIZE, false);
print_gl_attrib(glconfig, "Gdk::GL::STENCIL_SIZE", Gdk::GL::STENCIL_SIZE, false);
print_gl_attrib(glconfig, "Gdk::GL::ACCUM_RED_SIZE", Gdk::GL::ACCUM_RED_SIZE, false);
print_gl_attrib(glconfig, "Gdk::GL::ACCUM_GREEN_SIZE", Gdk::GL::ACCUM_GREEN_SIZE, false);
print_gl_attrib(glconfig, "Gdk::GL::ACCUM_BLUE_SIZE", Gdk::GL::ACCUM_BLUE_SIZE, false);
print_gl_attrib(glconfig, "Gdk::GL::ACCUM_ALPHA_SIZE", Gdk::GL::ACCUM_ALPHA_SIZE, false);
std::cout << std::endl;
}
namespace Shapes
{
const float View::NEAR_CLIP = 5.0;
const float View::FAR_CLIP = 60.0;
const float View::INIT_POS_X = 0.0;
const float View::INIT_POS_Y = 0.0;
const float View::INIT_POS_Z = -10.0;
const float View::INIT_AXIS_X = 1.0;
const float View::INIT_AXIS_Y = 0.0;
const float View::INIT_AXIS_Z = 0.0;
const float View::INIT_ANGLE = 0.0;
const float View::INIT_SCALE = 1.0;
const float View::SCALE_MAX = 2.0;
const float View::SCALE_MIN = 0.5;
const float View::ANIMATE_THRESHOLD = 25.0;
View::View()
: m_Scale(INIT_SCALE),
m_BeginX(0.0), m_BeginY(0.0),
m_DX(0.0), m_DY(0.0),
m_Animate(false)
{
reset();
}
View::~View()
{
}
void View::frustum(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w > h) {
float aspect = static_cast<float>(w) / static_cast<float>(h);
glFrustum(-aspect, aspect, -1.0, 1.0, NEAR_CLIP, FAR_CLIP);
} else {
float aspect = static_cast<float>(h) / static_cast<float>(w);
glFrustum(-1.0, 1.0, -aspect, aspect, NEAR_CLIP, FAR_CLIP);
}
glMatrixMode(GL_MODELVIEW);
}
void View::xform()
{
glTranslatef(m_Pos[0], m_Pos[1], m_Pos[2]);
glScalef(m_Scale, m_Scale, m_Scale);
float m[4][4];
Trackball::add_quats(m_QuatDiff, m_Quat, m_Quat);
Trackball::build_rotmatrix(m, m_Quat);
glMultMatrixf(&m[0][0]);
}
void View::reset()
{
m_Pos[0] = INIT_POS_X;
m_Pos[1] = INIT_POS_Y;
m_Pos[2] = INIT_POS_Z;
float sine = sin(0.5 * INIT_ANGLE * DIG_2_RAD);
m_Quat[0] = INIT_AXIS_X * sine;
m_Quat[1] = INIT_AXIS_Y * sine;
m_Quat[2] = INIT_AXIS_Z * sine;
m_Quat[3] = cos(0.5 * INIT_ANGLE * DIG_2_RAD);
m_Scale = INIT_SCALE;
m_QuatDiff[0] = 0.0;
m_QuatDiff[1] = 0.0;
m_QuatDiff[2] = 0.0;
m_QuatDiff[3] = 1.0;
}
void View::enable_animat"ke