Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Полусфера на поверхности сферы (OpenGL) [Delphi, Windows]


Страницы:   1 2 3 4 5

Creative ©   (2006-11-28 14:34:00) 

Есть Сфера и есть полусфера. Как сделать следующую вещь:
Нарисовать полусфера таким образом стобы ее можно было возить по сфере , останавливая в произвольной точке?
Была мысль использовать для рисования полусферы gluSphere + glClipPlane, но при тех параметрах, которые принимает в себя glClipPlane, не могу понять, как заставить ее произвольно вертеться.
Подскажите что-нибудь.


ancara   (2006-12-01 16:15:00) [21]


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

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

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

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


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

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


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

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


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

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

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


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


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


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


ancara   (2006-12-01 15:29:00) [26]


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

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


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

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


ancara   (2006-12-01 15:13:00) [28]


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

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

> как дура

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


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

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


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

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


ancara   (2006-12-01 14:59:00) [31]

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


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


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


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

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

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

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

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


ancara   (2006-12-01 14:50:00) [33]


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

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


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


> И это фсио?

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

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

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

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

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


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


> И это фсио?

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

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

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

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

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


ancara   (2006-12-01 14:38:00) [36]


> 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:00:00) [37]


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


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

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


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 13:46:00) [38]

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


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


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


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


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

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

Так?

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


Страницы:   1 2 3 4 5

Наверх

Титульная страница Поиск, карта сайта Написать письмо