Related
Suppose I want to draw 3 points in my window. One point at a time with 1 second delay each. So I want the window to open when I run the code, then wait 1 second and draw first point and then wait another second and write the second point in the same window.
But what is happening is that, when I run the code, it shows nothing and then shows all three points at once after 3 seconds have passed.
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
import time
def draw_points(x0,y0):
glPointSize(5)
glBegin(GL_POINTS)
glVertex2f(x0,y0)
glEnd()
def iterate():
glViewport(0, 0, 1000, 1000)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0.0, 1000, 0.0, 1000, 0.0, 1.0)
glMatrixMode (GL_MODELVIEW)
glLoadIdentity()
def showScreen():
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
iterate()
glColor3f(255, 255, 255)
draw_points(200,200)
time.sleep(1)
draw_points(300,300)
time.sleep(1)
draw_points(400,400)
glutSwapBuffers()
glutInit()
glutInitDisplayMode(GLUT_RGBA)
glutInitWindowSize(1000, 1000)
glutInitWindowPosition(0, 0)
wind = glutCreateWindow(b"")
glutDisplayFunc(showScreen)
glutMainLoop()
Don't wait in the application loop. The application executed continuously and the scene is redrawn in every frame. Measure the time and draw the points depending on the time elapsed. You can get the elapsed time in milliseconds with glutGet(GLUT_ELAPSED_TIME):
def showScreen():
elapesed_ms = glutGet(GLUT_ELAPSED_TIME)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
iterate()
glColor3f(255, 255, 255)
draw_points(200,200)
if elapesed_ms > 1000:
draw_points(300,300)
if elapesed_ms > 2000:
draw_points(400,400)
glutSwapBuffers()
from tokenize import Double
from OpenGL.GL import *
from OpenGL.GLU import *
import pygame
from pygame.locals import *
import serial
#ser = serial.Serial('/dev/tty.usbserial', 38400, timeout=1)
ser = serial.Serial('COM5', 38400, timeout=1)
ax = ay = az =0.0
dx = dy = dz =0.0
def resize(width, height):
if height==0:
height=1
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45, 1.0*width/height, 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
def init():
glShadeModel(GL_SMOOTH)
glClearColor(0.0, 0.0, 0.0, 0.0)
glClearDepth(1.0)
glEnable(GL_DEPTH_TEST)
glDepthFunc(GL_LEQUAL)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
def drawText(position, textString):
font = pygame.font.SysFont ("Courier", 18, True)
textSurface = font.render(textString, True, (255,255,255,255), (0,0,0,255))
textData = pygame.image.tostring(textSurface, "RGBA", True)
glRasterPos3d(*position)
glDrawPixels(textSurface.get_width(), textSurface.get_height(), GL_RGBA, GL_UNSIGNED_BYTE, textData)
def draw():
global rquad
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity()
glTranslatef(0,0.0,-7.0)
osd_text = "pitch: " + str("{0:.2f}".format(ay)) + ", roll: " + str("{0:.2f}".format(ax)) + ", yaw: " + str("{0:.2f}".format(az))
drawText((-2,-2, 2), osd_text)
drawText((-2,2, 0), "PRESS Z TO CALIBRATE OFFSETS")
# the way I'm holding the IMU board, X and Y axis are switched
# with respect to the OpenGL coordinate system
glRotatef((az-dz)*-1, 0.0, 1.0, 0.0) # Yaw, rotate around y-axis
glRotatef(ay-dy ,1.0,0.0,0.0) # Pitch, rotate around x-axis
glRotatef((-1*ax)-dx ,0.0,0.0,1.0) # Roll, rotate around z-axis
glBegin(GL_QUADS)
#glColor3f(0.0,1.0,0.0)
glVertex3f( 1.0, 0.2,-1.0)
glVertex3f(-1.0, 0.2,-1.0)
glVertex3f(-1.0, 0.2, 1.0)
glVertex3f( 1.0, 0.2, 1.0)
#glColor3f(1.0,0.5,0.0)
glVertex3f( 1.0,-0.2, 1.0)
glVertex3f(-1.0,-0.2, 1.0)
glVertex3f(-1.0,-0.2,-1.0)
glVertex3f( 1.0,-0.2,-1.0)
#glColor3f(1.0,0.0,0.0)
glVertex3f( 1.0, 0.2, 1.0)
glVertex3f(-1.0, 0.2, 1.0)
glVertex3f(-1.0,-0.2, 1.0)
glVertex3f( 1.0,-0.2, 1.0)
#glColor3f(1.0,1.0,0.0)
glVertex3f( 1.0,-0.2,-1.0)
glVertex3f(-1.0,-0.2,-1.0)
glVertex3f(-1.0, 0.2,-1.0)
glVertex3f( 1.0, 0.2,-1.0)
#glColor3f(0.0,0.0,1.0)
glVertex3f(-1.0, 0.2, 1.0)
glVertex3f(-1.0, 0.2,-1.0)
glVertex3f(-1.0,-0.2,-1.0)
glVertex3f(-1.0,-0.2, 1.0)
#glColor3f(1.0,0.0,1.0)
glVertex3f( 1.0, 0.2,-1.0)
glVertex3f( 1.0, 0.2, 1.0)
glVertex3f( 1.0,-0.2, 1.0)
glVertex3f( 1.0,-0.2,-1.0)
glEnd()
def read_data():
global ax, ay, az
ax = ay = az = 0
line = ser.readline().decode('utf-8')
line = line.strip()
imu = line.split(',')
ax = float(imu[0])
ay = float(imu[1])
az = float(imu[2])
def main():
video_flags = OPENGL|DOUBLEBUF
global dx, dy, dz
pygame.init()
screen = pygame.display.set_mode((640,480), video_flags)
pygame.display.set_caption("Press Esc to quit")
resize(640,480)
init()
frames = 0
ticks = pygame.time.get_ticks()
while 1:
event = pygame.event.poll()
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
pygame.quit() #* quit pygame properly
break
if event.type == KEYDOWN and event.key == K_z:
dx=ax
dy=ay
dz=az
read_data()
draw()
pygame.display.flip()
frames = frames+1
print ("fps: %d" % ((frames*1000)/(pygame.time.get_ticks()-ticks)))
ser.close()
if __name__ == '__main__': main()
I want to build an IMU visualization tool, this code works fine but as I am a complete beginner I am facing difficulties in building a custom model using GL_QUADS, even when i tried to display the cuboid(previously GL_Quads method) in GL_Lines there were a few portions missing as shown in the image, please guide me on how to build a model in OpenGL, I want to draw a 3D bi-copter in it.
Summary: please guide me on building any type of 3D polygon in OpenGL.
The vertex order of line primitives differs from the vertex order of quads. See GL_LINES not showing up on top of cube?. However, you can draw GL_QUADS and change the rasterization mode with glPolygonMode:
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
glBegin(GL_QUADS)
#[...]
glEnd()
Minimal example:
import pygame
from OpenGL.GL import *
from OpenGL.GLU import *
class Cube:
def __init__(self):
self.v = [(-1,-1,-1), ( 1,-1,-1), ( 1, 1,-1), (-1, 1,-1), (-1,-1, 1), ( 1,-1, 1), ( 1, 1, 1), (-1, 1, 1)]
self.surfaces = [(0,1,2,3), (5,4,7,6), (4,0,3,7),(1,5,6,2), (4,5,1,0), (3,2,6,7)]
def draw(self):
glEnable(GL_DEPTH_TEST)
glLineWidth(5)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
glBegin(GL_QUADS)
for i, quad in enumerate(self.surfaces):
for iv in quad:
glVertex3fv(self.v[iv])
glEnd()
glDisable( GL_POLYGON_OFFSET_FILL )
def set_projection(w, h):
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45, w / h, 0.1, 50.0)
glMatrixMode(GL_MODELVIEW)
pygame.init()
window = pygame.display.set_mode((400, 300), pygame.DOUBLEBUF | pygame.OPENGL | pygame.RESIZABLE)
clock = pygame.time.Clock()
set_projection(*window.get_size())
cube = Cube()
angle_x, angle_y = 0, 0
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
elif event.type == pygame.VIDEORESIZE:
glViewport(0, 0, event.w, event.h)
set_projection(event.w, event.h)
glLoadIdentity()
glTranslatef(0, 0, -5)
glRotatef(angle_y, 0, 1, 0)
glRotatef(angle_x, 1, 0, 0)
angle_x += 1
angle_y += 0.4
glClearColor(0.5, 0.5, 0.5, 1)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
cube.draw()
pygame.display.flip()
pygame.quit()
exit()
I used Glut for making window and wanted to draw triangle, then on click button redraw it, but after clearing window I can't draw again. Does something wrong with Buffer depth and buffer bit? If I cleared it do I need to setup both again in my draw function?
def drawSomething():
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glTranslatef(-2.5, 0.5, -6.0)
glColor3f( 1.0, 1.5, 0.0 )
glPolygonMode(GL_FRONT, GL_FILL)
glBegin(GL_TRIANGLES)
glVertex3f(2.0,-1.2,0.0)
glVertex3f(2.6,0.0,0.0)
glVertex3f(2.9,-1.2,0.0)
glEnd()
glFlush()
def funcForUpdate():
glClearColor(0.0, 0.0, 0.0, 0)
glClear(GL_COLOR_BUFFER_BIT)
glEnable(GL_TEXTURE_2D)
glBegin(GL_QUADS)
glTexCoord2f(0.0, 0.0)
glVertex2f(0.0, 0.0)
glTexCoord2f(0.0, 1.0)
glVertex2f(0.0, width)
glTexCoord2f(1.0, 1.0)
glVertex2f(height, width)
glTexCoord2f(1.0, 0.0)
glVertex2f(height, 0.0)
glEnd()
glFlush()
def resizeUpdateFunc(width, height):
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
gluOrtho2D(0.0, width, 0.0, height)
def handleKey(bkey,x,y):
key = bkey.decode("utf-8")
if key == "a":
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
drawSomething()
glFlush()
glutInit()
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)
glutInitWindowSize(width, height)
glutInitWindowPosition(0, 0)
glutCreateWindow("test")
drawSomething()
glutDisplayFunc(funcForUpdate)
glutReshapeFunc(resizeUpdateFunc)
glutKeyboardFunc(handleKey)
glutMainLoop()
See glutDisplayFunc:
[...] sets the display callback for the current window. [...] The redisplay state for a window can be either set explicitly by calling glutPostRedisplay or implicitly as the result of window damage reported by the window system.
In fact, a triangle is drawn in drawSomething, but it is immediately overdrawn in funcForUpdate.
Add a state drawTriangle and set the state in handleKey:
drawTriangle = False
def handleKey(bkey, x, y):
global drawTriangle
key = bkey.decode("utf-8")
if key == "a":
drawTriangle = not drawTriangle
glutPostRedisplay()
Draw depending on the variable drawTriangle in funcForUpdate:
def funcForUpdate():
glClearColor(0, 0, 0, 0)
glClear(GL_COLOR_BUFFER_BIT)
# [...]
if drawTriangle:
# [...]
glFlush()
A complete example:
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
drawTriangle = False
def funcForUpdate():
glClearColor(0, 0, 0, 0)
glClear(GL_COLOR_BUFFER_BIT)
glColor3f(1, 1, 0)
glBegin(GL_QUADS)
glVertex2f(0.0, 0.0)
glVertex2f(0, height)
glVertex2f(width, height)
glVertex2f(width, 0)
glEnd()
if drawTriangle:
glPushMatrix()
glLoadIdentity()
glTranslate(width/2, height/2, 0)
glColor3f(1, 0, 0)
glBegin(GL_TRIANGLES)
glVertex3f(-width/4, -height/4, 0)
glVertex3f(width/4, -height/4, 0)
glVertex3f(width/4, height/4, 0)
glEnd()
glPopMatrix()
glFlush()
def resizeUpdateFunc(width, height):
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluOrtho2D(0.0, width, 0.0, height)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
def handleKey(bkey, x, y):
global drawTriangle
key = bkey.decode("utf-8")
if key == "a":
drawTriangle = not drawTriangle
glutPostRedisplay()
width, height = 320, 200
glutInit()
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)
glutInitWindowSize(width, height)
glutInitWindowPosition(0, 0)
glutCreateWindow("test")
glutDisplayFunc(funcForUpdate)
glutReshapeFunc(resizeUpdateFunc)
glutKeyboardFunc(handleKey)
glutMainLoop()
I want to overlay 3d objects on OpenCV feed. I found an example here That uses webcam video as texture in OpenGL. I changed some part so that it works with cv2. Now the output is something strange
CODE
import cv2
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import numpy as np
import sys
#window dimensions
width = 1280
height = 720
nRange = 1.0
global capture
capture = None
def cv2array(im):
h,w,c=im.shape
a = np.fromstring(
im.tostring(),
dtype=im.dtype,
count=w*h*c)
a.shape = (h,w,c)
return a
def init():
#glclearcolor (r, g, b, alpha)
glClearColor(0.0, 0.0, 0.0, 1.0)
glutDisplayFunc(display)
glutReshapeFunc(reshape)
glutKeyboardFunc(keyboard)
glutIdleFunc(idle)
def idle():
#capture next frame
global capture
_,image = capture.read()
cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
#you must convert the image to array for glTexImage2D to work
#maybe there is a faster way that I don't know about yet...
#print image_arr
# Create Texture
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGB,
720,1280,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
image)
cv2.imshow('frame',image)
glutPostRedisplay()
def display():
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glEnable(GL_TEXTURE_2D)
#glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
#glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
#glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)
#this one is necessary with texture2d for some reason
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
# Set Projection Matrix
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluOrtho2D(0, width, 0, height)
# Switch to Model View Matrix
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
# Draw textured Quads
glBegin(GL_QUADS)
glTexCoord2f(0.0, 0.0)
glVertex2f(0.0, 0.0)
glTexCoord2f(1.0, 0.0)
glVertex2f(width, 0.0)
glTexCoord2f(1.0, 1.0)
glVertex2f(width, height)
glTexCoord2f(0.0, 1.0)
glVertex2f(0.0, height)
glEnd()
glFlush()
glutSwapBuffers()
def reshape(w, h):
if h == 0:
h = 1
glViewport(0, 0, w, h)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
# allows for reshaping the window without distoring shape
if w <= h:
glOrtho(-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange)
else:
glOrtho(-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
def keyboard(key, x, y):
global anim
if key == chr(27):
sys.exit()
def main():
global capture
#start openCV capturefromCAM
capture = cv2.VideoCapture(0)
print capture
capture.set(3,1280)
capture.set(4,720)
glutInit(sys.argv)
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH)
glutInitWindowSize(width, height)
glutInitWindowPosition(100, 100)
glutCreateWindow("OpenGL + OpenCV")
init()
glutMainLoop()
main()
I find it very unlikely that your camera is providing a 720 pixel wide and 1280 pixel high image as you tell to OpenGL here:
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGB,
720,1280, // <---- HERE
0,
GL_RGB,
GL_UNSIGNED_BYTE,
image)
It seems you just mixed up those two parametes, so the data is reinterpreted as such, resulting in the output you got.
I'm trying to use the OpenGL module with Python.
Here is my source:
pygame.init()
screen = pygame.display.set_mode((800, 600), HWSURFACE|OPENGL|DOUBLEBUF)
def init():
glEnable(GL_DEPTH_TEST)
glShadeModel(GL_FLAT)
glClearColor(1.0, 1.0, 1.0, 0.0)
glEnable(GL_COLOR_MATERIAL)
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
glLight(GL_LIGHT0, GL_POSITION, (0, 1, 1, 0))
def draw():
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glColor3fv((25, 123, 180))
glBegin(GL_TRIANGLES)
glVertex3f( 0.0, 10.0, 0.0)
glVertex3f(-10.0,-10.0, 0.0)
glVertex3f( 10.0,-10.0, 0.0)
glEnd()
def run():
init()
while True:
draw()
pygame.display.flip()
run()
Can anyone see what is wrong? I'm just trying to draw a simple 3 pointed vertex, yet nothing shows up on the screen. Occasionally I get a bright pink screen. I'm confident it's a basic error.
You need to setup view and projection matrices.
http://www.opengl.org/resources/faq/technical/transformations.htm#tran0090