Python OpenGL module - can't render basic triangle - python

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

Related

Moving a point using cordinate in 2D OpenGL Python

Suppose I have a point in pixel (200,200), and I would like to just shift it to (400,400) pixel. Is there any way to do it without glClear() as I don't want my other objects to get erased?
Here is the code that I am using for drawing a single point:
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
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():
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)
glutSwapBuffers()
glutInit()
glutInitDisplayMode(GLUT_RGBA)
glutInitWindowSize(1000, 1000)
glutInitWindowPosition(0, 0)
wind = glutCreateWindow(b"")
glutDisplayFunc(showScreen)
glutMainLoop()

OpenGl incomplete formation of the 3d cuboid when i use Gl_lines

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()

PyOpenGL not drawing anything after clearing

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()

how to apply lighting to .obj file on pyopengl

i implement arcball with an object from .obj file in the center
when i try to implement lighting, the object show strange behaviour
when i turn the object slightly, the object deconstruct and suddenly show the back side
this behaviour doesn's come up until i implement lighting
based on this How to correctly add a light to make object get a better view with pygame and pyopengl
this is what i do regarding the lighting impelementation
if __name__ == "__main__":
pygame.init()
display = (SCREEN_WIDTH,SCREEN_HEIGHT)
screen = pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
glMatrixMode( GL_PROJECTION );
gluPerspective(45, (display[0]/display[1]), 0.1, 30000.0)
glTranslatef(0.0, 0.0, -250)
glLight(GL_LIGHT0, GL_POSITION, (1, 1, 1, 0))
glLightfv(GL_LIGHT0, GL_AMBIENT, (0, 0, 0, 1))
glLightfv(GL_LIGHT0, GL_DIFFUSE, (2, 2, 2, 1))
while True:
mouse_pos = pygame.mouse.get_pos()
glMatrixMode( GL_MODELVIEW )
glLoadIdentity()
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
glEnable(GL_COLOR_MATERIAL)
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE )
object1.draw()
glDisable(GL_LIGHT0)
glDisable(GL_LIGHTING)
glDisable(GL_COLOR_MATERIAL)
pygame.display.flip()
pygame.time.wait(10)
You have to enable the Depth Test. Enable the depth test before the application loop:
glEnable(GL_DEPTH_TEST)

How to render two object in same z position in Open Gl?

I load a Candide3D model self.drawFace(vertices) and load a hat 3D model glCallList(obj.gl_list), but when I change the z position of the hat, it never stay on the Candidie3 model.
I also changed the gluPerspective(50,self.w/float(self.h), 1 , 250.0) camera matrix but, in almost every case the hat render in front of Candide3 model.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
setOrtho(self.w, self.h)
glEnable(GL_DEPTH_TEST)
glEnable(GL_TEXTURE_2D)
glDepthMask(GL_FALSE)
self.drawFace(vertices)
glDepthMask( GL_TRUE )
######## render next model ##########
glLightfv(GL_LIGHT0, GL_POSITION, (-40, 50, 100, 0.0))
glLightfv(GL_LIGHT0, GL_AMBIENT, (0.2, 0.2, 0.2, 1.0))
glLightfv(GL_LIGHT0, GL_DIFFUSE, (0.5, 0.5, 0.5, 1.0))
glEnable(GL_LIGHT0)
glEnable(GL_LIGHTING)
glEnable(GL_COLOR_MATERIAL)
glEnable(GL_DEPTH_TEST)
glShadeModel(GL_SMOOTH)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(50,self.w/float(self.h), 1 , 250.0)
glEnable(GL_DEPTH_TEST)
glMatrixMode(GL_MODELVIEW)
glBindTexture(GL_TEXTURE_2D, self.texture_image2)
glTranslate(self.tx,self.ty,-40)
self.tx,self.ty=self.track(shape2D)
glRotate(ry, 1, 0, 0)
glPushMatrix()
glCallList(obj.gl_list)
glPopMatrix()
glEnable(GL_TEXTURE_2D)

Categories

Resources