Es++ Class: OpenGLView

 Es++ Class Library  Es++ Samples 

Source code

/******************************************************************************
 *
 * Copyright (c) 2017 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer.
 *  
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 *  OpenGLView.h
 *
 *****************************************************************************/

#pragma once

#include <gtkmm/drawingarea.h>

#include <es++/opengl/OpenGLContext.h>
#include <es++/opengl/OpenGLGC.h>
#include <es++/opengl/OpenGLBitmap.h>
#include <es++/opengl/OpenGLMainView.h>
#include <es++/opengl/OpenGLImageInfo.h>

#include <gdkmm-3.0/gdkmm.h>
#include <gdk/gdkx.h>
#include <X11/Xlib.h>
#include <gtkmm/drawingarea.h>

using namespace Gtk;

namespace Es {

class OpenGLView :public Gtk::DrawingArea {
private:
  ::Display*      xdisplay;
  ::Window        xwindow;
  OpenGLContext*  context;
  int             bufferType;

public:
  OpenGLView()
  :DrawingArea()
  ,xdisplay(NULL)
  ,xwindow(None)
  {
    xdisplay = gdk_x11_get_default_xdisplay();

    set_app_paintable(TRUE);

    add_events(Gdk::POINTER_MOTION_MASK |
             Gdk::BUTTON_PRESS_MASK |
             Gdk::BUTTON_RELEASE_MASK);
  }

  //X11 Default Display
  ::Display* getDisplay()
  {
    return xdisplay;
  }

  //X11 Window
  ::Window   getWindow()
  {
    return xwindow;
  }


  bool on_draw(const Cairo::RefPtr<Cairo::Context>& cr) override
  {
    return DrawingArea::on_draw(cr);
    render();
  }
 
  void on_size_allocate(Gtk::Allocation& allocation)
  {
    DrawingArea::on_size_allocate(allocation);
    int width = allocation.get_width();
    int height = allocation.get_height();
    
    resize(width, height);
  }

  virtual void render()
  {
    //Call a virtual method display.
    display();

    glFlush();
        
    if (bufferType == OpenGL_DOUBLE_BUFFER) {
      swapBuffers();
    }
    XFlush(xdisplay);
  }

  virtual void resize(int width, int height)
  {
    setViewPort(width, height);
  }

  void swapBuffers()
  {
    glXSwapBuffers(getDisplay(), getWindow());
  }

  // Please define your own display method in a sublcass
  // derived from this class.
  virtual void display()
  {
  }    

  void on_map()
  {
    DrawingArea::on_map();

    Glib::RefPtr<Gdk::Window> gdk_window = get_window();
    xwindow =  gdk_x11_window_get_xid(Glib::unwrap(gdk_window) );

    if (xwindow != None) {
      context -> makeCurrent(xwindow);
    }

    //Call a virtual initialize method.
    initialize();
  }

  // Define your own initialize method in a subclass derived
  // from this class.
  virtual void initialize()
  {
  }

  int width()
  {
    Gtk::Allocation allocation = get_allocation();
    return allocation.get_width();
  }

  int height()
  {
    Gtk::Allocation allocation = get_allocation();
    return allocation.get_height();
  }

  void setViewPort()
  {
    int w = width();
    int h = height();

    glViewport(0, 0, w, h);
  }

  void setViewPort(int w, int h)
  {
    glViewport(0, 0, w, h);
  }

  void setPerspective(GLdouble fovy=16.0,
        GLdouble zNear=0.5,
        GLdouble zFar =100.0f)
  {
    //Set a proportional perspective.
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    int w = width();
    int h = height();
    if (h > 0) {
      GLdouble aspect = (GLdouble)w / (GLdouble)h;
      gluPerspective(fovy, aspect, zNear, zFar);
    }
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
  }

  void set_opengl_context(OpenGLContext* context)
  {
    this->context = context;
    this->bufferType = context->getBufferType();
  }

  virtual bool on_key_press_event(GdkEventKey* event)
  {
    printf("KeyPressed\n");
    return true;
  }

  virtual void save(const char* filename)
  {
    if (StringT<char>::endsWithIgnoreCase(filename, ".jpg")) {
      saveAsJPG(filename);
    } 
    else if (StringT<char>::endsWithIgnoreCase(filename, ".png")) {
      saveAsPNG(filename);
    } else {
        //Ignore
    }
  }

  virtual void saveAsJPG(const char* filename)
  {
    try {
      int w = width();
      int h = height();
      int rw = (w / 8) * 8;
          
      OpenGLBitmap bitmap(0, 0, rw, h, 24, GL_RGB);

      bitmap.read(GL_FRONT);
      bitmap.saveAsJPG(filename);
     printf("saveAsJPG %s\n", filename);
    } catch (Exception& ex) {
      ex.display();
    }      
  }

  virtual void saveAsPNG(const char* filename)
  {
    try {
      int w = width();
      int h = height();
      int rw = (w / 8) * 8;
          
      //OpenGLBitmap bitmap(0, 0, w, h, 8, GL_RGBA);
      OpenGLBitmap bitmap(0, 0, rw, h, 8, GL_RGBA);
      bitmap.read(GL_FRONT);
      bitmap.saveAsPNG(filename);
     printf("saveAsPNG %s\n", filename);
    } catch (Exception& ex) {
      ex.display();
    }      
  }

};

}



Last modified: 4 Apr 2019

Copyright (c) 2019 Antillia.com ALL RIGHTS RESERVED.