Сообщения на форуме пользователя Andrey (216 стр.)
Рендер через Octree-дерева:FPS низок по сравнению с прямым рендером.Прошу помощи. | 26 мая 2005 | 9:58 | #7 |
---|
resurected_timofei
>Если из 5000 - не знаю =)
сейчас продебагил вот 5282 полигона для сцены из скриншота
>То же самое тебе скажут и дядки-профи ГеймДева. Всем так говорят.
>Да так и есть на самом деле ;) Так что не волнуйся! Когда сцена будет
>огромной ты это почувствуешь!
Спасибо ты меня успокоил!!! а то я уже вообще в панике я даже про это не
задумался теперь чуть чуть врубаюсь...
>PS: Ты мне скажи, а что ты делаешь с дробными тругольниками между
>границ узлов? Мне самому интересно, что люди применяют ;)
Я просто пробовал вести учет индексов тех полигонов которые уже попали в узел.
т.е. просто перед добавление смотрел
находится ли он в узле или нет... но там что-то не получилось.Мне кажется для
больших сцен процент дублей не окажет большого влияния на производительность
Sandman
>Ничего удивительного, что тормозит. Ты ведь по одному треугольнику рисуешь, да ещё и каждый треугольник на >попадание в фрустум проверяешь....
Пробовал отключать проверку в frustum эффект такой-же...
скажи а как это влияет ведь и там и там по 1 треугольнику, что скажешь?
Правка: 26 мая 2005 10:00
Рендер через Octree-дерева:FPS низок по сравнению с прямым рендером.Прошу помощи. | 26 мая 2005 | 9:30 | #4 |
---|
//установить максимальную точку boundingBox.SetMaxPoint(Max); //установить минимальную точку boundingBox.SetMinPoint(Min); //получить дочерний узел childNode = node -> GetChildNode(i); //цикл по полигонам for (j = 0; j < num; j++) { //Вершина 1 vert0 = model -> GetVertice(j).vert[0]; //Вершина 2 vert1 = model -> GetVertice(j).vert[1]; //Вершина 3 vert2 = model -> GetVertice(j).vert[2]; //проверить нахождение 3 точек полигона в ограничивающем теле if (boundingBox.contains(vert0, vert1, vert2)) { //если не был создан if (!childNode) { childNode = new OctreeNode; childNode -> GetBoundingBox().SetMaxPoint(Max); childNode -> GetBoundingBox().SetMinPoint(Min); } //добавить индекс в узел childNode -> AddIndexPoligon(j); //Если получилось большее число полигонов if (childNode -> GetNumberPoligons() > OctreeNode::NUMBERPOLIGONS) { break;//выйти из цикла } } } //установить указатель на узел node -> SetChild(childNode, i); //если существует узел if (childNode) //если число полигонов превышает if (childNode -> GetNumberPoligons() > OctreeNode::NUMBERPOLIGONS) { childNode -> ClearPoligons(); //Обработка дочернего узла узла ProcessingNode(model, childNode, Depth + 1); } else childNode -> SetLeaf();//узел является листом } }
//отображение дерева void Octree::Draw(Mesh *mesh, OctreeNode *&node, const Frustum& frustum) { if (!node) return; //отображение Bounding Box'а для отладки if (DrawBox) node -> DrawBoundingBox(); //Если нет потомков //отобразить узел if (node -> IsLeaf()) { node -> Draw(model, frustum); ... return; } int i; //дочерний узел OctreeNode *childNode; //цикл по дочерним узлам for (i = 0; i < 8; i++) { //получить дочерний узел childNode = node -> GetChildNode(i); //если узел существует if (childNode) //проверка нахождения в пирамиде видимости if (frustum.BoundingBoxInFrustum(childNode -> GetBoundingBox())) //рекурсивное отображение остальных узлов Draw(mesh, childNode, frustum); } } //отображение узла void OctreeNode::Draw(Mesh *mesh, const Frustum& frustum) { if (!mesh) return; Vector3D Normal; int i; Vector4D v; int k = 0; int index = 0; int Id; //число полигонов int Number = int(indexs.size()); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); Vector3D v0; Vector3D v1; Vector3D v2; Vector2D tvert; Mesh::Vertice *vertice; glEnable(GL_TEXTURE_2D); //обнулить число полигонов nPoligons = 0; //проход по граням for (i = 0; i < Number; i ++) { //получить индекс index = indexs[i]; //получить index грань vertice = &mesh -> GetVertice(index); //если есть материалы if (mesh -> MaterialsIsOk()) { //получить индекс материала Id = vertice -> MatId; //если индекс другой if (k != Id) { //запомнить его k = Id; //отражение float shininess; //индекс текстуры unsigned int TextId = mesh -> GetTextureDiffuseId(Id); glBindTexture(GL_TEXTURE_2D, TextId); //получить спекулярный цвет материала v = mesh -> GetSpecular(Id); //Спекулярная состовляющая материала glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &v[0]); //получить диффузионный цвет материала v = mesh -> GetDiffuse(Id); //Диффузионная состовляющая материала glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, &v[0]); //Получить Фоновый цвет для материала v = mesh -> GetAmbient(Id); //модель освещения glLightModelfv(GL_LIGHT_MODEL_AMBIENT, &v[0]); //Фоновая состовляющая материала glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, &v[0]); //получить отражение shininess = mesh -> GetShininess(Id); //Отраженная состовляющая материала glMaterialfv(GL_FRONT, GL_SHININESS, &shininess); } } //получить 1 вершину v0 = vertice -> vertex[0].vert; //получить 2 вершину v1 = vertice -> vertex[1].vert; //получить 3 вершину v2 = vertice -> vertex[2].vert; ... //если треугольник в пирамиде видимости if (frustum.TriangleInFrustum(v0, v1, v2)) { //установить смешанный массив glInterleavedArrays(GL_T2F_N3F_V3F, 0, vertice -> vertex); //отобразить 3 эелемента glDrawArrays(GL_TRIANGLES, 0, 3); } ... } glDisable(GL_TEXTURE_2D); }
Скажите что тут может быть не так? может нужно пересмотреть или где-то есть ошибка но я не мог ее найти?
ведь строиться дерево правильно. Очень прошу помощи в плане оптимизации я стою на месте...
Буду рад любому совету(дельному)
Спасибо всем заранее.
С уважением Андрей.
Правка: 26 мая 2005 9:33
Рендер через Octree-дерева:FPS низок по сравнению с прямым рендером.Прошу помощи. | 26 мая 2005 | 9:30 | #3 |
---|
//Обработка узла void Octree::ProcessingNode(Mesh* model, OctreeNode *&node, int Depth) { //выход при нулевом узле if (!node) return; //проверка глубины разбиения if (Depth > DepthOctree) return; //если узел является листом if (node -> IsLeaf()) return; //Вершина 1 Vector3D vert0; //Вершина 1 Vector3D vert1; //Вершина 2 Vector3D vert2; int i = 0; int j = 0; int l = 0; //указатель на ограничивающее тело AABB *BoundingBox = &node -> GetBoundingBox(); //число полигонов int num = model -> GetNumFaces(); //индекс занят индекса bool occuped = false; //цикл по полигонам for (j = 0; j < num; j++) { //Вершина 1 vert0 = model -> GetVertice(j).vertex[0].vert; //Вершина 2 vert1 = model -> GetVertice(j).vertex[1].vert; //Вершина 3 vert2 = model -> GetVertice(j).vertex[2].vert; //проверить нахождение 3 точек полигона в ограничивающем теле if (BoundingBox -> contains(vert0, vert1, vert2)) { //добавить индекс в узел node -> AddIndexPoligon(j); //Если получилось большее число полигонов if (node -> GetNumberPoligons() > OctreeNode::NUMBERPOLIGONS) { //очистить //node -> ClearPoligons(); break;//выйти из цикла } } } //если число полигонов меньше чем нужно то это является листом if (node -> GetNumberPoligons() <= OctreeNode::NUMBERPOLIGONS) { //установить флаг листа node -> SetLeaf(); return; } else//очистить полигоны node -> ClearPoligons(); //обработка //максимальная точка Vector3D max; //минмимальная точка Vector3D min; //разница между координатами float dz = 0; //середина по координате x float dcenterx = 0; //середина по координате y float dcentery = 0; //середина по координате z float dcenterz = 0; //для прибавления float k = 0; //временный вектор Vector3D Min; //временный вектор Vector3D Max; //дочерний узел OctreeNode *childNode = NULL; //получить максимальную точка max = node -> GetBoundingBox().GetMaxPoint(); //получить минимальную точку min = node -> GetBoundingBox().GetMinPoint(); //4 это - 2 по 4 всего 8 дочерних dz = (max.z - min.z) / 4; //середина по координате x dcenterx = (max.x - min.x) / 2; //середина по координате y dcentery = (max.y - min.y) / 2; //середина по координате z dcenterz = (max.z - min.z) / 2; //ограничивающий бокс узла AABB boundingBox; //цикл по 8 дочерним узлам for (i = 0; i < 8; i++) { //сохранить значение Min = min; //сохранить значение Max = max; //в зависимости от номера switch (i) { //расчет max и min точек BoundingBox'а для 0 дочернего бокса case 0: { Max.x -= dcenterx; Max.y -= dcentery; Max.z -= dcenterz; } break; //расчет max и min точек BoundingBox'а для 1 дочернего бокса case 1: { Min.y += dcentery; Max.z -= dcenterz; Max.x -= dcenterx; } break; //расчет max и min точек BoundingBox'а для 2 дочернего бокса case 2: { Min.z += dcenterz; Max.y -= dcentery; Max.x -= dcenterx; } break; //расчет max и min точек BoundingBox'а для 3 дочернего бокса case 3: { Min.z += dcenterz; Min.y += dcentery; Max.x -= dcenterx; } break; //расчет max и min точек BoundingBox'а для 4 дочернего бокса case 4: { Min.x += dcenterx; Max.z -= dcenterz; Max.y -= dcentery; } break; //расчет max и min точек BoundingBox'а для 5 дочернего бокса case 5: { Min.x += dcenterx; Min.y += dcentery; Max.z -= dcenterz; } break; //расчет max и min точек BoundingBox'а для 6 дочернего бокса case 6: { Min.x += dcenterx; Min.z += dcenterz; Max.y -= dcentery; } break; //расчет max и min точек BoundingBox'а для 7 дочернего бокса case 7: { Min.x += dcenterx; Min.z += dcenterz; Min.y += dcentery; } }
Правка: 26 мая 2005 9:41
Рендер через Octree-дерева:FPS низок по сравнению с прямым рендером.Прошу помощи. | 26 мая 2005 | 9:27 | #2 |
---|
//построение octree void Octree::BuildOctree(Mesh* model) { if (!model) return; if (root == NULL) { root = new OctreeNode; int i; //число полигонов int num = int(model -> GetNumFaces()); //получить Bounding Box узла AABB* bbox = &root -> GetBoundingBox(); //грань Mesh::Vertice* vertice = &model -> GetVertice(0); //инициализация минимальной точки bbox -> SetMaxPoint(vertice -> vert[0]); //инициализация максимальной точки точки bbox -> SetMinPoint(vertice -> vert[1]); //вершина Vector3D v; //цикл по граням for (i = 0; i < num; i++) { //получить грань vertice = &model -> GetVertice(i); //получить 1 вершину v = vertice -> vert[0]; //добавить 1 вершину bbox -> AddVertex(v); //получить 2 вершину v = vertice -> vert[1]; //добавить 2 вершину bbox -> AddVertex(v); //получить 3 вершину v = vertice -> vert[2]; //добавить 3 вершину bbox -> AddVertex(v); } } //начинаем с корневого узла ProcessingNode(model, root, 0); ok = true; MessageBox(NULL, "Octree build complete", "Info", MB_OK); }
Правка: 26 мая 2005 9:40
Рендер через Octree-дерева:FPS низок по сравнению с прямым рендером.Прошу помощи. | 26 мая 2005 | 9:26 | #1 |
---|
//Класс AABB (Axis-Aligned Bounding Box) class AABB { private: ... //Максимальная точка Vector3D maxPoint; //Минимальная точка Vector3D minPoint; public: //добавление вершины void AddVertex(const Vector3D& vert) { //проверка границ if (minPoint.x > vert.x) minPoint.x = vert.x; if (minPoint.y > vert.y) minPoint.y = vert.y; if (minPoint.z > vert.z) minPoint.z = vert.z; if (maxPoint.x < vert.x) maxPoint.x = vert.x; if (maxPoint.y < vert.y) maxPoint.y = vert.y; if (maxPoint.z < vert.z) maxPoint.z = vert.z; } ... //Установка новой минимальной точки void SetMinPoint(const Vector3D& newPoint) { minPoint = newPoint; } //Установка новой максимальной точки void SetMaxPoint(const Vector3D& newPoint) { maxPoint = newPoint; } ... //возврат минимальной точки inline const Vector3D& GetMinPoint() const { return minPoint; } //возврат максимальной точки inline const Vector3D& GetMaxPoint() { return maxPoint; } //содерхание точки в Bounding Box'е inline bool contains(const Vector3D& point) const { //проверить нахождение точки в границах return ((point.x >= minPoint.x && point.x <= maxPoint.x) && (point.y >= minPoint.y && point.y <= maxPoint.y) && (point.z >= minPoint.z && point.z <= maxPoint.z)); } //проверить содержание полигона в AABB inline bool contains(const Vector3D& v0, const Vector3D& v1, const Vector3D& v2) const { return (contains(v0) || contains(v1) || contains(v2)); } inline AABB(const AABB& aabb) : maxPoint(aabb.maxPoint), minPoint(aabb.minPoint) {} inline AABB(const Vector3D& MaxP, const Vector3D& MinP) : maxPoint(MaxP), minPoint(MinP) {} ... AABB(){}; ~AABB(){}; }; #endif
//класс Octree-дерева class Octree { private: ... //занятые индексы vector<int> indexsOccuped; //Глубина разбиения int DepthOctree; //ссылка на mesh Mesh *mesh; //узел дерева OctreeNode *root; //дерево построено bool ok; ... //Обработка узла void ProcessingNode(Mesh* model, OctreeNode *&node, int Depth); ... //отображение дерева void Draw(Mesh *mesh, OctreeNode *&node, const Frustum& frustum); public: ... //Установить глубину разбиения void SetDepth(int depth) { DepthOctree = depth; } //установка ссылки на Mesh void SetMesh(Mesh *Model) { mesh = Model; } //отображения дерева void DrawOctree(Camera& camera) { if (ok) Draw(mesh, root, camera.GetFrustum()); } ... //построение octree void BuildOctree(Mesh* model); Octree() : root(NULL), mesh(NULL), DepthOctree(0), ok(false) {}; ~Octree() { delete root; root = NULL; }; }; #endif
Правка: 26 мая 2005 9:38
Рендер через Octree-дерева:FPS низок по сравнению с прямым рендером.Прошу помощи. | 26 мая 2005 | 9:25 | #0 |
---|
построил Octree-дерево. при отрисовки скорость рендера с помощью Octree меньше чем при обычном рендере.
Строил дерево как обычно в итоге получалось что в листьях имеются индексы по которым можно брать из массива полигоны
сцены.При рендере через Octree-дерево FPS падает... точно сказать не могу во сколько но не в 2 раза... приблизительно 50%разница в FPS. Для рендера использую OpenGL, вертикальная синхронизация отключена.Я думаю что бы было понятно приведу код.
Начну с Mesh'а который используется для рендера сцены:(Mesh пока может не оптимизирован)
//Класс мешь class Mesh { public: //класс материала class Material { private: //Амбиент свойство Vector4D Ambient; //Diffuse свойство Vector4D Diffuse; //Specular свойство Vector4D Specular; //текстура Diffuse unsigned int TextureDiffuseId; //текстура Bump unsigned int TextureBumpId; //сомоосвещение float shininess; public: //возврат самоосвешение inline float GetShininess() const { return shininess; } ... //возврат specular свойства inline const Vector4D& GetDiffuse() const { return Diffuse; } ... //возврат specular свойства inline const Vector4D& GetSpecular() const { return Specular; } //возврат ambient свойства inline const Vector4D& GetAmbient() const { return Ambient; } ... //возврат индекса Diffuse текстуры inline unsigned int GetTextureDiffuseId() const { return TextureDiffuseId; } //возврат Bump текстуры inline unsigned int GetTextureBumpId() const { return TextureBumpId; } ... }; //вершина struct Vertex { //Текстурные координаты Vector2D tvert; //Нормали Vector3D normal; //координаты вершины Vector3D vert; }; //Грань class Vertice { public: //индекс материала char MatId; //3 Вершины полигона Vertex vertex[3]; }; private: ... //материалы vector<Material> materials; //Массив граней vector<Vertice> vertices; public: //присутвие материалов inline bool MaterialsIsOk() const { return !materials.empty(); } //возвратить отражение inline float GetShininess(int MatId) { return materials[MatId].GetShininess(); } //индекс диффузионной текстуры inline unsigned int GetTextureDiffuseId(int MatId) const { return materials[MatId].GetTextureDiffuseId(); } //индекс bump текстуры inline unsigned int GetTextureBumpId(int MatId) const { return materials[MatId].GetTextureBumpId(); } inline const Vector4D& GetAmbient(int MatId) const { return materials[MatId].GetAmbient(); } inline const Vector4D& GetDiffuse(int MatId) const { return materials[MatId].GetDiffuse(); } inline const Vector4D& GetSpecular(int MatId) const { return materials[MatId].GetSpecular(); } ... inline int GetNumFaces() const //число граней { return vertices.size(); } ... //возврат грани inline Vertice& GetVertice(int index) { return vertices[index]; } Mesh() {}; ~Mesh(){}; }; #endif
//класс узла octree class OctreeNode { private: ... //флаг показывающий что узел является листом дерева bool isLeaf; //ограничивающее тело AABB Box; //индексы vector<int> indexs; //дети узла OctreeNode *child[8]; public: enum { NUMBERPOLIGONS = 100//максимальное число полигонов в узле }; ... //вернуть массив индексов inline const vector<int>& GetIndexs() const { return indexs; } //учтановка листа void SetLeaf() { isLeaf = true; } //Возврат флага узла inline bool IsLeaf() const { return isLeaf; } //очистить void ClearPoligons() { indexs.clear(); } //возврат числа полигонов inline int GetNumberPoligons() const { return int(indexs.size()); } ... //отображение узла void Draw(Mesh *model, const Frustum& frustum); //добавить индекс void AddIndexPoligon(const int index) { indexs.push_back(index); } //возвратить указатель на i-сына inline OctreeNode* GetChildNode(int i) { return child[i]; } //присвоить новый узел void SetChild(OctreeNode* node, int index) { child[index] = node; } //возвратить ограничивающее тело inline AABB& GetBoundingBox() { return Box; } OctreeNode() : isLeaf(false) { //обнуление указателей memset(child, NULL, sizeof(child)); }; ~OctreeNode() { //рекурсивное уаление for (int i = 0; i < 8; i++) { if (child[i]) delete child[i]; child[i] = NULL; } }; };
Правка: 26 мая 2005 9:35
GUNgine | 20 мая 2005 | 9:01 | #634 |
---|
на чем компилируешь? там ве компилируеться на Visual C++ 6.0 с небольшими исправлениями некоторых мест...
на Visual C++ .Net 2002 компилируеться без проблем...
1C идёт на запад | 18 мая 2005 | 13:24 | #28 |
---|
>Значит - небольшие разработчики из провинции(!!!) никуда не денутся, только им будет немного сложнее маневрировать. И >лучший выход для них, мне кажется, это захватывающие и оригинальные проекты, не обладающие большим бюджетом.
-=InQ=-
>А его некому выдавать в провинции
обидная реальность....
-=InQ=-
>У нас программистов учат паскалю
у нас в институте раньше учили, теперь еще мышкой щелкать умеют :))GLoom
GLoom
>А мне вот страшненько. Столько лет убил на развитие в сторону PC
не переживай все у тебя получиться... ты человек с опытом и знаниями
MAX7 SDK | 14 мая 2005 | 14:21 | #10 |
---|
Имне пожалуйста!!
только если не сложно по частям по 1 метру
заранее спасибо :)
Поздравляем CEMEHа с днём рождения!!! | 12 мая 2005 | 13:04 | #40 |
---|
Я присоеденяюсь к поздравлениям!!! всего тебе чего сам пожелаешь!!!
OpenGL vs DirectX или на чем лучше(легче:)) писать движок? | 11 мая 2005 | 9:04 | #15 |
---|
лучше знать оба API, а качество написания движков зависит не от API, а от кривизны рук :)
C++. Указатель на функцию-компонент класса. ? | 6 мая 2005 | 17:58 | #2 |
---|
Ну на сколько я понял вот так попробуй:
class СD { public: CD(void CD::*ptrFunc()); void DoFunc(); private: void (*func_ptr)(void); }; ... //.cpp file CA::CA() { pD = new CD(void CD::*func_ptr ()); } ... CD::CD(void CD::*func_ptr ()) { this->func_ptr = func_ptr; }
Камера в Direct3D и OpenGL: почему в Direct3D работает неправильно? | 6 мая 2005 | 9:19 | #14 |
---|
Все получилось, поставил минус в повороте камеры
crazy25,IPSer,jm
Всем большое спасибо!!!!!! тема закрыта.
Камера в Direct3D и OpenGL: почему в Direct3D работает неправильно? | 6 мая 2005 | 9:10 | #13 |
---|
Спасибо большое!!!!! все заработало...
только во еще 1 мелочь как заставить что бы камера поворачивалась обратно перемещению мыши в плоскости X0Z?
т.е. мышью двиоаю влево камера вправо и наоборот?
Камера в Direct3D и OpenGL: почему в Direct3D работает неправильно? | 5 мая 2005 | 18:49 | #11 |
---|
а по сути?