Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Игры";
Текущий архив: 2008.01.13;
Скачать: [xml.tar.bz2];

Вниз

Полусфера на поверхности сферы (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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.64 MB
Время: 0.011 c
2-1197529644
XerSon
2007-12-13 10:07
2008.01.13
Как перевести сие на код Дельфи т.е написать функцию?


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


4-1182258624
Викетор1985
2007-06-19 17:10
2008.01.13
Как зная имя процесса получить его PID


8-1166004227
Николай_Москва
2006-12-13 13:03
2008.01.13
Разложить отрезок по цветам пикселей


15-1197035508
@!!ex
2007-12-07 16:51
2008.01.13
Потестите прогу.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский