Увеличение производительности
Подскажите кто знает.
заранее спасибо
Если это решеие чем-то не одходит, поподробнее опиши задачу: что за точки и для чего они нужны.
и ты маня заитересовал по поводу текструры. каким способом ее можно создать?:o
Для создания текстуры - выделяешь память, заливаешь цветом фона, вычисляешь координаты каждой точки на текстуре и рисуешь ее каким-либо другим цветом, после чего биндишь сощданую текстуру средствами OpenGL.
а по-русски?!!!!:o:o:o
как мне это сделать?!!!!
какими функциями?
а что мне надо - надо не перерисовывать всю сцену а только то что я хочу изменить
ну например как в игре- сцена не перерисовывается а человечки движуться,т.е перерисовывается их местоположение.!!!!!!!
по поводу текстуры- я так и не понял как это делается!!!!
1. Насколько я понял, проблема не в самой перерисовке как таковой, а в том, что ты скармливаешь OpenGL весь набор точек вне зависимости от того, надо ли его рисовать. Можно попытаться передавать на графический конвейер не все точки, а лишь те, которые нужны для текущего кадра. Как - для этого надо лучше представлять исходную задачу.
2. Текстурирование - элементарное действие в OpenGL. В любой доке по нему это подробно описано.
2. я не особо разбираюсьа прорисовке отдельных кадров. я вот знаю что идет такой процесс которым я и сейчас пользуюсь:
{
GLUquadricObj *quadObj;
if (f_r==0) {
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
quadObj = gluNewQuadric();
gluQuadricTexture(quadObj, GL_TRUE);
gluQuadricDrawStyle(quadObj, GLU_FILL);
glGetIntegerv(GL_VIEWPORT,viewport); // узнаём параметры viewport-a.
glGetDoublev(GL_PROJECTION_MATRIX,projection); // узнаём матрицу проекции.
glGetDoublev(GL_MODELVIEW_MATRIX,modelview); // узнаём видовую матрицу.
}
glPushMatrix(); //повороты нужны для вращения земного шара
glRotated(roty, 1,0,0);//когда используешь для этого мышку(как в проге \\ GoogleEarth)
glRotated(rotx, 0,-1,0);
glColor3d(1,1,1);
if (CheckBox1->Checked==true)
glRotated(-povzem,0,1,0);
glPushMatrix();
glRotated(-90, 1,0,0);
gluSphere(quadObj, Rz, 100, 100);\\\ рисование земного шара
glPopMatrix();
gluDeleteQuadric(quadObj);
Draw2();
if (f_r==0)
{
DrawPsTG(); \\рисование подспутниковой точки
DrawPn();
DrawSetka();\\рисование коодинатной сетки
Drawspyt(); \\рисование местоположения спутника
Drawrti(); \\рисование массива точек
glPopMatrix();
}
SwapBuffers(ghDC); \\смена буферов.
}
Drawrti(); - функция которая все тормозит.даже когда пользуешься списками и массивами вершин. мне надо чтобы они только один раз прорисовались.
1. Оптимизация вывода массива точек.
2. Замена массива точек текстурой.
Итак:
1. Если точки распределены по всему земному шару, то половина из них сразу не видна, т.к. находится на невидимой стороне Земли. Нужно их рисовать? Вряд ли.
Если ты находишься достаточно близко к Земле, и видишь только небольшую часть поверхности, нужно тебе рисовать точки, которые не попадают в твое поле зрения? Тоже вряд ли.
Таким образои мы можем довольно существенно сократить количество точек, которое нам нужно рисовать, особенно при взгляде вблизи.
2. Ты пошел по самому простому пути - рисуешь шар высокоуровневой процедурой. И как только у тебя возникает потребность вывести что-то чуть-чуть по-другому, ты сразу не знаешь, что делать. Тебе известны координаты вершин в мировом пространстве твоего полигональной объекта, имитирующего сферу? Тебе известны географические координаты тех же самых вершин? Тебе известнв текстурные координаты этих же самых вершин?
Первые - Бог с ними, вторые и третьи сами по себе также не нужны, а вот связь вторых и третьих тебе для того, чтобы натянуть текстуру, имитирующую точки, нужна обязательно.
Можно, конечно, доподлинно выяснить, как работает gluSphere, и, исходя из этого, найти интересующие нас зависимости (т.е. связь географических и текстурных координат). Но я бы поступил по-другому. Хотя бы для того, чтобы, когда возникнет следующий вопрос, не чесать репу в поисках документации по стандартным ( и не очень) функциям.
- Самостоятельно построил сферу в массиве в оперативной памяти, вычисляя попутно географические и текстурные координаты. Благо, сфера - самая простая фигура, которую только можно придумать.
- Так же в оперативной памяи выделил массив под текстуру.
- Зная формулы перевода географических координат в текстурные, нарисовал бы точки на этой текстуре.
- Выводил бы текстурированную сферу как обычный меш из оперативной памяти.
Еще пара рассуждений по поводу реализации.
Как ты рисуешь точки? Как кружочки?
Тогда тебе нужно будет на текстуре рисовать не кружки, а эллипсы в соответствии с различным растяжением данного элемента текстуры по широте и долготе. В принципе, тоже ничего сложного - все элементарно считается.
Должны ли увеличиваться кружочки п мере приближения к поверхности? Или оставаться примерно постоянного размера?
Во втором случае целесообразно сделать механизм подобный тому, что применяется при трилинейной фильрации. Либо суметь приспособить этот механизм для своих нужд, либо написать аналог ручками.
И последнее.
Если точки, опять же, нужны фиксированного размера на экране вне зависимости от расстояния (с точки зрения текстуры, как ты, наверное, уже понял, это самый сложный случай), возможно, будет целесообразно применить комбинированный подход: на дальних расстояниях использоваьт текстуру, а на ближних - честно рисовать точки, только, естественно, не все, а лишь те, что попадают в зону видимости.
2.для меня идеальный вариант- для отображения файла создается текстура.текстура выглядит так-фон прозразный, точки- только красным цветом. тем самым оператор визуально видит расброс точек а когда кликает на одну из точек, то происходит выделение по цвету (с помощью glReadPixels) и по координатам из файла получает инфу о данной точке (точка- эта меска местоположения объекта в определеный момент времени.в файле хранится время,место и параметры объекта).
3. да я могу рисовать сферу с помощью например прямоугольников.просто я никак не могу понять как натягивать тектуру из массивов точек. я везде читал что для загрузки текстуры сначала надо загрузить рисунок в текстуру а потом ее загрузить. но как загрузить текстуру если у меня нет рисунка для загрузки. текстурные координаты по моему мнению нужны для того чтобы натянуть текстуру на объкт если он не стандартнойформы.например если объект создается из массива точек то текстурные координаты говорят какой точке объкта соответствует точка тектуры.все упирется в то что у меня еще нет текстуры
3. мне нужны точки стандартного размера. сейчас я их делаю с помощь. glVertex3f(x,y,z)
2. Текстура не обязательно должна быть прозрачной. Просто заливка одним цветом, точки - другим.
3. Пусть перед тобой на экране окно. Ты умеешь нарисовать в этом окне по заданным координатам точку?
А если это не окно, а рисунок, загруженный в оперативную память, ты можешь на нем в заданном месте нарисовать точку?
А сам можешь в оперативной памяти завести рисунок - двумерный массив точек и покрасить в нем нужный пиксель?
Честно говоря, для меня это действия настолько элементарные, что я не знаю, на что опираться, чтобы объяснить, как это надо делать.
Попытайся написать, как бы ты стал решать такую задачу: создать рисунок размером 1024 на 1024 пикселя, покрасить его в зеленый цвет и поставить точку с координатами (0.345, 0.876).
PS. Кстати, сейчас ты выводишь точки по одной или используешь что-то вроде VertexArray?
тут есть пример для того, как отрисовать в текстуру нужную 3д-сцену
смотри в сторону RenderToTexture
тоже самое и с текстурой, нужен прозразный фон иначе не будет видна изначально натянутая текстура.
2. сложновато ответить на то знаю я то что ты сказал или нет !!!
точки на фоне....так
glBegin(GL_POINTS);
glColor3d(1,0,0);
glVertex3d(-4.5,4,0);
glEnd();
загружать картинку в оперативную память....так....
image = auxDIBImageLoad("photo.bmp");
ну а о том как нарисовать точку не тектуре а не так, поверх как я это делаю не знаю
подскажи хоть какими функциями....
может я и знаю только не до конца разобрался.
Ну, если это такая уж большая проблема, делайте по другому.. Лично я в этом ничего сложного не вижу.
Автору же порекомендую для изучения книгу "Расширения OpenGL". Автор - Алексей Боресков. Много для себя проясните. Тот же рендеринг в текстуру там хорошо описан.
2. Ксли у тебя цвет не меняется, то glColor3d, думаю, внутри циклане нужен. Кроме того, ты привел только внутренность цикла, а я хотел предложить тебе заменить весь цикл на glVertexPointer + glDrawArrays. Не намного, но должно быть быстрее.
Код загрузки текстуры совсем не тот, тебе нужно загрузить рисунок не в WinGUI, а в OpenGL, т.е. glGenTextures + glBindTexture + glTexParameteri + glteximage2d.
Точка на текстуре, естественно, делается ДО загрузки текстуры в OpenGL.
Экран - двумерняй массив точек (каждая точка - 3 или 4 байта, для 24 и 32-битного цвета соответственно). Поставить точку - записать число в нужный элемент массива. Можно и по другому - через виндовые средства работы с битмапом, но это существенно дольше, так что при миллионе точек, думаю, будет неприемлемо долго.
если я правильно понимаю то что пишеться в учебниках то этот порядок идет когда уже есть какой то рисунок. а если его еще просто в природе не существует?
Цитирую свое предыдущее сообщение:
хм,ну тогда во первых надо сделать так что бы экран был по ширине в 2 раза больше чем по высоте.у меня есть формулы для перевода георафических координат для плоскости.
давай я тебе покажу порядок действий а ты скажешь - прав я или нет.
1.чищу экран и ставлю его размеры 2:1 (ширина:высота).экран чищу белым цветом и абсолютно прозрачным.
2. с помощью
glVertex3f(x,y,z)
glEnd()
наношу точки красным непрозразным цветом по координатам из файла.
3.полученный "рисунок" сохраняю как *.bmp и потом могу ее загрузить как текстуру.
только один вопрос-3 пункт- какими функциями можно создать рисунок из вьюпорта!!!!!
А сам, коль скоро рисовать ты хочешь не ручками (как я предлагапл), а средствами OpenGL, повторю свое предложение заменить кучу вызовов
glVertex3f(x,y,z)
glEnd()
в цикле одним
glVertexPointer + glDrawArrays.
Да, по вопросу в начале письма: экран и битмап в памяти, конечно, несколько различаются, но их внутренняя организация одинакова, поэтому, собственно, я и ошибся, назвав битмап экраном.
Да, и еще: коль скоро тебе нужна исключительно плоская картинка, третья координата вряд ли нужна. Только на этом можно увеличить скорость до полутора раз. Переход на VertexArray должен дать еще примерно двойку и столько же - последующее применение VBO. Так что рисование текстуры средствами OpenGL может привести к уменьшению времени раз в 6 по сравнению с тем, что у тебя сейчас есть. Думаю, что рисование "ручками" все-таки было бы быстрее. Но тут надо пробовать.
Наверное, такой вопрос возник из-за того, что я тебе параллельно предлагаю два разных направления действий:
1. Оптимизация существующего алгоритма, с точками, - применение glDrawArray и VBO.
2. Переход на текстуру, которую я предлагаю создавать не средствами OpenGL, а непосредственно программой, вписывая нужные байты в нужное место массива-текстуры.
Я бы, по крайней мере, попробывал оба эти направления.
то что просто создаешь массив типа данных GLubyte и его отображаешь.!!! мне вот только не очень стало понятно что ты имел ввиду когда говорил по поводу создания средствами OGL?например я создам массив
тут в книгах это пишут но не где на практике не показывают. у меня есть карта местности.есть она вся с плохой детализацией и есть маленькие части с хорошей детализацией. в книгах пишут что можно создавать текстурные объекты которые представляют собой большую текстуру из набора маленьких.не сталкивался с таким?
Честно говоря, не понял, что в описаном алгоритме формирования массива тупого.
А вот записывать из памяти в файл массив, чтобы потом его снова считывать из файла в память - действительно тупо. Загружать, естественно, нужно сразу из памяти.
2. Честно говоря, не вижу в представлении большого объекта как совокупности маленьких ничего необычного. Более того, это наиболее распространенный способ оптимизации как по скорости работы, так и по затратам памяти.
Честно говоря, не понял, что в описаном алгоритме формирования массива тупого.
А вот записывать из памяти в файл массив, чтобы потом его снова считывать из файла в память - действительно тупо. Загружать, естественно, нужно сразу из памяти.
2. Честно говоря, не вижу в представлении большого объекта как совокупности маленьких ничего необычного. Более того, это наиболее распространенный способ оптимизации как по скорости работы, так и по затратам памяти.
1 тупо это не значит что неправильно. я имел ввиду что тут не надо много мозгов-просто прогоняешь цикл и все.а под записью в файл я имел ввиду что для того что бы в след. раз не проделывать это копбинацию можно этот массив загнать в файл*.bmp и потом его загружать в память как текстуру из рисуунка а не из массива.
2. я же написал что нигде не нашел. подскажи хоть какими командами если ты в этом разбираешься.
Ну, "команды", собственно, обычные - циклы, присваивания, выделение памяти, вызов процедур...
Тут, наверное, интереснее подумать над структурой данных, тем более, что по Вирту она связана с алгоритмами.
В наиболее общем виде структура должна состоять из заголова и двумерного массива указателей на структуры следующего уровня (т.е. более высокой детализации).
В заголовке, думаю, должно быть имя файла, откуда считываются данные (если данные берутся именно из файла, иначе - какой-то другой идентификатор) и ссылка на объект более высокого уровня (т.е. с более низким уровнем детализации). А массив в самом простом случае - размером 2х2. Т.е. там должны быть указатели на объекты, содержащие карты вдвое более высокой детализации. Если таких карт нет, то NULL/nil.
Это - структура, предназначенная для работы с загруженными данными. Для загрузки же данных, наверное, лучше в массиве хранить строки с названиями файлов.Правда, тут надо подумать, как это все лучше разместить на диске.