Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.01.13;
Скачать: CL | DM;

Вниз

Полусфера на поверхности сферы (OpenGL)   Найти похожие ветки 

 
ancara ©   (2006-11-30 11:59) [40]

Дело в том, что порядок хранения цветов в bmp-файле и RGB-текстуре различается : в bmp BGR, а в текстуре RGB, вот она и меняет местами крайние байты..


 
Creative   (2006-11-30 12:03) [41]

Пример потрясающий. То, что мне нужно!!!


 
ancara ©   (2006-11-30 12:41) [42]

Кушай, не обляпайся :))


 
Creative   (2006-11-30 12:46) [43]

Уляпаюсь по уши и еще попрошу! :-)

Только у меня чуть позже могут вопросы возникнуть, так что заглядывай, если не трудно.


 
Creative   (2006-11-30 15:13) [44]

Скажи, у тебя в DisplayMouseMove X и Y - это координаты курсора?


 
Creative   (2006-11-30 15:19) [45]

И еще вопрос: в твоем последнем примере у тебя в процедуре DisplayMouseMove что происходит при нажатии Alt+левая мышь?


 
ancara ©   (2006-11-30 16:35) [46]


> в DisplayMouseMove X и Y - это координаты курсора?

так точно


> что происходит при нажатии Alt+левая мышь?

не обращай внимания, это лишнее, я не заметил и забыл удалить. В этом примере раньше на плоскость накладывались две текстуры и одну из них можно было перемещать как раз левой кнопкой с зажатым альтом, а tx и ty как раз были координаты смещения текстуры... короче это не нужно :))


 
Creative   (2006-11-30 16:53) [47]

В общем, я перетолмачила твой пример на АПИ и теперь все очень здорово работает. ТЫ мне очень помог, спасибо.
Будем учиться натягивать на шарик текстуру :-)


 
ancara ©   (2006-11-30 19:18) [48]


> спасибо

На здоровье! :))

> Будем учиться натягивать на шарик текстуру :-)

Нет ничего проще: в BuildList сферы, после вычислений координат вершин,
ну там где glVertex3fv(@Vec2) и glVertex3fv(@Vec1) вставь такой код:

glNormal3fv(@vNorm2);
glTexCoord2f(azi/pi/2, zenNext/pi+0.5);
glVertex3fv(@Vec2);

glNormal3fv(@vNorm1);
glTexCoord2f(azi/pi/2, zen/pi+0.5);
glVertex3fv(@Vec1);

и все, текстурные координаты для вершин заданы, осталось "применить" текстуру к объекту, для этого в рендере, перед вызовом списка glCallList
нужно "забиндить" соответствующую текстуру:
glBindTexture(GL_TEXTURE_2D, Tex_1);
Tex_1 - это идентификатор текстуры, там в процедуре InitGL загружается картинка 1.jpg в качестве текстуры с номером Text_1:
LoadTexture("1.jpg", Tex_1);

Итого, еще раз:
 - в процессе инициализации создается текстура с номером Tex_1 (эта переменная примет некот. значение, мы его у OpenGL попросим);
 - содержимое этой текстуры загружается из файла 1.jpg;
 - в процессе построения диспл. списка сферы для каждой ее вершины указываются текстурные координаты;
 - перед рендерингом сферы, "биндится" (становится текущей) соответствующая текстура;
 - в результате рендеринга получаем сферу с натянутой текстурой;

Вопросы? :)


 
Creative   (2006-12-01 10:38) [49]

Объяснение отличное, пошла делать. Только переведу LoadTexture на понятный язык. :-)

Скажи, а ечли я хочу сделать например глобус - мне нужна карта мира, вырезанная в виду "апельсиновой корки" или как лучше? (я и сама конечно попробую, просто вдруг у тебя опыт есть)


 
ancara ©   (2006-12-01 11:24) [50]

нужна карта мира в виде равноугольной проекции Меркатора, т.е. той, на которой и параллели и меридианы параллельны, а полюсами являются верхняя и нижняя строны прямоугольника. Вобщем, вот такая вот: http://img135.imageshack.us/img135/6897/earthdaynq0.jpg
она там правда не очень высокого разрешения, 1024х1024.


 
Creative   (2006-12-01 11:35) [51]

Спасибо, мне за глаза хватит.
Кстати, если я внутри этой ветки один примитивный вопрос по VCL задам  - не страшно?


 
ancara ©   (2006-12-01 11:49) [52]


> не страшно?

:)) Это очень страшно! Через пол-часа придут люди в погонах и предъявят обвинение в умышленном оффтопе в игровой ветке! Не делай этого! Только не это!


 
Creative   (2006-12-01 11:51) [53]

Ну смотри, сам напросился. :-)
У меня на форме лежат несколько компонентов. Я делаю обработчик onKeyDown (или onKeyPress, как получится) для клавиш vk_Up/DOWN/LEFT/RIGHT. Но при запуске оказывается, что этот обработчик к жизни не вызывается, а при нажатии на стрелки просто по всем компонентам форму бегает фокус. Как правильно с этим бороться? Я точно помню, что как-то можно, но напрочь забыла - как. :-(


 
ancara ©   (2006-12-01 12:07) [54]

Понятно, можно поступить так:
на форму положи компонент TApplicationEvents (вкладка Additional),
в ее обработчике события OnMessage помести такой код:
 if msg.message=WM_KEYDOWN then
 begin
   if msg.wParam=VK_DOWN then //обработать нажатие клавиши "вниз"
   if msg.wParam=VK_UP then //обработать нажатие клавиши "вверх"
//если не хочешь чтоб фокус прыгал по компонентам
//раскоментируй след. строчку
//    handled:=true;
 end;


 
Creative   (2006-12-01 12:23) [55]

Угу, попробую.

У меня еще вопросы по поводу шариков.
У меня есть два разных объекта класса TSphere (написанного по твоему примеру). Соответственно у класса есть метод отрисовки TSphere.Render, выглядящий примерно так:


 glPushMatrix;
 glTranslatef
 glRotatef(Fbeta, 1,0,0);
 glRotatef(Falpha, 0,1,0);

 glCallList(ListID);  // рисование собственно сферы

 glPopMatrix;


В обработчике onMouseMove вот такой код:

S1.FAlpha:=Round(S1.FAlpha+(lpPoint.X-pX)*0.5);
S1.FBeta:=Round(S1.FBeta+(lpPoint.Y-pY)*0.5);

S1.Render;
S2.Render;


Я сильно надеялась, что этот код заставляет повернуться только одну сферу, а вторую остаться на месте (ты мне вроде бы так объяснял как крутить разные объекты?). Но при запуске картинка вообще не шевелится. Делаешь углы глобальными переменными - опять все нормально, но по прежнему крутится вся сцена целиком. Где я наглючила? Разве не должны сферы двигаться раздельно? Я где-то неправильно поняла?


 
Creative   (2006-12-01 12:33) [56]

Стрелки заработали. Ну, ты понял, что я хочу сказать :-)


 
ancara ©   (2006-12-01 12:42) [57]

lpPoint - а что это?

а вот насчет кода в OnMouseMove, я что-то затупил, не пойму что там должно получится...
Просто при изменениях свойств одного из объектов сцены нужно вызывать не его рендерер, а рендерер всей сцены, потому что в OpenGL невозможно перерисовать один объект а остальные нет,  если уж перерисовывать кадр так всю сцену придется рисовать.
  Т.е. в OnMouseMove надо вызвать глобальный рендерер (RenderScene или как там?), а в нем уже:
- подготовка всяких параметров (цвет фона там, cull-инг и пр.)
- настройка света;
- установка положения камеры;
- прочие приблуды;
- перебор всех объектов, подлежащих рендерингу и вызов у них метода Render;
- и наконец SwapBuffers;


 
Creative   (2006-12-01 12:59) [58]


> lpPoint - а что это?


Это переменная типа TPoint, куда складываются координаты курсора. Я пользуюсь GetCursorPos(lpPoint:TPoint).

в OnMouseMove надо вызвать глобальный рендерер (RenderScene или как там?), а в нем уже

а его собственно надо заключать в
PushMatrix;
PopMatrix;
?

cull-инг  - а это что?


 
ancara ©   (2006-12-01 13:31) [59]


> Я пользуюсь GetCursorPos(lpPoint:TPoint).

Дык в процедуру OnMouseMove и так передаются координаты курсора, они хранятся в переменных X и Y :) Ну результат в принципе такой же будет...


> cull-инг  - а это что?

Face culling - это дословно "отбраковка граней", каждый полигон в OpenGL имеет лицевую и обратную стороны, для каждой из них модно установить отдельные свойства  (материал, например). Включив куллинг (glEnable(GL_CULL_FACE)) и указав какие именно грани не рисовать (например обратные: glCullFace(GL_BACK)) мы позволим OpenGL расчитывать только лицевые грани, сэкономив таким образом процессорное время. Это может быть полезно в случае с какими-то замкнутыми фигурами, кубиком напрмер, если мы будем смотреть на него только снаружи и он непрозрачный мы никогда не увидим его обратных граней, т.к. они будут обращены внутрь (об этом надо позаботится отдельно), следовательно их незачем рисовать. Ну куллинг я как пример привел, его не обязательно использовать :)..


> а его собственно надо заключать в
> PushMatrix;
> PopMatrix;

Как это сделано у меня:
в глобальном рендере каждый кадр:

- устанавливаю единичную матрицу:glLoadIdentity;
- поворачиваю и смещаю сист.коорд. согласно положению камеры:
    glRotatef(FCamera.Beta, 1,0,0);
    glRotatef(-FCamera.Alpha, 0,1,0);
    glTranslatef(-FCamera.Position.X,  -FCamera.Position.Y,  -FCamera.Position.Z);

- всякая приблуда: SetupLights; //солнышко светит
- делаю рендеринг всех объектов:   RenderObjects ... (ну это очень упрощенно :)) )
  причем каждый объект перед рендерингом себя:
   - сохраняет матрицу: glPushMatrix;
   - смещает и крутит сист. координат, согласно своей позиции и ориентации;
   - назначает нужный ему материал, ставит куллинг, если надо, включает нужную ему текстуру и т.д., вобщем они у меня все взрослые и самостоятельные...
  - рендерит сам себя: glCallList;
  - возвращает все как было, чтоб следующий не обиделся: glPopMatrix;
  - ну и после того как нарисовали все что хотели : SwapBuffers


 
ancara ©   (2006-12-01 13:33) [60]


> для каждой из них модно установить

для каждой из них можно установить
гыгы, гламурный куллинг :)


 
Creative   (2006-12-01 13:41) [61]

Где-то я глобально запуталась. Вот смотри - всю систему координат мне крутить не надо. Рендеринг объекта я привела в [55], и там по-моему все, как ты и сказал. В глобальном рендере только и остается, что :
 
 glLoadidentity;
 S1.Render;
 S2.Render;

Так?

обработчик onMouseMove изменяет углы поворота и расстояние до экрана одного из объектов. И что получается: если я пытаюсь крутить или двигать первый объект - я вообще не вижу, что с ним происходит, хотя он уже по всем ожиданиям должен из экрана выпрыгнуть. А если второй - да, он крутится, но лежащий под ним первый объект не виден. Почему так?


 
Creative   (2006-12-01 13:42) [62]


> для каждой из них можно установитьгыгы, гламурный куллинг
> :)


да, меня сильно озадачило, думаю...ишь ты, у них там еще мода бывает :-))))


 
ancara ©   (2006-12-01 13:46) [63]

Т.е. первый крутится а второй нет?
Ну тогда давай код рендера и OnMouseMove, будем думать :))


 
Creative   (2006-12-01 14:00) [64]


> Т.е. первый крутится а второй нет?


второй (верхний) крутится, а первого просто не видно, что он там делает.

Рендер объекта:


procedure TSphere.Render;
var
diffuse: array [0..3]of GLfloat;
const
 light_pos: array [0..3]of GLfloat = (5.0, 5.0, 5.0, 0.0);
begin
 diffuse[0] :=FColor[0];
 diffuse[1] :=FColor[1];
 diffuse[2] :=FColor[2];
 diffuse[3] :=1;
 glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

 glPushMatrix;
 glTranslatef(0,0,-FDistance);
 glRotatef(Fbeta, 1,0,0);
 glRotatef(Falpha, 0,1,0);

 glLightfv(GL_LIGHT0, GL_POSITION, @light_pos);
 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT,   @diffuse);
 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,   @diffuse);

 glCallList(ListID);

 glPopMatrix;

end;



Рендер сцены:


procedure DrawScene;
begin
 glLoadidentity;
 S1.Render;
 S2.Render;
end;


onMouseMove:


begin
GetCursorPos(lpPoint);
  if mouse[0]  then      
 begin
    S2.FAlpha:=Round(S2.FAlpha+(lpPoint.X-pX)*0.5);
    S2.FBeta:=Round(S2.FBeta+(lpPoint.Y-pY)*0.5);
 end;

  if mouse[1]  then
 begin
    S2.FDistance:=S2.FDistance+(pX-lpPoint.X)*S2.FDistance*0.01;
 end;
 pX:=lpPoint.X;
 pY:=lpPoint.Y;

 DrawScene;

end;


{if mouse[0/1] - это переменная, указывающая на то, какая мышь зажата - левая или правая, не обращай внимания, я этот обработчик сама писала, как умела}

и еще такой вопрос6 я все-таки переделываю твой пример и я заметила такую вещь: если Distance поставить в glTranslatef не вместо оси Z, а вместо X, то объект доедет до середины окна и замрет там, больше его не сдвинуть. Почему так?


 
ancara ©   (2006-12-01 14:38) [65]


> procedure DrawScene;
> begin
>  glLoadidentity;
>  S1.Render;
>  S2.Render;
> end;

И это фсио? А камеру установить? Она по идее будет находится в точке (0, 0, 0) и смотреть вдоль оси Z в положительном направлении, и S1 будет рисоваться там же... получается так.. может она за камерой просто? А вот S2 можно двигать мышкой по оси Z...
попробуй так:

procedure DrawScene;
begin
glLoadidentity;
glTranslatef(0,0,-5); //это мы камеру сдвигаем "назад" на 5
S1.Render;
S2.Render;
end;


> доедет до середины окна и замрет там, больше его не сдвинуть.
>  Почему так?

Потому что у меня FDistance определял расстояние от камеры до ее "цели", точки на кот. она смотрит, оно не должно было быть отрицательным.
И поэтому в моем OnMouseMove было
Distance:=Distance+(pX-X)*Distance*0.01;
т.е. инкремент дистанции уменьшался вместе с самой дистанцией, т.е. чем ближе к нулю, тем медленее она к нему стремится, но видимо из-за недостаточной точности она все же обращалась в ноль и поэтому не отъезжала обратно.


 
Creative   (2006-12-01 14:43) [66]


> И это фсио?

не сочти за труд - говори по-русски :-)

А камеру установить? Она по идее будет находится в точке (0, 0, 0) и смотреть вдоль оси Z в положительном направлении, и S1 будет рисоваться там же... получается так.. может она за камерой просто?

Да нет же. Если заремить отрисовку S2 - то S1 преспокойно будет виден, благо он рисуется на тех же координатах. Я имею в виду, что если я поверну S2 или сдвину его назад - я не увижу S1, лежащий за ним, как будто его и нет вовсе.

glTranslatef(0,0,-5); //это мы камеру сдвигаем "назад" на 5

да от же самое, только издали :-(


 
Creative   (2006-12-01 14:43) [67]


> И это фсио?

не сочти за труд - говори по-русски :-)

А камеру установить? Она по идее будет находится в точке (0, 0, 0) и смотреть вдоль оси Z в положительном направлении, и S1 будет рисоваться там же... получается так.. может она за камерой просто?

Да нет же. Если заремить отрисовку S2 - то S1 преспокойно будет виден, благо он рисуется на тех же координатах. Я имею в виду, что если я поверну S2 или сдвину его назад - я не увижу S1, лежащий за ним, как будто его и нет вовсе.

glTranslatef(0,0,-5); //это мы камеру сдвигаем "назад" на 5

да от же самое, только издали :-(


 
ancara ©   (2006-12-01 14:50) [68]


> сдвину его назад - я не увижу S1, лежащий за ним, как будто
> его и нет вовсе.

А куда ж он девается-то? Может они вместе уезжают?
А попробуй заремить S2 и кнопки понажимать - S1 двигается? Хотя с чего ему двигаться...
А FDistance, FAlpha и FBeta это точно поля класса, может глоб. переменные?


 
Creative   (2006-12-01 14:54) [69]


> А куда ж он девается-то? Может они вместе уезжают?


С какой стати ему уезжать? Его то коодинаты не изменяются.

А попробуй заремить S2 и кнопки понажимать - S1 двигается? Хотя с чего ему двигаться...

Совершенно верно - никуда он не девается.

А FDistance, FAlpha и FBeta это точно поля класса, может глоб. переменные?

Абсолютно точно.


 
ancara ©   (2006-12-01 14:59) [70]

ну не знаю тогда... попробуй дебаггером посмотреть FDistances обеих сфер когда ты их двигаешь...


 
Creative   (2006-12-01 15:00) [71]

До меня кажется начало доходить!!!! Опытным путем я выяснила, что всему виной была строчка
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
стоящая в рендере объекта. По моему она просто аккуратно вытирала первый объект и спокойно на чистом листе рисовала второй.


 
Creative   (2006-12-01 15:01) [72]

просто в твоем примере она стояла в RenderScene. ну я и взяла ее :-)
как дура...


 
ancara ©   (2006-12-01 15:13) [73]


> аккуратно вытирала первый объект

ну это конечно зря :)) ее ж надо было перед началом формирования кадра вызвать один раз, и все :))

> как дура

нуну, не надо так себя :)) самокритика хороша, когда в меру :))


 
Creative   (2006-12-01 15:23) [74]

Как здорово все получилось!
Ну, до следующего косяка :-)


 
ancara ©   (2006-12-01 15:29) [75]


> до следующего косяка :-)

<затягиваясь> Угу, позовешь если что...


 
Creative   (2006-12-01 15:31) [76]


> <затягиваясь>


Я не эту гадость имела в виду :-(
Но позвать - позову


 
Creative   (2006-12-01 15:49) [77]

Еще кстати вопрос:
1. я использую дисплейный список.
2. внутри списка я использую поле объекта F.
3. я создаю два объекта с разными значениями поля - F1 и F2.
4. в конструкторе у меня стоит BuildList (F: real - переменная, которая будет принимать в себя значение поля создаваемого объекта)
5. в рендере дисплейный список вызывается glCallList(ListID).

Проблема вот какая: glCallList(ListID) - это ведь уже стандартная процедура, к ней не убавишь, не прибавишь, и получается, что она вызывает список в том виде, в котором он был заполнен для _последнего объекта_.
Я правильно поняла, что именно поэтому все объекты рисуются одинаково (с точки зрения тех переменных, которые находятся внутри BuildList)?


 
Creative   (2006-12-01 15:50) [78]

Это же глупо - создавать два идентичных дисплейных списка просто потому, что они различаются на одну цифру?


 
Creative   (2006-12-01 15:52) [79]

И еще: мне только что пришло в голову: а почему не написать просто процедуру, например DrawSphere и не вызывать в рендере объекта именно ее, а не Список? В чем принципиальное отличие Списка от процедуры?


 
ancara ©   (2006-12-01 16:15) [80]


> Это же глупо - создавать два идентичных дисплейных списка
> просто потому, что они различаются на одну цифру?

Нет, гораздо глупее пересобирать один и тот же список для разных объектов :)) Для каждого объекта нужно выделить отдельный персональный список :))

> В чем принципиальное отличие Списка от процедуры?

ну если рендер сделать просто в процедуре то, очевидно, там будут содержаться такие команды:
 glVertex(x,y,z);
 glNormal(x,y,z);
 и т.д.,
т.е. мы будем по-очереди, каждую вершину с ее координатами, нормалями, текстрными координатами и пр. загонять в видеокарту.
А она, в свою очередь, при получении очередного полигона, почти мгновенно его расчитает (нарисует) и будет ждать, пока мы подготовим следующий и пропихнем его по медленной AGP (PCI-E) шине.
 И так каждый кадр, даже если ничего не поменялось, мы опять будем гнать те же данные снова и снова, в итоге FPS -> к нулю..
 Когда мы используем список, а точнее его собираем (glNewList и так далее..)
мы проделываем те же операции, т.е. гоним данные по шине в видеокарту, но мы делаем это только один раз (в идеальном случае), а в момент рендеринга мы просто вызываем соответствующий дисплейный список (glCallList), т.е. мы всего лишь просим видеокарту отрисовать некий объект (совокупность полигонов) который уже находится в ней, и это происходит значительно быстрее.



Страницы: 1 2 3 вся ветка

Текущий архив: 2008.01.13;
Скачать: CL | DM;

Наверх




Память: 0.66 MB
Время: 0.02 c
2-1197638738
сосед
2007-12-14 16:25
2008.01.13
Разложить стиль окна


3-1188920505
spogi
2007-09-04 19:41
2008.01.13
TTable->Paradox->QRReport


2-1197534498
phantom
2007-12-13 11:28
2008.01.13
Многопоточность в CGI


2-1197394841
Виталий
2007-12-11 20:40
2008.01.13
Работа с Ole


8-1161287385
Skopas
2006-10-19 23:49
2008.01.13
Поиск в BMP