На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела "Программирование графики"
1) Данный раздел предназначен для обсуждения проблем, возникающих при программировании задач, связанных с чтением, сохранением, обработкой, созданием, отрисовкой графической информации (в том числе - 3D [OpenGL, Direct3D] и анимации [в т.ч. VFW, DirectShow, OpenDML]).
Флэш обсуждают здесь!.

2) Если вы хотите получить совет для конкретной платформы/языка программирования, обязательно укажите их в вопросе.

3) Уважаемые новички! Мы приветствуем Ваше желание научить всех посетителей раздела правильному программированию. Но огромная просьба, перед тем, как писать поучения в старых (последний ответ - "старее" месяца, а особенно, если вопрошавший не появляется на форуме уже не первый месяц, в чем можно убедиться в его профиле) темах, хорошо подумать, будет ли кому-нибудь, кроме Вас cамих, это интересно.



Ваше мнение о модераторах: user posted imageBarazuk, user posted imageOpenGL, user posted imageMikle
Модераторы: OpenGL, Mikle
Страницы: (13) [1] 2 3 ...  12 13 все  ( Перейти к последнему сообщению )  
> Cвободно летающая камера в 3D (OpenGL - EGL, Delphi XE7), пишу кросс-платформенную графическую библиотеку
    Приветствую всех круглых любителей квадратных пикселов.
    Как вы уже заметили по скриншотику, я сейчас озадачилась построением графических примитивов, воюю с нормалями.

    user posted image

    Вот как у меня строится цилиндр (пока без крышек):

    ExpandedWrap disabled
      // рассчитать массив вершин для единичного цилиндра
      function CalcUnitaryCylinder(vSlice:Integer):TAVertexN;
      var i,k:Integer;  a,da:Single; p,vN,p0,p1,p2,p3:TV3; avn:TAVertexN;
      begin
       SetLength(avn,(vSlice+1)*2);
       da:=pi2/vSlice; // delta angle by slice
       for i:=0 to vSlice do begin
        a:=i*da;
        p:=vX*Sin(a)+vZ*Cos(a);
        k:=2*i;
        avn[k+0].V:=p+vY;
        avn[k+1].V:=p-vY;
       end;
       for i:=0 to vSlice-1 do begin
        k:=2*i;
        vN:=vNormal3p(avn[k+2].V,avn[k+0].V,avn[k+1].V); // обход против часовой, нормали наружу
        avn[k+0].N:=vN;
        avn[k+1].N:=vN;
       end;
       k:=2*vSlice;
       vN:=vNormal3p(avn[0].V,avn[k+0].V,avn[k+1].V); // .. последней паре нормали с 0й точкой - не то
       avn[k+0].N:=vN;
       avn[k+1].N:=vN;
       Result:=avn;
      end;
       
      // отобразить готовый массив вершин как TRIANGLE_STRIP
      procedure DrawAVertexNStrip(avn:TAVertexN;Size,Position,Rotation:TV3);
      begin
       glVertexPointer(3, GL_FLOAT, SizeOf(TVertexN), @avn[0].V);
       glNormalPointer(GL_FLOAT, SizeOf(TVertexN), @avn[0].N);
       glPushMatrix;
       PositionRotate(Position,Rotation);
       glDrawArrays(GL_TRIANGLE_STRIP, 0, Length(avn));
       glPopMatrix;
      end;
       
      procedure Cylinder(Size,Position,Rotation:TV3;ShadeModel:TShadeModel=shmDefault);
      var i:Integer; avn:TAVertexN;
      begin
       avn:=CalcUnitaryCylinder(nSlice);
       for i:=0 to High(avn) do
        avn[i].V:=avn[i].V*Size;
       SetShadeModelSmooth(ShadeModel);
       DrawAVertexNStrip(avn,Size,Position,Rotation);
      end;


    Что не так:
    - на последней секции нормаль навыворот;
    - на картинке Flat нормали, при Smooth их гладит между треугольниками, видны косые грани, это не то; наверное надо нормали в каждом вертексе пооттопыривать (усреднить с соседними);
    - ради крышек сверху и снизу придется еще пару раз glDrawArrays творить, а хотелось бы единым массивом GL_TRIANGLE_STRIP;
    - и вообще меня терзают смутные сомнения, таким путем я на сфере вспотею, а текстурировать аж страшно. Есть ли у кого толковые примеры построения цилиндра, сферы и т.п. через glDrawArrays?

    Я использую Delphi XE7, в данном случае без FMX, графика Open GL/ Open GL ES (EGL).

    Репо открыто: http://sourceforge.net/p/delphioga/code/ci/default/tree/
    На днях скомпилировала демку с кубеменами и выложила на Яндекс-диск:
    Android mc.apk 3.8 MB https://yadi.sk/d/UaGYqsu9ff8Dd
    Win32 mc.zip 1.7 MB https://yadi.sk/d/tBKQxaV7ff8KW
    Все в дебаге, не пугайтесь мегабайт. Под Win жать WASD и F1, мышой тащить - поворот. А на планшете и ёжик разберется :))
    Ну, и моя старая демка под Win, кто помнит, она нам еще тут пригодится: http://bionica-game.tumblr.com/
      Цитата Блекморша Таня @
      Есть ли у кого толковые примеры построения цилиндра, сферы и т.п. через glDrawArrays?
      А почему бы вам не взять исходники gluCylinder и т.п.? Могу выложить, коли лень искать.
      П.С. кстати, с точки зрения теории приближений, цилиндр будет построен наиболее точно, если решётка точек на верхнем контуре будет довёрнута на угол в дельтаФи/2, где дельтаФи - угол меж двумя соседними точками. ;)
        Славян
        Да, надо бы глянуть исходники glu (C++?), плиз выкладывайте, в тему. Мне нужно бы через glDrawArrays, потому как glBegin и прочего "старья" в EGL просто нет. Впрочем перевести можно.
        Кроссплатформа у меня такая: под Android используются функции EGL Androidapi.Gles.pas, Androidapi.Gles2.pas + дописаны свои glOrtho,gluPerspective,LookAt;
        ну а под Windows использую старый добрый Winapi.OpenGL.pas. Поэтому OpenGL могу использовать в той его части, что есть в EGL 1.4, если что-то сверх этого - под EGL придется как то имитировать.
        Прикладной код, как в примере, един на обе платформы.
        Довернуть точки - это запросто, но мне недовернутый вариант больше подходит, я этой же функцией при малом числе Slice вывожу треугольные, пятиугольные и т.п. штуковины.
        У самостоятельного написания примитивов есть плюсы, можно делать оптимизированные варианты функций.
        Например, кроме куба буду делать функцию "объект состоящий из многих одинаковых кубиков, у коих смежные грани и не существуют". Типа примитивных вокселей.
          Цитата Блекморша Таня @
          Да, надо бы глянуть исходники glu (C++?), плиз выкладывайте, в тему. Мне нужно бы через glDrawArrays, потому как glBegin и прочего "старья" в EGL просто нет. Впрочем перевести можно.
          Да, почти - Си'шный код. Если что - переведёте без проблем:
          ExpandedWrap disabled
            void GLAPI
            gluCylinder(GLUquadric *qobj, GLdouble baseRadius, GLdouble topRadius,
                    GLdouble height, GLint slices, GLint stacks)
            {
                GLint i,j,max;
                GLfloat sinCache[CACHE_SIZE];
                GLfloat cosCache[CACHE_SIZE];
                GLfloat sinCache2[CACHE_SIZE];
                GLfloat cosCache2[CACHE_SIZE];
                GLfloat sinCache3[CACHE_SIZE];
                GLfloat cosCache3[CACHE_SIZE];
                GLfloat angle;
                GLfloat x, y, zLow, zHigh;
                GLfloat sintemp, costemp;
                GLfloat length;
                GLfloat deltaRadius;
                GLfloat zNormal;
                GLfloat xyNormalRatio;
                GLfloat radiusLow, radiusHigh;
                int needCache2, needCache3;
             
                if (slices >= CACHE_SIZE) slices = CACHE_SIZE-1;
             
                if (slices < 2 || stacks < 1 || baseRadius < 0.0 || topRadius < 0.0 ||
                    height < 0.0) {
                gluQuadricError(qobj, GLU_INVALID_VALUE);
                return;
                }
             
                /* Compute length (needed for normal calculations) */
                deltaRadius = baseRadius - topRadius;
                length = SQRT(deltaRadius*deltaRadius + height*height);
                if (length == 0.0) {
                gluQuadricError(qobj, GLU_INVALID_VALUE);
                return;
                }
             
                /* Cache is the vertex locations cache */
                /* Cache2 is the various normals at the vertices themselves */
                /* Cache3 is the various normals for the faces */
                needCache2 = needCache3 = 0;
                if (qobj->normals == GLU_SMOOTH) {
                needCache2 = 1;
                }
             
                if (qobj->normals == GLU_FLAT) {
                if (qobj->drawStyle != GLU_POINT) {
                    needCache3 = 1;
                }
                if (qobj->drawStyle == GLU_LINE) {
                    needCache2 = 1;
                }
                }
             
                zNormal = deltaRadius / length;
                xyNormalRatio = height / length;
             
                for (i = 0; i < slices; i++) {
                angle = 2 * PI * i / slices;
                if (needCache2) {
                    if (qobj->orientation == GLU_OUTSIDE) {
                    sinCache2[i] = xyNormalRatio * SIN(angle);
                    cosCache2[i] = xyNormalRatio * COS(angle);
                    } else {
                    sinCache2[i] = -xyNormalRatio * SIN(angle);
                    cosCache2[i] = -xyNormalRatio * COS(angle);
                    }
                }
                sinCache[i] = SIN(angle);
                cosCache[i] = COS(angle);
                }
             
                if (needCache3) {
                for (i = 0; i < slices; i++) {
                    angle = 2 * PI * (i-0.5) / slices;
                    if (qobj->orientation == GLU_OUTSIDE) {
                    sinCache3[i] = xyNormalRatio * SIN(angle);
                    cosCache3[i] = xyNormalRatio * COS(angle);
                    } else {
                    sinCache3[i] = -xyNormalRatio * SIN(angle);
                    cosCache3[i] = -xyNormalRatio * COS(angle);
                    }
                }
                }
             
                sinCache[slices] = sinCache[0];
                cosCache[slices] = cosCache[0];
                if (needCache2) {
                sinCache2[slices] = sinCache2[0];
                cosCache2[slices] = cosCache2[0];
                }
                if (needCache3) {
                sinCache3[slices] = sinCache3[0];
                cosCache3[slices] = cosCache3[0];
                }
             
                switch (qobj->drawStyle) {
                  case GLU_FILL:
                /* Note:
                ** An argument could be made for using a TRIANGLE_FAN for the end
                ** of the cylinder of either radii is 0.0 (a cone).  However, a
                ** TRIANGLE_FAN would not work in smooth shading mode (the common
                ** case) because the normal for the apex is different for every
                ** triangle (and TRIANGLE_FAN doesn't let me respecify that normal).
                ** Now, my choice is GL_TRIANGLES, or leave the GL_QUAD_STRIP and
                ** just let the GL trivially reject one of the two triangles of the
                ** QUAD.  GL_QUAD_STRIP is probably faster, so I will leave this code
                ** alone.
                */
                for (j = 0; j < stacks; j++) {
                    zLow = j * height / stacks;
                    zHigh = (j + 1) * height / stacks;
                    radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
                    radiusHigh = baseRadius - deltaRadius * ((float) (j + 1) / stacks);
             
                    glBegin(GL_QUAD_STRIP);
                    for (i = 0; i <= slices; i++) {
                    switch(qobj->normals) {
                      case GLU_FLAT:
                        glNormal3f(sinCache3[i], cosCache3[i], zNormal);
                        break;
                      case GLU_SMOOTH:
                        glNormal3f(sinCache2[i], cosCache2[i], zNormal);
                        break;
                      case GLU_NONE:
                      default:
                        break;
                    }
                    if (qobj->orientation == GLU_OUTSIDE) {
                        if (qobj->textureCoords) {
                        glTexCoord2f(1 - (float) i / slices,
                            (float) j / stacks);
                        }
                        glVertex3f(radiusLow * sinCache[i],
                            radiusLow * cosCache[i], zLow);
                        if (qobj->textureCoords) {
                        glTexCoord2f(1 - (float) i / slices,
                            (float) (j+1) / stacks);
                        }
                        glVertex3f(radiusHigh * sinCache[i],
                            radiusHigh * cosCache[i], zHigh);
                    } else {
                        if (qobj->textureCoords) {
                        glTexCoord2f(1 - (float) i / slices,
                            (float) (j+1) / stacks);
                        }
                        glVertex3f(radiusHigh * sinCache[i],
                            radiusHigh * cosCache[i], zHigh);
                        if (qobj->textureCoords) {
                        glTexCoord2f(1 - (float) i / slices,
                            (float) j / stacks);
                        }
                        glVertex3f(radiusLow * sinCache[i],
                            radiusLow * cosCache[i], zLow);
                    }
                    }
                    glEnd();
                }
                break;
                  case GLU_POINT:
                glBegin(GL_POINTS);
                for (i = 0; i < slices; i++) {
                    switch(qobj->normals) {
                      case GLU_FLAT:
                      case GLU_SMOOTH:
                    glNormal3f(sinCache2[i], cosCache2[i], zNormal);
                    break;
                      case GLU_NONE:
                      default:
                    break;
                    }
                    sintemp = sinCache[i];
                    costemp = cosCache[i];
                    for (j = 0; j <= stacks; j++) {
                    zLow = j * height / stacks;
                    radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
             
                    if (qobj->textureCoords) {
                        glTexCoord2f(1 - (float) i / slices,
                            (float) j / stacks);
                    }
                    glVertex3f(radiusLow * sintemp,
                        radiusLow * costemp, zLow);
                    }
                }
                glEnd();
                break;
                  case GLU_LINE:
                for (j = 1; j < stacks; j++) {
                    zLow = j * height / stacks;
                    radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
             
                    glBegin(GL_LINE_STRIP);
                    for (i = 0; i <= slices; i++) {
                    switch(qobj->normals) {
                      case GLU_FLAT:
                        glNormal3f(sinCache3[i], cosCache3[i], zNormal);
                        break;
                      case GLU_SMOOTH:
                        glNormal3f(sinCache2[i], cosCache2[i], zNormal);
                        break;
                      case GLU_NONE:
                      default:
                        break;
                    }
                    if (qobj->textureCoords) {
                        glTexCoord2f(1 - (float) i / slices,
                            (float) j / stacks);
                    }
                    glVertex3f(radiusLow * sinCache[i],
                        radiusLow * cosCache[i], zLow);
                    }
                    glEnd();
                }
                /* Intentionally fall through here... */
                  case GLU_SILHOUETTE:
                for (j = 0; j <= stacks; j += stacks) {
                    zLow = j * height / stacks;
                    radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
             
                    glBegin(GL_LINE_STRIP);
                    for (i = 0; i <= slices; i++) {
                    switch(qobj->normals) {
                      case GLU_FLAT:
                        glNormal3f(sinCache3[i], cosCache3[i], zNormal);
                        break;
                      case GLU_SMOOTH:
                        glNormal3f(sinCache2[i], cosCache2[i], zNormal);
                        break;
                      case GLU_NONE:
                      default:
                        break;
                    }
                    if (qobj->textureCoords) {
                        glTexCoord2f(1 - (float) i / slices,
                            (float) j / stacks);
                    }
                    glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i],
                        zLow);
                    }
                    glEnd();
                }
                for (i = 0; i < slices; i++) {
                    switch(qobj->normals) {
                      case GLU_FLAT:
                      case GLU_SMOOTH:
                    glNormal3f(sinCache2[i], cosCache2[i], 0.0);
                    break;
                      case GLU_NONE:
                      default:
                    break;
                    }
                    sintemp = sinCache[i];
                    costemp = cosCache[i];
                    glBegin(GL_LINE_STRIP);
                    for (j = 0; j <= stacks; j++) {
                    zLow = j * height / stacks;
                    radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
             
                    if (qobj->textureCoords) {
                        glTexCoord2f(1 - (float) i / slices,
                            (float) j / stacks);
                    }
                    glVertex3f(radiusLow * sintemp,
                        radiusLow * costemp, zLow);
                    }
                    glEnd();
                }
                break;
                  default:
                break;
                }
            }

          Цитата Блекморша Таня @
          Довернуть точки - это запросто, но мне недовернутый вариант больше подходит, я этой же функцией при малом числе Slice вывожу треугольные, пятиугольные и т.п. штуковины.
          Ну ладно - вам виднее. Просто есть ещё такой интересный момент: все обычно пользуются готовым примитивом 'сфера', а она создаётся OpenGL'ем до жути неоптимально (на полюсах - сгустки точек). А вот если бы вы погрузились в контактные числа и забабахали создание сферы с равномерным распределением точек, то издалека бы ваши сферы казались довольно гладкими, а точек было бы оптимально мало! ;)
          Сообщение отредактировано: Славян -
            Цитата Славян @
            точек было бы оптимально мало!

            Точек было бы всего в полтора раза меньше. Но все-же даже при грубом приближении сфера выглядела бы заметно аккуратнее.
            Правда программа для генерации приблизительно равномерного размещения точек заметно длиннее. Даже если ограничиться случаем аппроксимации только 20*n2-гранниками.
            И контактные числа в этом деле не помогут. Тут немного другой принцип.
              Цитата amk @
              Правда программа для генерации приблизительно равномерного размещения точек заметно длиннее. Даже если ограничиться случаем аппроксимации только 20*n2-гранниками.
              Крошить икосаэдры предлагаете? Наверное неплохой вариант, хоть и далеко не оптимальный. :yes:
                Славян
                Вери сенкз. Почитать интересно, только сегодня думала об этом:
                Цитата
                An argument could be made for using a TRIANGLE_FAN for the end of the cylinder of either radii is 0.0 (a cone). However, a TRIANGLE_FAN would not work in smooth shading mode (the common case) because the normal for the apex is different for every triangle (and TRIANGLE_FAN doesn't let me respecify that normal). Now, my choice is GL_TRIANGLES, or leave the GL_QUAD_STRIP and just let the GL trivially reject one of the two triangles of the QUAD. GL_QUAD_STRIP is probably faster, so I will leave this code alone.

                Черт сидит в мелочах. Но переводить glu целиком на мой случай сложно: GL_QUAD_STRIP, glNormal3f, glVertex3f и т.п. в EGL нет (прикиньте, они даже на кваде сэкономили, я его 2-мя GL_TRIANGLE_STRIP рисую).
                В EGL есть массивы вертексов с нормалями (но они в видеокарту почему-то не грузятся, они в ОЗУ живут, мне непонятно почему так), если на них переписать - родной отец этого модуля не узнает свои алгоритмы.

                Я была бы еще более рада толковым рабочим Delphi примерам построения 3D примитивов с glVertexPointer, glNormalPointer, glDrawArrays, но без glBegin, glVertex3f (EGL базируется на OGL 2.0, то есть для меня это вопрос не стиля, я необходимость).

                Мой вариант отрисовки цилиндра мне кажется более понятным и компактным, я его как-то случайно начала сама писать, даже не погуглила и теперь не жалею. Если Вы заметили, я расчеты и рисование разношу по разным функциям, это мне позволит оптимизировать быстродействие, по сути могу единичный цилиндр один раз посчитать и потом нарисовать N разных цилиндров, используя только glDrawArrays, каждый могу в динамике скалить (плющить), крутить как угодно, цвет менять.
                Я пытаюсь нащупать выгодную стратегию для рисования параметрических примитивов, потому как после цилиндра их будет еще десяток других.

                Вы угадали мою мысль, я игралась с glu функциями (старая демка) и "снаружи" поняла по тестам что они неоптимальны в своей реализации для моих задач. Мне эти "сгустки точек на полюсах" сферы тоже не нравятся, хочу равномерное распределение точек. Я позволю себе идти к более-менее оптимальному решению таким путем: цилиндр, "равно-граненные-примитивы-как-их-там-зовут", и только потом сфера. Правда, потом мне еще текстурирование писать, в случае равномерного распределения точек сферы нужно её развертку думать так, чтобы легко натянуть на неё квадратную N2 текстурку, и на этой текстурке рисование с "пред-искажениями" не было бы слишком сложным.

                "Контактные числа" тут не к чему, есть дискрет угла 2*Pi/n в полярной системе координат, этого достаточно для построения сферы с равномерным распределением точек.

                Дополнительно сообщаю Вам, что "мои сферы" как издалека, так и вблизи выглядят вполне гладко, но несколько выпирают за рамки рассматриваемой тематики :)) Постарайтесь сосредоточится на своем "цилиндре" :)) <пацталом> :))
                Сообщение отредактировано: Блекморша Таня -
                  Цитата Славян @
                  Крошить икосаэдры предлагаете? Наверное неплохой вариант, хоть и далеко не оптимальный.
                  Метод достаточно простой и даёт аккуратную аппроксимацию.
                    Татьяна, тот код - 2000 года от силиконГрафикс, так что всё сделано вот на том уровне. Для себя понятно, что каждый напишет компактнее и понятнее, и без лишнего. Успехов! ;)

                    Добавлено
                    Цитата amk @
                    Метод достаточно простой и даёт аккуратную аппроксимацию.
                    Да, согласен. Но мы уже, как написала автор темы, вылезли за рамки, интересующие даму. :blush:

                    Добавлено
                    Цитата Блекморша Таня @
                    после цилиндра их будет еще десяток других.
                    Очень хочется от вас увидеть не только квадрики, но и поинтереснее что-нибудь. Седло легендарной обезьянки или ещё какие кубосферы x4 + y4 + z4 = 1 :yes:
                      amk
                      Поддерживаю. Я намекала на n2-гранники, но думаю что если просто, красиво и шустро перейти в полярную систему координат, а потом обратно, то это будет просто дискретизация по углу. Мысль пока не материализовалась в код, как получится так и похвастаюсь.

                      * Уточняю для других возможных читателей, я приняла тот же принцип который в glu и везде практически - примитивы я строю в центре координат, они "единичного размера" (2.0 единицы макс. размер, 1.0 по каждой оси), что здорово упрощает все расчеты. А уже при отрисовке фрейма я их glTransform, glRotate, glScalе, то есть меняю матрицу GPU, но не считаю лишнего на CPU.

                      Все это хорошо, но у меня есть предчувствие, что кто-то давно такое уже написал, отладил и оптимизировал. Быть такого не может, что абсолютно все только glu сферу юзают.
                      Сообщение отредактировано: Блекморша Таня -
                        Славян amk
                        Свои шуточки и оргвопрос я заспойлила, как и остальной длиннопост, побила на спойлеры.
                        Скрытый текст
                        Вы ни разу не вылезли за рамки, наоборот молодцы. Поддержали меня в сложный момент. То я про "сферы" шутила: мол, в случае чего, держите свои "сферы", "цилиндры" и "конусы" в руках :)) Не меряйтесь ими, по крайней мере прямо здесь :)) Пока все норм, я это, без заморочек. Рамок никому не ставлю и не признаю таковых, где рамки увижу бью их. Но и меня поймите: 3-й раз тему же создаю по новой, стоит хоть одному сорваться и начать тролить, я ж за словом в карман не полезу, и тогда что? Четвертого раза может и не быть.

                        Про крошить "икосаедр", это похоже на то что я предлагаю, только думаю: по заданному дискрету угла посчитать равномерную сеточку шарика в полярных координатах, нормали от центра для каждого вертекса естественно же получаются (усреднять соседние не надо). То есть 2*Pi крошить. Если уж крошить, то базовые константы :)) До числа "e" позже доберемся, после кривых Безье. Без е. Безье. Забавное совпадение :))
                        Silicon Graphics
                        Скрытый текст
                        уважаю, Джим Кларк молодец, он как Стив Джобз только без "кислотных закидонов". Вот это были люди, не то что нынешние "прокладко-писатели". Поясню на примерах, почему это имеет отношение к моему вопросу.
                        "Прокладкой" я называю модуль, который сам ничего почти не делает, так, может быть некую объектную структуру создает для удобства его автора, но для своих действий он вызывает другой модуль. Который в свою очередь тоже является "прокладкой". Один слой "прокладки" называют "обертка", это нормально, это полезно. Но наслоений "прокладок" я встречала до 15 (!), и особенно весело видеть что в итоге вызывается-то всего лишь парочка функций WinAPI. Ой, как будто какая религия запрещает вызвать их напрямую :))
                        Подобное возникает из здорового в общем-то принципа, зачем что-то писать когда можно взять нечто уже готовое, работающее и проверенное? Можно взять. Но автор выбранной либы тоже следовал этому принципу, и построил свой труд на чьей-то другой либе и т.п. Матрешка получается.
                        Не из праздного любопытства я проходила отладчиком такие случаи до базового API, а потому что "стопка прокладок" как правило работает проблемно: тормозит, жрет память, утечки, функционал урезан.

                        Жизненные примеры (все тестила, тестовые проги могу предьявить):
                        1) <абзац для Mikle> Microsoft DirectCanvas
                        Скрытый текст
                        тот что основан на Direct2D от DirectX, тот что идет начиная от Win7 (точнее с Vista последний патч) и не работает в WinXP по сути по маркетинговым причинам (DirecX 10). Для неигровой 2D графики это очень удобная штука для программистов, работаем как бы с Canvas привычными методами, но рисует на видеокарте через DirectX. Дополнительные фичи все доступны через интерфейсы, тоже несложно, документировано хорошо.
                        Красота.
                        И че? На простых тестах с кружочками оно медленнее (!) GDI. И это на шустрой видеокарте. Копаю исходники - 12 слоев прокладок над собственным API Direct X, и это в рисовании каждого примитива.
                        Вот мы ругали Билла Гейтса, а без него там вообще каких-то индусов набрали, индусы пишут $1=1 КВ кода, но код у них .. индусский.
                        Говорили же люди - хорошая 2D графика под DirectX делается через Direct3D, а не через Direct2D.
                        Вы должны купить новую Windows (ну, это не про нас:)) и купить новый более мощный компьютер, чтобы узреть новые технологии ... которые местами работают хуже старых. Потому что слой прокладок велик.
                        А лучшие программы под Windows используют разные API почти напрямую, в исходниках видятся лишь минимальные разумные обертки.

                        2) Embarcadero FireMonkey XE7
                        Скрытый текст
                        ну тут подробно останавливаться не буду, хейторы дополнят. Скажу только, что все там есть и местами неплохо сделано, то что было сырое в XE5 уже давно допилено и забыто. FMX реально работает как на Win, так и на iOS и Android. Java-программеры даже мне завидуют и приходят посмотреть, это при том что Java для Android родное средство разработки приложений. Я иду по пути ndk, а Java это sdk. $1200 минимум за одно рабочее место просят эти ребята, а сами сидят они в Питере, Испании и Штатах.
                        И че? Под Win графика работает на DirectCanvas, см. п.1. Число прокладок достигло 15. Комп-то быстрый, все пашет. Каждый exe-шник содержит в себе полную либу графики под DirectCanvas + полную либу на GDI+ ради WinXP. Поэтому exe жирные (это никого не волнует при нынешних компах, просто удивляет). Под Android получше, у них адекватная надстройка над Native-контролами + EGL. Но там другое, время "билда через тулчейны, заливки и деплоя" угнетает каждого.
                        Поэтому: это проект я пишу на Delphi XE7, но без FMX, использую голые API.
                        Плюсы: время "билда через тулчейны, заливки и деплоя" минимально, меня устраивает; время запуска приложения на планшете/смартфоне тоже менее чем у FMX проектов.
                        Минусы: все писать самостоятельно. И передрать толком не от куда. Изначально у меня есть возможность нарисовать треугольник из 3х вершин и более ничего. Меня устраивает.


                        3) GLScene
                        Скрытый текст
                        уф, давайте я по сцене завтра проедусь, с примерами. Достаточно того что FMX с неё был бездарно содран. Она мне нравится, хоть и не красавица.


                        К чему эти мои примеры:
                        - если вы поняли суть "прокладки" и мысленно ощутили боль при использовании "многих слоев прокладок", тогда вам будет понятна необходимость некоторые вещи написать самостоятельно. Я согласна с Славян в его оценке glu, хороший пример и правильное замечание. Это тоже случай "прокладки", но некритический случай, 2 слоя всего, терпимо, кому надо сбоку допишет желаемый функционал, glu не урезает наши возможности. А вот надстройки над glu, видела и такие - они просто смешны.
                        - в своем проекте я постараюсь свести к минимуму "количество слоев". Кроме графики на планшете/смартфоне есть еще тачскрин, датчики, GPS, звук, микрофон, веб-камеры и т.п. все это входит в обсуждаемую тематику, потому как используется для управления и вывода. И в этих вопросах я буду копать Native API.
                        - я не нашла более подходящий вариант названия для описанного мной явления, какой-то англоязычный термин есть по-любому. Но для тех, кто понял концепцию негативного явления "прокладка" я постараюсь на днях изложить суть программных технологий с условными названиями "памперс" и "тампакс". В итоге всем будет сухо и комфортно, можно будет носить белое и обтягивающее, и бесконечно поливать что нибудь-синей жидкостью :))

                        ***

                        Лирика (сочинила только что):
                        Желаю вам ветра, и если он будет у Вас, то пускай он дует из Вашего окна, и на Ваше лицо. Это так приятно, когда у тебя есть свое окно. А лучше все четыре. Это так здорово, когда у тебя есть свое лицо. Не теряйте своего лица, не падайте им в грязь. И не забывайте про ветер, который я пожелала, он терпелив, и будет дуть всегда, пока вы шьете свой парус.
                        Сообщение отредактировано: Блекморша Таня -
                          Славян
                          Обезьянка из Blender-а или FM? Они разные. Но что-то такое надо. Без функции построения чайника вообще не феншуй.
                          "Контактные числа" забраковали, а вот картинка в вики наводит меня на мысль о круглых вокселях. Весь мир из шариков построить. Неоптимально, но кубики уже были.

                          user posted image

                          Прозрачность уже пробовала, на OpenGL все как было (очередность отрисовки), но с EGL придется по-"это-самое". И есть аппаратные зависимости, разные планшеты с прозрачностью глючат по разному.

                          Демки никто не смотрел? Эх, теоретики. Меня интересует испытание apk, репорт идет/неидет с указанием типа устройства. Если вдруг неидет - в logcat пишу шаги инициализации, то есть вы можете глянуть отладочный лог.
                          Напоминаю, для Android mc.apk 3.8 MB качать тут: https://yadi.sk/d/UaGYqsu9ff8Dd
                          У кого нет плашнета - идите и купите себе планшет. Сегодня.

                          Тестили на:
                          1) Lenovo A3300-GV
                          2) Nomi A07000 (китаяц)
                          3) Samsung GALAXY Tab3 Lite SM-T110
                          4) Samsung Galaxy Tab Active 8 SM-T365
                          5) Samsung Galaxy ACE 2.
                          6) Samsung Galaxy Note II GT-N7100

                          2 и 3 у меня при себе.
                            Цитата Блекморша Таня @
                            Обезьянка из Blender-а или FM? Они разные. Но что-то такое надо.
                            Не знаю их различий, сделайте как в вики, например: z = x3 - 3xy2.
                            Цитата Блекморша Таня @
                            Без функции построения чайника вообще не феншуй.
                            Эта экзотика уже написана, не повторяйте глупостей. ;)
                            Цитата Блекморша Таня @
                            картинка в вики наводит меня на мысль о круглых вокселях. Весь мир из шариков построить.
                            Плохая мысль, потому как пока наши вычислительные возможности фантастически далеки от нужной для шаров реализации. А при погружении в мир вокселов придётся слишком много физики поднять, т.к. сами они без неё - полупустые понты. :yes-sad:
                            Цитата Блекморша Таня @
                            Прозрачность уже пробовала, на OpenGL все как было (очередность отрисовки), но с EGL придется по-"это-самое". И есть аппаратные зависимости, разные планшеты с прозрачностью глючат по разному.
                            Да, с прозрачностью известны принципиальные тяготы. Всё просто прёт от того, что сам OpenGL основан на тупом Z-буфере, кой отвратительно работает с категорией 'прозрачность'. Так что советую на неё в первых версиях забить полностью, иначе времени убьёте - вагон. :yes-sad:
                              Славян
                              Сложные фигуры и поверхности описанные мат. функциями мне интересны, но я их планирую делать после базовых примитивов, да и то по необходимости.
                              Вы же не смотрели демку? Демка отличается от скриншота, это я для отладки функций "выключаю мир".
                              Там я нарисовала мир из кубиков, потому что у меня была на тот момент только функция рисования кубика и прямоугольника.
                              Сначала я создала небо, и усыпала его звездами (разноцветные прозрачные кубики по +- сфере от центра вселенной), это у меня вместо скайбокса так пока.
                              Потом я создала землю, она была пуста и безвидна (серый квад, могу на него натянуть текстурку генерированную или из файла, про генератор текстур потом расскажу).
                              Есть время для того чтобы разбрасывать камни и для того чтобы их собирать. По земле я разбросала камни (кубики в greyscale).
                              А по земле бегают разноцветные "кубемены". Их надо видеть, на скриншотах они угловаты, в динамике норм. Это еще будет вопрос потом, параметрическое рисование NPC из примитивов и их анимация.

                              И эта штука работает как под Windows, так и на Android, в этом суть проекта, если бы только под Win было бы не особо актуально.
                              Бегать можно, под Win WASD + мышь тащить, на планшете тачскрин повернутся и 2 экранных кнопки "вперед-назад" (зачатки GUI, это еще будет вопрос потом).
                              Да, из этого уже можно сделать нехитрую игрушку. Но я пока либу пишу (кросс-платформенную библиотеку), пример с кубеменами - лишь пример.
                              У меня там несколько примеров в исходниках, есть и пример 2D графики типа построения больших схем/карт.

                              Ноу-хау тут в том, что такой проект на голых API максимально быстро заливается на планшет (в отличие от FMX) и его приятно разрабатывать. Версия под Win нужна мне лишь для разработки (после отладки платформенно-зависимых методов я спокойно пишу под Win и лишь раз в час проверяю на планшете). Впрочем потом можно и под Win все полноценно допилить.

                              Я выложила ссылку на репо, там все свежие исходники, в моей программе нет вредоносных функций, её смело можно и нужно тестить на мобильных девайсах, ну а версия под Win скажем так - для ознакомления.

                              А у Вас нет планшета/смартфона под Android?
                              Сообщение отредактировано: Блекморша Таня -
                                Цитата Блекморша Таня @
                                Сложные фигуры и поверхности описанные мат. функциями мне интересны, но я их планирую делать после базовых примитивов, да и то по необходимости.
                                Вы же не смотрели демку? Демка отличается от скриншота, это я для отладки функций "выключаю мир".
                                А мне как раз аппроксимация=приближение разного рода поверхностей, точность оного, намного интереснее, нежели просто кубики. Да, до сегодняшнего дня демку вашу не смотрел. Сейчас скачал и посмотрел на бегающих роботов. Эти социально-сетевые баталии скучноваты. :yes-sad:
                                Всякий интерес будет если вы вдруг предложите нечто новое. Например, пусть ваши роботы бегают не по плоскости, а по тору! И пусть тяготение есть к поверхности тора!! Покажите нам, как катится по такому тору, брошенный под углом мяч=шар. Это точно заинтересует определённый круг лиц, поднимет научный интерес к вашей работе=программе. ;)
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (13) [1] 2 3 ...  12 13 все


                                Рейтинг@Mail.ru
                                [ Script Execution time: 0,1549 ]   [ 15 queries used ]   [ Generated: 28.01.21, 05:13 GMT ]