![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
||||
|
||||
![]() Вопрос не столько по Delphi, сколько по WinAPI.
Пишу программку на чистом WinAPI, застопорился на обработке крысиных событий. Сабж: есть некое поле, прорисованное в пространстве (камера под углом ~45 градусов). Надо узнать координаты мыши над этим полем (если она, конечно, над ним). Просчитывать вручную, конечно, можно (благо координаты известны и геометрию знаем), но уж очень не хочется... ![]() Оставайтесь хорошими людьми... VK id2634397, ds [at] phoenix [dot] dj |
#2
|
||||
|
||||
![]() Цитата:
Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |
#3
|
||||
|
||||
![]() Поле двигается, вертится, размер формы меняется как угодно, есть полноэкранные и оконные режимы
![]() Я так понимаю, в пакете gl* не предусмотрено получение координат в пространстве по координатам мыши над "камерой"? Оставайтесь хорошими людьми... VK id2634397, ds [at] phoenix [dot] dj |
#4
|
||||
|
||||
![]() Все-таки OpenGL, а не просто WinAPI.
![]() Ага, нашёл. Смотри, может подойдёт: Код:
{**********************************************************************} {* Иллюстрация к книге "OpenGL в проектах Delphi" *} {* Краснов М.В. softgl@chat.ru *} {**********************************************************************} {*********************************************************************} {(c) Copyright 1993, Silicon Graphics, Inc. ALL RIGHTS RESERVED} program Select; uses Messages, Windows, OpenGL; const AppName = 'GL_Select'; MAXOBJS = 20; // максимальное число объектов MAXSELECT = 4; // размер буфера выбора {--- запись для хранения объектов ---} type TGLObject = record // объект - треугольник {вершины треугольника} v1 : Array [0..1] of GLFloat; v2 : Array [0..1] of GLFloat; v3 : Array [0..1] of GLFloat; color : Array [0..2] of GLFloat; // цвет объекта end; Var Window : HWnd; Message : TMsg; WindowClass : TWndClass; windW, windH : GLint; dc : HDC; hrc : HGLRC; ps : TPAINTSTRUCT; objects : Array [0..MAXOBJS - 1] of TGLObject; // массив объектов vp : Array [0..3] of GLint; selectBuf : Array [0..MAXSELECT - 1] of GLuint;// буфер выбора hit : GLint; mouseX, mouseY : Integer; {======================================================================= Инициализация объектов} procedure InitObjects; var i : GLint ; x, y : GLfloat ; begin For i := 0 to MAXOBJS - 1 do begin x := random(300) - 150; y := random(300) - 150; // вершины треугольника - случайно objects[i].v1[0] := x + random(50) - 25; objects[i].v2[0] := x + random(50) - 25; objects[i].v3[0] := x + random(50) - 25; objects[i].v1[1] := y + random(50) - 25; objects[i].v2[1] := y + random(50) - 25; objects[i].v3[1] := y + random(50) - 25; // цвета выбираются случайными objects[i].color[0] := (random(100) + 50) / 150.0; objects[i].color[1] := (random(100) + 50) / 150.0; objects[i].color[2] := (random(100) + 50) / 150.0; end; end; {======================================================================= Рисование массива объектов} procedure Render (mode : GLenum); // параметр - режим (выбора/рисования) var i : GLuint; begin For i := 0 to MAXOBJS - 1 do begin If mode = GL_SELECT then glLoadName(i); // загрузка очередного имени glColor3fv(@objects[i].color); // цвет для очередного объекта glBegin(GL_POLYGON); // рисуем треугольник glVertex2fv(@objects[i].v1); glVertex2fv(@objects[i].v2); glVertex2fv(@objects[i].v3); glEnd; end; end; {======================================================================= Выбор объекта в точке} function DoSelect(x : GLint; y : GLint) : GLint; var hits : GLint; begin glSelectBuffer(MAXSELECT, @selectBuf); // создание буфера выбора glRenderMode(GL_SELECT); // режим выбора // режим выбора нужен для работы следующих команд glInitNames; // инициализация стека имен glPushName(0); // помещение имени в стек имен glGetIntegerv(GL_VIEWPORT, @vp); glMatrixMode(GL_PROJECTION); glLoadIdentity; gluPickMatrix(x, windH-y, 4, 4, @vp); gluOrtho2D(-175, 175, -175, 175); glMatrixMode(GL_MODELVIEW); glClear(GL_COLOR_BUFFER_BIT); Render(GL_SELECT); // рисуем массив объектов с выбором hits := glRenderMode(GL_RENDER); if hits <= 0 then DoSelect := -1 else DoSelect := selectBuf[3]; end; {======================================================================= Изменение цвета объекта номер h} procedure RecolorTri (h : GLint); begin objects[h].color[0] := (random(100) + 50) / 150.0; objects[h].color[1] := (random(100) + 50) / 150.0; objects[h].color[2] := (random(100) + 50) / 150.0; end; {======================================================================= Основная процедура рисования картинки} procedure DrawScene; begin glPushMatrix; glGetIntegerv(GL_VIEWPORT, @vp); glMatrixMode(GL_PROJECTION); glLoadIdentity; gluOrtho2D(-175, 175, -175, 175); glMatrixMode(GL_MODELVIEW); glClear(GL_COLOR_BUFFER_BIT); Render(GL_RENDER); // рисуем массив объектов без выбора glPopMatrix; glFlush; end; procedure SetDCPixelFormat (hdc : HDC); var pfd : TPIXELFORMATDESCRIPTOR; // данные формата пикселей nPixelFormat : Integer; Begin With pfd do begin nSize := sizeof (TPIXELFORMATDESCRIPTOR); // размер структуры nVersion := 1; // номер версии dwFlags := PFD_DRAW_TO_WINDOW OR PFD_SUPPORT_OPENGL; // множество битовых флагов, определяющих устройство и интерфейс iPixelType := PFD_TYPE_RGBA; // режим для изображения цветов cColorBits := 16; // число битовых плоскостей в каждом буфере цвета cRedBits := 0; // число битовых плоскостей красного в каждом буфере RGBA cRedShift := 0; // смещение от начала числа битовых плоскостей красного в каждом буфере RGBA cGreenBits := 0; // число битовых плоскостей зелёного в каждом буфере RGBA cGreenShift := 0; // смещение от начала числа битовых плоскостей зелёного в каждом буфере RGBA cBlueBits := 0; // число битовых плоскостей синего в каждом буфере RGBA cBlueShift := 0; // смещение от начала числа битовых плоскостей синего в каждом буфере RGBA cAlphaBits := 0; // число битовых плоскостей альфа в каждом буфере RGBA cAlphaShift := 0; // смещение от начала числа битовых плоскостей альфа в каждом буфере RGBA cAccumBits := 0; // общее число битовых плоскостей в буфере аккумулятора cAccumRedBits := 0; // число битовых плоскостей красного в буфере аккумулятора cAccumGreenBits := 0; // число битовых плоскостей зелёного в буфере аккумулятора cAccumBlueBits := 0; // число битовых плоскостей синего в буфере аккумулятора cAccumAlphaBits := 0; // число битовых плоскостей альфа в буфере аккумулятора cDepthBits := 32; // размер буфера глубины (ось z) cStencilBits := 0; // размер буфера трафарета cAuxBuffers := 0; // число вспомогательных буферов iLayerType := PFD_MAIN_PLANE;// тип плоскости bReserved := 0; // число плоскостей переднего и заднего плана dwLayerMask := 0; // dwVisibleMask := 0; // индекс или цвет прозрачности нижней плоскости dwDamageMask := 0; // игнорируется end; nPixelFormat := ChoosePixelFormat (hdc, @pfd); // запрос системе - поддерживается ли выбранный формат пикселей SetPixelFormat (hdc, nPixelFormat, @pfd); // устанавливаем формат пикселей в контексте устройства End; function WindowProc (Window : HWnd; Message, WParam : Word; LParam : LongInt) : LongInt; export; stdcall; Begin WindowProc := 0; case Message of wm_Destroy : begin wglMakeCurrent (0, 0); wglDeleteContext (hrc); ReleaseDC (Window, DC); DeleteDC (DC); PostQuitMessage (0); Exit; end; WM_CREATE: begin Randomize; dc := GetDC (Window); SetDCPixelFormat (dc); hrc := wglCreateContext (dc); wglMakeCurrent (dc, hrc); InitObjects; end; WM_SIZE: begin windW := LOWORD (lParam); windH := HIWORD (lParam); glViewport(0, 0, windW, windH); end; WM_PAINT: begin BeginPaint (Window, ps); DrawScene; EndPaint (Window, ps); end; WM_LBUTTONDOWN: {--- реакция на щелчок мыши ---} begin mouseX := LoWord (lParam); mouseY := HiWord (lParam); hit := DoSelect(mouseX, mouseY); // номер объекта под курсором If hit <> -1 then RecolorTri(hit); // перекрашиваем объект InvalidateRect(Window, nil, False); // обновляем картинку end; end; // case WindowProc := DefWindowProc (Window, Message, WParam, LParam); End; Begin With WindowClass do begin Style := cs_HRedraw or cs_VRedraw; lpfnWndProc := @WindowProc; hCursor := LoadCursor (0, idc_Arrow); lpszClassName := AppName; end; RegisterClass (WindowClass); Window := CreateWindow (AppName, AppName, ws_OverlappedWindow or ws_ClipChildren or ws_Clipsiblings, cw_UseDefault, cw_UseDefault, cw_UseDefault, cw_UseDefault, HWND_DESKTOP, 0, HInstance, nil); ShowWindow (Window, CmdShow); While GetMessage (Message, 0, 0, 0) do begin TranslateMessage (Message); DispatchMessage (Message); end; End. Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. Последний раз редактировалось angvelem, 23.08.2011 в 02:58. |
#5
|
||||
|
||||
![]() После недельной работы в C++ минуты 2 вдуплял в код на Delphi...
Ничего так запутано. Будем разбираться... А обязательно объекты? А если их много? Лучше всё-таки координаты... А, забыл сказать. Все координаты поля на нулевой Z-координате. Оставайтесь хорошими людьми... VK id2634397, ds [at] phoenix [dot] dj |
#6
|
||||
|
||||
![]() Цитата:
К сожалению других подобных примеров не встречал, а мне было без надобности. P.S. А код в принципе простой, это после С++ так кажется. ![]() Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |
#7
|
||||
|
||||
![]() Ну, вертится и двигается оно исключительно по осям X и Y, а Z-координаты всех точек постоянны.
Оставайтесь хорошими людьми... VK id2634397, ds [at] phoenix [dot] dj |
#8
|
||||
|
||||
![]() Не согласен, когда поле вращается его стороны уходят с нулевой позиции.
Je venus de nulle part 55.026263 с.ш., 73.397636 в.д. |
#9
|
||||
|
||||
![]() Код:
glPushMatrix(); glRotatef(rotangle,0,0,1); .... glPopMatrix(); /*Возникла ещё одна проблема. При прорисовке текста резко падает яркость. GL_NORMALIZE включен. При замене WGL_FONT_POLYGONS на WGL_FONT_LINES всё нормально, но шрифты не закрашены, что обидно.*/ Проблема решена, такое происходит только при extrusion !=0. Хотя хрен знает, из-за чего так... ![]() Оставайтесь хорошими людьми... VK id2634397, ds [at] phoenix [dot] dj Последний раз редактировалось PhoeniX, 23.08.2011 в 04:08. |