Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Мультимедия, OpenGL/DirectX > Вывод трехмерной матрицы


Автор: Nikonik 21.3.2007, 13:09
Казалось бы простая задача - а найти не могу

Есть трехмерная матрица M[][][]

сейчас я ее вывожу набором вложенных for и рисую куб если в матрице не ноль.
по отрисовке перемещаюсь gl_translatef, после каждого блока for возращаю на суммарный сдвиг

При размере матрицы до 40 -- FPS еще держится на уровне 30-40,  даже уже при размере 64 начинаются дикие тормоза - 3-4 FPS. (я вращаю матрицу)
Я использую библиотеку GLUT.
При GLAUX ситуация чуть лучше. но не намного.
Хочется выводить матрицы размером хотя бы до 256.

Матрица создается в начале программы и больше не меняется
Возможно как-то можно загнать эту структуру в единый объект, или прорисовывать только видимые кубы? 
Подскажите, пожалуйста.

Автор: Rickert 23.3.2007, 09:48
Размер матрицы - это что? Ты же сказал, что у тебя трёхмерная матрица.
В любом случае, делай так: получай все вершины все х объектов в один массив такого типа: x1, y1, z1, x2, y2, z2 и используй glDrawElements.
Как его юзать, читай progz.ru

Автор: Nikonik 28.3.2007, 21:49
Размер матрицы это количество элементов в одной грани
матрицы размером до 256 - это 256х256х256

glDrawElements начал читать....

Автор: Rickert 29.3.2007, 08:04
Ну тогда делаешь так:
Вычисляешь по размеру матрицы координаты вершин куба. По сути у тебя каждая ячейка - это куб. Следовательно тебе нужно просто получить точки (если матрица 3х3х3) вершин 27 кубов. Загоняешь их в один массив, отрисовываешь через drawElements или drawArray, затем ставишь по местам текст со значениями каждой ячейки. Но быстрее будет, если ты будешь работать с текстом, как с полигонами, имея их вершины и выводя также через drawArray или drawElements.

ЗЫ
progz.ru - там перевод красной книги openGL. Очень советую сохранить всё это дело, хороший справочник выходит. Ещё достань книгу Анджела "Программирование графики на opengl", там много мат. трюков и этого тебе хватит на реализацию и понятие азов минимум половину алгоритмов.

Автор: Nikonik 4.4.2007, 13:24
попробовал DrawElements - действительно быстрее, но заодно прочитал и о такой вещи как VBO - она должна еще более ощутимый прирост

Цитата

Загоняешь их в один массив, отрисовываешь через drawElements или drawArray


а как определить порядок вершин? по-моему тут это главная задача

не понял о каком тексте идёт речь

не понял про красную книгу, но progz, читать начал


Автор: Rickert 4.4.2007, 17:56
Есть такая штука - красная книга ogl, там расписаны принципы функционирования его. Так вот: на progz.ru - это перевод этой самой книги.
Цитата(Nikonik @  4.4.2007,  13:24 Найти цитируемый пост)
а как определить порядок вершин?

Порядок на сколько мне известно значения не имеет. Главное чтобы в памяти лежало так, как ты укажешь в параметрах, при вызове функций.

Автор: FIaR 4.4.2007, 22:03
Если юзаеш DrawElements (даже если и drawArray) то порядок вершин имеет весомое значение!


Автор: Rickert 5.4.2007, 07:52
FIaR, и какое?

Автор: Nikonik 8.4.2007, 18:29
Порядок, как оказалось,  имеет значение если использовать culling - я целый час перебирал вершины пока сделал так что кубики видны со всех сторон.

С VBO пока не лады.. не могу найти толкового объяснения.


Автор: betal 17.4.2007, 09:08
 smile 

Автор: Rickert 17.4.2007, 18:26
betal, какой пример ещё?

Автор: betal 19.4.2007, 21:24
на то что получилось.

Автор: Nikonik 15.6.2007, 19:07
Sorry, на форум не заходил smile
Нашел через поисковик - google top по запросу "glaux вывод FPS" - что подтвержает, что мало все-таки литературы по gl в рунете.

С неплохими задержками люди примеры хотят, получилось вот так:

Вершины шестиугольников (в моей пркиладной задаче - шестиугольники)
Код

GLfloat vertices[] =                    //шестиугольник
        {
                   -0.5,0,0,
                   -0.25,0.433,0,
                   +0.25,0.433,0,
                   +0.5,0,0,
                   +0.25,-0.433,0,
                   -0.25,-0.433,0,
                   -0.5,0,0.25,
                   -0.25,0.433,0.25,
                   +0.25,0.433,0.25,
                   +0.5,0,0.25,
                   +0.25,-0.433,0.25,
                   -0.25,-0.433,0.25                 
        }       ;                            
GLuint indices[] = {                //вершины в правильном порядке обхода
                    1,0,6,7,
                    2,1,7,8,
                    3,2,8,9,
                    4,3,9,10,
                    5,4,10,11,
                    0,5,11,6,
                    0,1,2,3,
                    3,4,5,0,
                    9,8,7,6,
                    6,11,10,9,
                    6,7,8,9,
                    9,10,11,6
                    };



Вывод:
Код

static void draw_p(unsigned char x,unsigned char y,unsigned char z)
{
            unsigned char val = M[(x<<16)+(y<<8)+z];
            char clrstr[80];
            float r,g,b;           
           glPushMatrix();     
              glColor3f(colors[val][0],colors[val][1],colors[val][2]);
              glTranslatef((x-128),(y-128),(z-128)/4.0);
              if (x&1) glTranslatef(0,0.5,0); //смещение гексагональной решётки
              glDrawElements (GL_QUADS, 40, GL_UNSIGNED_INT, indices);
            glPopMatrix();
}



В main не забыть привязать:
Код

    glEnableClientState (GL_VERTEX_ARRAY);
    glVertexPointer (3, GL_FLOAT, 0, vertices);

и отвязать smile
Код

         glDisableClientState (GL_VERTEX_ARRAY);


дополнительно ради чего мучался с порядком обхода - culling

Код

        glEnable(GL_CULL_FACE);
        glCullFace(GL_BACK);}

Ну и еще ускорение за счет разрежености матриц + линеаризация трехмерного массива в одномерный M.


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)