Gl Graph

Gl Graph Source of glwindow.cpp


#include <glwindow.h>
 
#include "drawableset.h"
#include "glscene.h"
#include "glcanvas.h"
#include "math.h"
#include <ctype.h>
 
 
GlWindow::GlWindow(unsigned int width, unsigned int height)
    : GlRenderer(width,height)
{
    init();
}
 
GlWindow::GlWindow(unsigned int width, unsigned int height, bool debug)
    : GlRenderer(width,height,debug)
{
    init();
}
 
GlWindow::~GlWindow()
{
    delete this->scene;
}
 
void GlWindow::init()
{
    this->scene= new GlScene(width,height);
}
 
 
std::string GlWindow::getPngFileName()
{
    const int strSize = 25;
    char buffer [strSize];
    for (int i=0; i<1000; i++)
    {
        bzero(buffer,strSize);
        snprintf(buffer, strSize, "screenshot_%03i.png", i);
        FILE *fp = fopen(buffer, "r");
        if (fp) //file exists
            fclose(fp);
        else //file do not exists
            return std::string((char *)&buffer);
    }
    return std::string("screenshot");
}
 
 
void GlWindow::setDebug(bool debug)
{
    this->debug = debug;
}
 
bool GlWindow::isDebug()
{
    return this->debug;
}
 
void GlWindow::swapHelpTextMode()
{
    this->helpTextMode = !this->helpTextMode;
    scene->setReDraw();
}
 
void GlWindow::processButtonPressEscape()
{
 
}
 
void GlWindow::processButtonPressF1()
{
    swapHelpTextMode();
}
 
void GlWindow::processButtonPressF2()
{
    scene->swapKeepProportionXY();
}
 
void GlWindow::processButtonPressF3()
{
    scene->swapTextInfo();
}
 
void GlWindow::processButtonPressF4()
{
    scene->reset();
}
 
void GlWindow::processButtonPressF5()
{
    scene->swapDepthBuffer();
}
 
void GlWindow::processButtonPressF6()
{
    scene->swapPolygonMode();
}
 
void GlWindow::processButtonPressF7()
{
    writePng();
}
 
void GlWindow::processButtonPressF8()
{
    scene->swapView();
}
 
void GlWindow::processButtonPressF9()
{
 
}
 
void GlWindow::processButtonPressF10()
{
 
}
 
void GlWindow::processButtonPressF11()
{
 
}
 
void GlWindow::processButtonPressF12()
{
 
}
 
void GlWindow::processButtonUp()
{
    scene->getDrawableSet()->onButtonUp();
}
 
void GlWindow::processButtonDown()
{
    scene->getDrawableSet()->onButtonDown();
}
 
void GlWindow::processButtonRight()
{
    scene->getDrawableSet()->onButtonRight();
}
 
void GlWindow::processButtonLeft()
{
    scene->getDrawableSet()->onButtonLeft();
}
 
 
void GlWindow::processButtonPressChar(char c)
{
    if (this->isDebug())
        printf("processButtonPressChar  : %c\n", c);
}
 
void GlWindow::processCloseEvent()
{
    stopped = true;
}
 
 
 
void GlWindow::onMouseMotion(int x, int y, MouseButton button,ModifierButton mod)
{
    mkState.xButtonMotion = x;
    mkState.yButtonMotion = y;
 
    if (button==MOUSE_BUTTON_RIGHT && mod==NO_MODIFIER)
    {
        processTranslation(x, y);
    }
    else if (button==MOUSE_BUTTON_MIDDLE && mod==NO_MODIFIER)
    {
        processRotation(x, y);
    }
    else if (button==MOUSE_BUTTON_MIDDLE && mod==CTRL_MODIFIER)
    {
        const float coeff = 1.01f;
        float coeffx=1;
        float coeffy=1;
        float dx=x - mkState.xButtonPress;
        float dy=mkState.yButtonPress - y;
 
        if (abs(dx)>abs(dy))
            coeffx = pow(coeff,dx);
        else
            coeffy = pow(coeff,dy);
 
        Vec3f co=Vec3f(coeffx,coeffy,1);
        co.componentMul(mkState.scale);
        scene->getCamera()->setScale(co);
    }
 
    mkState.xButtonMotionPrevious = mkState.xButtonMotion;
    mkState.yButtonMotionPrevious = mkState.yButtonMotion;
 
    scene->setReDraw();
}
 
void GlWindow::onMouseButtonPress(int x, int y, MouseButton button, ModifierButton mod)
{
    if (debug)
        printf("onMouseButtonPress  : x %d y %d %d %d\n",x,y,button,mod);
 
    mkState.xButtonPress = x;
    mkState.yButtonPress = y;
    mkState.xButtonMotionPrevious = x;
    mkState.yButtonMotionPrevious = y;
 
    GlCamera * camera=scene->getCamera();
    camera->startMovement();
    mkState.scale=camera->getScale();
    const float coeff = 1.1f;
 
    if (button==MOUSE_BUTTON_LEFT)
    {
        mkState.isSelectionSquare=true;
    }
    else if (button==MOUSE_BUTTON_MIDDLE_UP)
    {
        camera->multScale(coeff);
    }
    else if (button==MOUSE_BUTTON_MIDDLE_DOWN)
    {
        camera->multScale(1.0f/coeff);
    }
    scene->setReDraw();
 
}
void GlWindow::onMouseButtonRelease(int x, int y, MouseButton button,ModifierButton mod)
{
    if (debug)
        printf("onMouseButtonRelease  : x %d y %d %d %d\n",x,y,button,mod);
 
    if (button==MOUSE_BUTTON_LEFT)
    {
        mkState.isSelectionSquare=false;
        int middlex=abs(mkState.xButtonPress+x)/2;
        int middley=abs(mkState.yButtonPress+y)/2;
        int halfsizex=abs(mkState.xButtonPress-x)/2;
        int halfsizey=abs(mkState.yButtonPress-y)/2;
 
        processOnclick(middlex,middley,halfsizex,halfsizey);
    }
    if (button==MOUSE_BUTTON_RIGHT && mod==NO_MODIFIER)
    {
        processTranslation(x, y);
    }
    scene->setReDraw();
}
 
void GlWindow::processOnclick(int x, int y,int halfsizex,int halfsizey)
{
    float XPixelSize = scene->getXPixelSize();
    float YPixelSize = scene->getYPixelSize();
    float X = XPixelSize * (x - (int)width/2);
    float Y = YPixelSize * ((int)height/2 - y);
 
    GlCamera* camera=scene->getCamera();
 
    Vec3f pos = camera->getPosition();
    Vec3f translationx = camera->getX();
    translationx.scale(X);
    Vec3f translationy = camera->getY();
    translationy.scale(Y);
    Vec3f translation;
    translation.add(translationx,translationy);
    translation.add(translation,pos);
 
    Vec3f directionz = camera->getZ();
    directionz.scale(-1);
    directionz.normalize();
    Vec3f directionx = camera->getX();
    directionx.scale(halfsizex*XPixelSize);
    Vec3f directiony = camera->getY();
    directiony.scale(halfsizey*YPixelSize);
 
    scene->getDrawableSet()->onClick(translation,directionx,directiony,directionz);
}
 
void GlWindow::processTranslation(int x, int y)
{
    float XPixelSize = scene->getXPixelSize();
    float YPixelSize = scene->getYPixelSize();
    float X = XPixelSize * (x - mkState.xButtonPress);
    float Y = YPixelSize * (mkState.yButtonPress - y);
    Vec3f translation(-X, -Y, 0);
    scene->getCamera()->updateMovementTranslation(translation);
}
 
void GlWindow::processRotation(int x, int y)
{
    float thetaY = ((float) (mkState.xButtonMotionPrevious - x) / (float) 200);
    float thetaX = ((float) (mkState.yButtonMotionPrevious - y) / (float) 200);
 
    scene->getCamera()->rotateX(thetaX);
    scene->getCamera()->rotateY(thetaY);
    scene->setFreeView();
}
 
void GlWindow::processResizeEvent(unsigned int width, unsigned int height)
{
    if (this->width != width || this->height != height)
    {
        this->width = width;
        this->height = height;
        scene->onResize(height, width);
    }
}
 
void GlWindow::init(DrawableSet * set)
{
    initBeforeGl();
    initGl();
    initAfterGl(set);
}
 
void GlWindow::initBeforeGl()
{
    int argc = 0;
    glutInit(&argc, 0);
}
 
void GlWindow::initAfterGl(DrawableSet * set)
{
    scene->init(set);
    stopped = false;
 
    if (scene->getVersion()->hasGlEXTENSION("GLX_EXT_swap_control") )
    {
        typedef void (*glXSwapIntervalEXTPtr)(int );
        glXSwapIntervalEXTPtr glXSwapInterval = (glXSwapIntervalEXTPtr) glXGetProcAddress((const GLubyte*)"glXSwapIntervalEXT");
        glXSwapInterval(-1);
    }
}
 
void GlWindow::drawHelpText()
{
    if (scene->isReDraw())
    {
        scene->unsetReDraw();
        GlCanvas* canvas=scene->getCanvas();
        scene->clearBuffer();
        scene->loadIdentity();
        canvas->resetLine();
        canvas->setColor(0.9, 0.9, 0.9);
        *canvas << "                       HELP MODE\n";
        canvas->setColor(0.7, 0.7, 0.9);
        *canvas << "-> F1  Open or close help mode\n";
        *canvas << "-> F2  Set/Remove aspect ratio to 1:1\n";
        *canvas << "-> F3  Set/Remove Text Info\n";
        *canvas << "-> F4  Reset initial view\n";
        *canvas << "-> F5  Set/Remove Buffer\n";
        *canvas << "-> F6  Select Polygon Mode\n";
        *canvas << "-> F7  Record a screenshot\n";
        *canvas << "-> F8  Change camera view (Front,Up,Down,Left,Right,Back)\n";
        canvas->setColor(0.9, 0.9, 0.9);
        *canvas << "                       GL INFO\n";
        canvas->setColor(0.7, 0.7, 0.9);
        *canvas << *scene->getVersion();
        glFinish();
    }
}
 
void GlWindow::drawAll()
{
    if (scene->isReDraw() || scene->isSetChange())
    {
        scene->unsetReDraw();
        scene->drawAll(&mkState);
        glFinish();
    }
}