Форум сайта python.su
Здравствуйте. Столкнулся со следующей проблемой: рисую сцену на OpenGL и хочу ее вращать мыщью. При этом сравниваю координаты мыши до и после перемещения (между эвентами) и на разницу/коэффициент смещаю сцену. Но курсор мыши тоже движется, и в конце концов доходит до края экрана…Так вот, хочу чтобы мышь, после обработки эвента и перемещения сцены, возвращалась в центр экрана. Подключил import win32api, использую SetCursorPos() в вункции обработки события перемещения мыши. Но тут возникла проблема: SetCursorPos() двигает мышь и тем самым снова вызывает glutMotionFunc(mouse_move)…. И зто дело благополучно зацикливается. :( Как бы сделать так, чтобы SetCursorPos не вызывал событие перемещения мыши? А еще лучше посоветуйте какой-нибудь кросс-платформенный способ передвинуть мышь :)
#!/bin/env python
# -*- coding: utf-8 -*-
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import sys
import pygame
import wx
import wx.wizard
import math
import win32api
rot = 0
quadObj = gluNewQuadric()
__Window_Hight = 600
__Window_Width = 800
print math.pi
#координаты прямоугольной системы координат
x = 0.1
y = 0.1
z = 0.1
#полярные координаты
pol = [0.0, 0.0, 0.0]
delta = 0.1
mouse_old = [0,0]
mouse_coord_dx_x = 0
mouse_coord_dx_y = 0
def InitGL(Width, Height):
glClearColor(0.0, 0.0, 0.0, 0.0)
glClearDepth(1.0)
glDepthFunc(GL_LESS)
glEnable(GL_DEPTH_TEST)
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
glEnable(GL_COLOR_MATERIAL)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0, float(Width)/float(Height), 0.1, 1000.0)
glMatrixMode(GL_MODELVIEW)
pygame.init()
def ReSizeGLScene(Width, Height):
if Height == 0: Height = 1
glViewport(0, 0, Width, Height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0, float(Width)/float(Height), 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
def KeyPressed(*args):
if args[0]=="\033": sys.exit()
def mouse_move(*args):
print "mouse:", args
def main():
app = wx.PySimpleApp()
frame = MyFrame()
panel = wx.Panel(self, -1)
panel.Bind(wx.EVT_MOTION, self.OnMove)
def OnMove(self, event):
pos = event.GetPosition()
print "mouse_move:", pos
def InitGL(Width, Height):
glClearColor(0.0, 0.0, 0.0, 0.0)
glClearDepth(1.0)
glDepthFunc(GL_LESS)
glEnable(GL_DEPTH_TEST)
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
glEnable(GL_COLOR_MATERIAL)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0, float(Width)/float(Height), 0.1, 1000.0)
glMatrixMode(GL_MODELVIEW)
pygame.init()
def ReSizeGLScene(Width, Height):
if Height == 0: Height = 1
glViewport(0, 0, Width, Height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0, float(Width)/float(Height), 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
def KeyPressed(*args):
if args[0]=="\033": sys.exit()
def mouse_move(*args):
print "mouse:", args
def InitGL(Width, Height):
glClearColor(0.0, 0.0, 0.0, 0.0)
glClearDepth(1.0)
glDepthFunc(GL_LESS)
glEnable(GL_DEPTH_TEST)
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
glEnable(GL_COLOR_MATERIAL)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0, float(Width)/float(Height), 0.1, 1000.0)
glMatrixMode(GL_MODELVIEW)
pygame.init()
def ReSizeGLScene(Width, Height):
global __Window_Hight
global __Window_Width
global x, y, z
__Window_Hight = Height
__Window_Width = Width
if Height == 0: Height = 1
glViewport(0, 0, Width, Height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0, float(Width)/float(Height), 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
def DrawGLScene():
global rot
global __Window_Hight
global __Window_Width
global mouse_coord_dx_x
global mouse_coord_dx_y
global x, y ,z
rot = (rot + 1) % 360
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
#glOrtho(-5,5, -5,5, 2,12);
gluLookAt( 0,0,0, x,y,z, 0.0, 1.0, 0.0)
glPushMatrix()
glTranslatef(0.0,0.0,-10.0)
glRotatef(rot,1.0,0.0,0.0)
glRotatef(rot,0.0,1.0,0.0)
glRotatef(rot,0.0,0.0,1.0)
glColor4f(0.0,0.7,0.1,1)
glutWireCube(3)
glPopMatrix()
glColor3f(1.0, 1.0, 1.0)
glTranslatef(0.0,0.0,-10.0)
glBegin(GL_LINES)
glVertex3f(0, 0, -12)
glVertex3f(mouse_coord_dx_x - __Window_Width/2, __Window_Hight/2 - mouse_coord_dx_y, -12)
glEnd()
glColor3f(1, 1, 1)
glBegin(GL_QUADS)
glVertex3f(-10.0, -5.0, 10.0)
glVertex3f(10.0, -5.0, 10.0)
glVertex3f(10.0, -5.0, -10.0)
glVertex3f(-10.0, -5.0, -10.0)
glEnd()
glPushMatrix()
#glTranslatef(x,y,z)
#glRotatef(pol[0],1.0,0.0,0.0)
#glRotatef(pol[1],0.0,1.0,0.0)
glutWireCube(3)
glPopMatrix()
glutSwapBuffers()
def KeyPressed(*args):
global delta
if args[0]=="\033": sys.exit()
if args[0]=='w': #up
#print "w: pol = ", pol
Normal2Polar(x, y, z)
pol[0] -= delta
Polar2Normal( pol[0], pol[1], pol[2])
print "x,y,x:", x,y,z
if args[0]=='s': #down
print "s"
Normal2Polar(x, y, z)
pol[0] += delta
Polar2Normal( pol[0], pol[1], pol[2])
print "x,y,x:", x,y,z
if args[0]=='a': #left
print "a"
Normal2Polar(x, y, z)
pol[1] -= delta
Polar2Normal( pol[0], pol[1], pol[2])
print "x,y,x:", x,y,z
if args[0]=='d': #right
print "d"
Normal2Polar(x, y, z)
pol[1] += delta
Polar2Normal( pol[0], pol[1], pol[2])
print "x,y,x:", x,y,z
ReSizeGLScene(__Window_Width, __Window_Hight)
def mouse_move(*args):
global mouse_coord_dx_x
global mouse_coord_dx_y
global __Window_Hight
global __Window_Width
global mouse_old
win32api.SetCursorPos([__Window_Width/2, __Window_Hight/2])
mouse_coord_dx_x = mouse_old[0] - args[0]
mouse_coord_dx_y = mouse_old[1] - args[1]
#print "mouse_move:", mouse_coord_dx_x, mouse_coord_dx_y
Normal2Polar(x, y, z)
pol[1] += mouse_coord_dx_x/155.0
pol[0] += mouse_coord_dx_y/155.0
Polar2Normal( pol[0], pol[1], pol[2])
print "x,y,x:", x,y,z
mouse_old = args
def mouse(*args):
#print "mouse:", args
print mouse_coord_dx_x, mouse_coord_dx_y
def main():
glutInit(sys.argv)
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH)
glutInitWindowSize(__Window_Width, __Window_Hight)
glutInitWindowPosition(0, 0)
glutCreateWindow("OpenGL demo")
glutDisplayFunc(DrawGLScene)
glutIdleFunc(DrawGLScene)
glutReshapeFunc(ReSizeGLScene)
glutKeyboardFunc(KeyPressed)
glutMouseFunc(mouse)
glutMotionFunc(mouse_move)
glutPassiveMotionFunc(mouse_move)
InitGL(400, 300)
glutMainLoop()
print mousepos()
def Polar2Normal( a, b, r):
global x
global y
global z
x = r * math.cos(a) * math.cos(b)
y = r * math.sin(a)
z = -r* math.cos(a) * math.sin(b)
def Normal2Polar(x, y, z):
global pol
pol[2] = math.sqrt(x*x+y*y+z*z)
if pol[2] != 0:
pol[0] = math.asin(y/pol[2])
if x != 0 and y != 0:
pol[1] = math.acos(x/math.sqrt(x*x+z*z))
if z>0:
pol[1] = 2 * math.pi - pol[1]
main()
Офлайн
в модуле глут есть функция перемещения курсора, в си я использовал glutWarpPointer(screenX/2, screenY/2); ищи что-то подобное. Вижу по урокам NeHe учишся) если есть вопросы обращайся, постараюсь помочь. Ток я с opengl'ом в си работал и у меня не виндовс)
Отредактировано (Июнь 2, 2011 00:14:58)
Офлайн
DarkVortexОтлично :) Спасибо за glutWarpPointer - работает (в смысле мышь перемещает). И теперь все ф-ии кросс-платформенные, не важно в мастдае запускать или где еще :) А в питоне все тоже самое что и в СИ что касается OpenGL. Я сначала в Си опенжеэлем занимался, потом на питон перебрался, чтобы за одно и с питоном разобраться :) Но основная проблема с прерыванием мыши так и не решилась. glutWarpPointer тоже вызывает прерывание перемещения мыши. Кстати, в Си у меня такой проблемы не было. Там CALLBACK не вызывался по от SetCursorPos().
в модуле глут есть функция перемещения курсора, в си я использовал glutWarpPointer(screenX/2, screenY/2); ищи что-то подобное. Вижу по урокам NeHe учишся) если есть вопросы обращайся, постараюсь помочь. Ток я с opengl'ом в си работал и у меня не виндовс)
Отредактировано (Июнь 2, 2011 12:04:35)
Офлайн
У меня тоже была такая проблема, после перемешения курсора, координаты тоже то надо менять) если переместил в центр, то и в координать запиши что она в центре, и после вызова каллбека камера не двинется) все просто)
Офлайн
Ну да, логично…
Значит так, мои действия:
1. движение мыши, CALLBACK.
2. В колбэке: старые координаты минус новые, разницу запоминаем. При вызове DrawGLScene на эту разницу сдвинем сцену.
3. старые координаты заменяем новыми.
4. двигаем курсор в центр экрана.
Итог: при движении мыши курсор прыгает, что логично, а сцена стоит и не шевелится
Если двигать курсоh в DrawGLScene после перемещения камеры, то камера дергается вместе с курсором и опять встает на место где была..
В общем тут понятно все. И я так же делал в Си как ты пишешь. И все работало.
Я заметил, что glutWarpPointer, зараза, вызывает CALLBACK мыши! т.е. когда я переместил мышь, подвинул камеру и вызываю glutWarpPointer, то мышь перемещается обратно. Это перемещение вызывает CALLBACK и камера по тому же алгоритму перемещается вместе с курсором обратно. :((
Вот ведь блин… Как бы сделать так чтобы glutWarpPointer не вызывал колбэк?
Может дело в том, что я не сцену саму двигаю, а камеру с помощью gluLookat, но это по моему одно и тоже..
Или я чего-то не понимаю…. В Си glutWarpPointer вызывает колбэк?
вот мой исходник:
#!/bin/env python
# -*- coding: utf-8 -*-
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import sys
import pygame
import wx
import wx.wizard
import math
import win32api
rot = 0
quadObj = gluNewQuadric()
__Window_Hight = 600
__Window_Width = 800
print math.pi
#координаты прямоугольной системы координат
x = 0.1
y = 0.1
z = 0.1
#полярные координаты
pol = [0.0, 0.0, 0.0]
delta = 0.1
mouse_old = [0,0]
mouse_coord_dx_x = 0
mouse_coord_dx_y = 0
mm = 0
def InitGL(Width, Height):
glClearColor(0.0, 0.0, 0.0, 0.0)
glClearDepth(1.0)
glDepthFunc(GL_LESS)
glEnable(GL_DEPTH_TEST)
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
glEnable(GL_COLOR_MATERIAL)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0, float(Width)/float(Height), 0.1, 1000.0)
glMatrixMode(GL_MODELVIEW)
pygame.init()
def ReSizeGLScene(Width, Height):
global __Window_Hight
global __Window_Width
global x, y, z
__Window_Hight = Height
__Window_Width = Width
if Height == 0: Height = 1
glViewport(0, 0, Width, Height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0, float(Width)/float(Height), 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
def DrawGLScene():
global rot
global __Window_Hight
global __Window_Width
global mouse_coord_dx_x
global mouse_coord_dx_y
global x, y ,z
global mm
rot = (rot + 1) % 360
if mm == 1:
glutWarpPointer(__Window_Width/2, __Window_Hight/2)
print "wrap"
mm = 0
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
lookAround()
#glOrtho(-5,5, -5,5, 2,12);
glPushMatrix()
glTranslatef(0.0,0.0,-10.0)
glRotatef(rot,1.0,0.0,0.0)
glRotatef(rot,0.0,1.0,0.0)
glRotatef(rot,0.0,0.0,1.0)
glColor4f(0.0,0.7,0.1,1)
glutWireCube(3)
glPopMatrix()
glColor3f(1.0, 1.0, 1.0)
glTranslatef(0.0,0.0,-10.0)
glBegin(GL_LINES)
glVertex3f(0, 0, -12)
glVertex3f(mouse_coord_dx_x - __Window_Width/2, __Window_Hight/2 - mouse_coord_dx_y, -12)
glEnd()
glColor3f(1, 1, 1)
glBegin(GL_QUADS)
glVertex3f(-10.0, -5.0, 10.0)
glVertex3f(10.0, -5.0, 10.0)
glVertex3f(10.0, -5.0, -10.0)
glVertex3f(-10.0, -5.0, -10.0)
glEnd()
glPushMatrix()
#glTranslatef(x,y,z)
#glRotatef(pol[0],1.0,0.0,0.0)
#glRotatef(pol[1],0.0,1.0,0.0)
glutWireCube(3)
#треугольники
glBegin(GL_TRIANGLES)
glVertex3f(0, 8, -10)
glVertex3f(1, 6, -10)
glVertex3f(-1, 6, -10)
glEnd()
glPopMatrix()
glutSwapBuffers()
def KeyPressed(*args):
global delta
if args[0]=="\033": sys.exit()
if args[0]=='w': #up
#print "w: pol = ", pol
Normal2Polar(x, y, z)
pol[0] -= delta
Polar2Normal( pol[0], pol[1], pol[2])
print "x,y,x:", x,y,z
if args[0]=='s': #down
print "s"
Normal2Polar(x, y, z)
pol[0] += delta
Polar2Normal( pol[0], pol[1], pol[2])
print "x,y,x:", x,y,z
if args[0]=='a': #left
print "a"
Normal2Polar(x, y, z)
pol[1] -= delta
Polar2Normal( pol[0], pol[1], pol[2])
print "x,y,x:", x,y,z
if args[0]=='d': #right
print "d"
Normal2Polar(x, y, z)
pol[1] += delta
Polar2Normal( pol[0], pol[1], pol[2])
print "x,y,x:", x,y,z
ReSizeGLScene(__Window_Width, __Window_Hight)
def lookAround():
global x,y,z
glLoadIdentity()
gluLookAt( 0,0,0, x,y,z, 0.0, 1.0, 0.0)
def mouse_move(*args):
global mouse_coord_dx_x
global mouse_coord_dx_y
global __Window_Hight
global __Window_Width
global mouse_old
global mm
mouse_coord_dx_x = mouse_old[0] - args[0]
mouse_coord_dx_y = mouse_old[1] - args[1]
mouse_old = args
#print "mouse_move:", mouse_coord_dx_x, mouse_coord_dx_y
print "mouse_old", mouse_old
print "args:", args
if mouse_coord_dx_x != 0 or mouse_coord_dx_y != 0 :
Normal2Polar(x, y, z)
pol[1] += mouse_coord_dx_x/155.0
pol[0] += mouse_coord_dx_y/155.0
Polar2Normal( pol[0], pol[1], pol[2])
print "x,y,x:", x,y,z
mm = 1
# mouse_old = [__Window_Width/2, __Window_Hight/2]
def mouse(*args):
#print "mouse:", args
print mouse_coord_dx_x, mouse_coord_dx_y
def main():
glutInit(sys.argv)
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH)
glutInitWindowSize(__Window_Width, __Window_Hight)
glutInitWindowPosition(0, 0)
glutCreateWindow("OpenGL demo")
glutDisplayFunc(DrawGLScene)
glutIdleFunc(DrawGLScene)
glutReshapeFunc(ReSizeGLScene)
glutKeyboardFunc(KeyPressed)
#glutMouseFunc(mouse)
#glutMotionFunc(mouse_move)
glutPassiveMotionFunc(mouse_move)
InitGL(400, 300)
# glutGameModeString("640x480:16@60")
# glutEnterGameMode()
glutMainLoop()
print mousepos()
def Polar2Normal( a, b, r):
global x
global y
global z
x = r * math.cos(a) * math.cos(b)
y = r * math.sin(a)
z = -r* math.cos(a) * math.sin(b)
def Normal2Polar(x, y, z):
global pol
pol[2] = math.sqrt(x*x+y*y+z*z)
if pol[2] != 0:
pol[0] = math.asin(y/pol[2])
if x != 0 and y != 0:
pol[1] = math.acos(x/math.sqrt(x*x+z*z))
if z>0:
pol[1] = 2 * math.pi - pol[1]
main()
Отредактировано (Июнь 3, 2011 10:53:59)
Офлайн
напиши в асю 92141814 все объясню…
Офлайн
void motionFunc(int x, int y){
printf(" %u x %u.\n", x, y);
if(motion.posY < y){//проверяем смещение по Y
lookupdown += mousespeed*(y-motion.posY);//поворачиваем сцену вправо
}else if(motion.posY > y){
lookupdown -= mousespeed*(motion.posY-y);//влево
}
/*тоже самое с X координатами*/
if(motion.posX < x){
heading -= mousespeed*(x-motion.posX);
yrot = heading;
}else if(motion.posX > x){
heading += mousespeed*(motion.posX-x);
yrot = heading;
}
glutWarpPointer(screenX/2, screenY/2);//перемещаем мышь в центр
}
void ReSizeGLScene(int Width, int Height) {
printf("Function ReSizeGLScene %u x %u.\n", Width, Height);
screenX = Width;
screenY = Height;
motion.posY = screenY/2;
motion.posX = screenX/2;
Отредактировано (Июнь 3, 2011 13:02:33)
Офлайн
Все оказалось просто :)
оказывается это не одно и тожее ))
if args != :
if args != __Window_Width/2 and args != __Window_Hight/2:
Ошибка в синтаксисе вкралась :)
Офлайн