1

My intention is to draw some 3d object in a GTK+ window. I found OpenGL is best for my purpose. So, I am using GTK+ and pyopenGL for the purpose.

This is my current status, and merely able to draw a GtkGlArea:

import gi
import sys
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gio, Gdk
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *


class GridWindow(Gtk.ApplicationWindow):
  def __init__(self, app):
    Gtk.Window.__init__(self, application = app,
                        default_width=1000,
                        default_height=200,
                        border_width=2,
                        name = "MyWindow")

    # Main drawing area
    self.area = DrawArea()
    self.area.set_size_request(1000,800)
    # To attach everything
    grid = Gtk.Grid()

    grid.attach(self.area,1,0,1,1)
    self.add(grid)

class DrawArea(Gtk.GLArea):
    def __init__(self):
        Gtk.GLArea.__init__(self)
        self.connect("realize", self.on_realize)
        self.connect("render", self.render)
        glutInit(sys.argv)
        glutDisplayFunc(self.render)
        return

    def on_realize(self, area):
        ctx = self.get_context()
        ctx.make_current()
        err = self.get_error()
        if err:
            print("The error is {}".format(err))

    def render(self, area, ctx):
        glClearColor(.7,.70,.70,1)
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
        color = [1.0,0.,0.,1.]
        glutSolidSphere(2,20,20)
        return True

class draw(Gtk.Application):
  def __init__(self):
    Gtk.Application.__init__(self)
  def do_activate(self):
    win = GridWindow(self)
    win.show_all()


app = draw()
exit_status = app.run(sys.argv)
sys.exit(exit_status)

Without the Glut's call, this is showing the GlArea. But as soon as I am trying to draw a sphere using Glut, its throwing error:

python3 devel.py 
Traceback (most recent call last):
  File "devel.py", line 54, in do_activate
    win = GridWindow(self)
  File "devel.py", line 19, in __init__
    self.area = DrawArea()
  File "devel.py", line 33, in __init__
    glutDisplayFunc(self.render)
  File "/usr/lib/python3.6/site-packages/OpenGL/GLUT/special.py", line 147, in __call__
    contextdata.setValue( self.CONTEXT_DATA_KEY, cCallback )
  File "/usr/lib/python3.6/site-packages/OpenGL/contextdata.py", line 58, in setValue
    context = getContext( context )
  File "/usr/lib/python3.6/site-packages/OpenGL/contextdata.py", line 41, in getContext
    """Attempt to retrieve context when no valid context"""
OpenGL.error.Error: Attempt to retrieve context when no valid context

Since there is not much resource in python3+opengl+gtk3, I am in a bit trouble.

Updated Code After First Reply By Rabbid76:

import gi
import sys
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gio, Gdk
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *


class GridWindow(Gtk.ApplicationWindow):
  def __init__(self, app):
    Gtk.Window.__init__(self, application = app,
                        default_width=1000,
                        default_height=200,
                        border_width=2,
                        name = "MyWindow")

    # Main drawing area
    self.area = DrawArea()
    self.area.set_size_request(1000,800)
    # To attach everything
    grid = Gtk.Grid()

    grid.attach(self.area,1,0,1,1)
    self.add(grid)

class DrawArea(Gtk.GLArea):
    def __init__(self):
        Gtk.GLArea.__init__(self)
        self.connect("realize", self.on_realize)
        self.connect("render", self.render)
        glutInit(sys.argv)
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH)
        glutInitWindowSize(600, 800)
        glutCreateWindow(b'my OpenGL window')
        glutDisplayFunc(self.render)
        glutMainLoop()

    def on_realize(self, area):
        ctx = self.get_context()
        ctx.make_current()
        err = self.get_error()
        if err:
            print("The error is {}".format(err))

    def render(self):
        glClearColor(.7,.70,.70,1)
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
        color = [1.0,0.,0.,1.]
        glutSolidSphere(20,20,20)
        glutSwapBuffers()
        glutPostRedisplay()
        return True

class draw(Gtk.Application):
  def __init__(self):
    Gtk.Application.__init__(self)
  def do_activate(self):
    win = GridWindow(self)
    win.show_all()


app = draw()
exit_status = app.run(sys.argv)
sys.exit(exit_status)
BaRud
  • 3,055
  • 7
  • 41
  • 89
  • That is generic and applied for C language. I need help in this code because pyopengl+gtk documentation is too sparse. But, one info is interesting **Gtk+GLUT does not make sense**. Is it correct? In that case what is the way to draw sphere in openGl? – BaRud Jan 13 '18 at 13:14
  • @Rabbid76: Please undelete your reply. It is still usefull. – BaRud Jan 13 '18 at 13:16

1 Answers1

1

You cannot use GTK and GLUT together. See How do I use GTK and glut together? .

If you want to draw a glutSolidSphere sphere in a "glut" window, then you have to create a OpenGL window with a current OpenGL context. See glutCreateWindow, glutMainLoop, glutSwapBuffers, glutPostRedisplay :

class DrawArea:
    def __init__(self):
        glutInit(sys.argv)
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH)
        glutInitWindowSize(600, 800)
        glutCreateWindow(b'my OpenGL window')
        glutDisplayFunc(self.render)
        glutMainLoop()


   def render(self, area, ctx):

        .....

        glutSwapBuffers()
        glutPostRedisplay()


See also Texture wrapping an entire sphere in PyOpenGL

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Hi, thanks for your reply. But this is neither drawing the sphere in glut window,nor glutwindow is openning on GlArea. May you kindly check it a bit more? The updated code is attached – BaRud Jan 13 '18 at 13:03