![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Полусфера на поверхности сферы (OpenGL) [Delphi, Windows]
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 изменяет углы поворота и расстояние до экрана одного из объектов. И что получается: если я пытаюсь крутить или двигать первый объект - я вообще не вижу, что с ним происходит, хотя он уже по всем ожиданиям должен из экрана выпрыгнуть. А если второй - да, он крутится, но лежащий под ним первый объект не виден. Почему так?