Найти - Пользователи
Полная версия: OpenGL перемещение курсора
Начало » GUI » OpenGL перемещение курсора
1
lup
Здравствуйте. Столкнулся со следующей проблемой: рисую сцену на 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()
П.С. Использую IDLE python 2.7 для редактирования. Так он мне функции дублирует частично почему-то 0_о. И что самое странное - интерпритатор на это не ругается. Эти дубли видно в коде, я их специально не стал удалять. Например KeyPressed, mouse_move? DrawGLScene..
DarkVortex
в модуле глут есть функция перемещения курсора, в си я использовал glutWarpPointer(screenX/2, screenY/2); ищи что-то подобное. Вижу по урокам NeHe учишся) если есть вопросы обращайся, постараюсь помочь. Ток я с opengl'ом в си работал и у меня не виндовс)
lup
DarkVortex
в модуле глут есть функция перемещения курсора, в си я использовал glutWarpPointer(screenX/2, screenY/2); ищи что-то подобное. Вижу по урокам NeHe учишся) если есть вопросы обращайся, постараюсь помочь. Ток я с opengl'ом в си работал и у меня не виндовс)
Отлично :) Спасибо за glutWarpPointer - работает (в смысле мышь перемещает). И теперь все ф-ии кросс-платформенные, не важно в мастдае запускать или где еще :) А в питоне все тоже самое что и в СИ что касается OpenGL. Я сначала в Си опенжеэлем занимался, потом на питон перебрался, чтобы за одно и с питоном разобраться :) Но основная проблема с прерыванием мыши так и не решилась. glutWarpPointer тоже вызывает прерывание перемещения мыши. Кстати, в Си у меня такой проблемы не было. Там CALLBACK не вызывался по от SetCursorPos().

Я полагаю, что тут решение чисто алгоритмическое, но вот никак не могу понять как фильтровать этот событие вызванное glutWarpPointer.
DarkVortex
У меня тоже была такая проблема, после перемешения курсора, координаты тоже то надо менять) если переместил в центр, то и в координать запиши что она в центре, и после вызова каллбека камера не двинется) все просто)
lup
Ну да, логично…
Значит так, мои действия:
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()
DarkVortex
напиши в асю 92141814 все объясню…
DarkVortex
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);//перемещаем мышь в центр

}
в функции ReSizeGLScene тебе нужно завести переменные с высотой и шириной экрана (screenX/screenY) и координаты центра (motion.posX/motion.posY)
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;
двигаем мышью, вызывается келлбек, проверяем куда двинули, находим разницу между координатоми текущего положения и центра(мышь там всегда) двигаем камеру и перемешаем мышь в центр, при перемещение в центр камера не двинеца потому что будет думать что там она и была) надеюсь теперь понятно…
писал движок в свое время. но что-то забросил( опыта пока маловато для такого( …хотя скорее упорства)
lup
Все оказалось просто :)
оказывается это не одно и тожее ))
if args != :
if args != __Window_Width/2 and args != __Window_Hight/2:

Ошибка в синтаксисе вкралась :)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB