Построение координат 2D-карты в 3D-проекции OpenGL

Я пытаюсь преобразовать 2D-карту, созданную в редакторе карт, в 3D-графику с помощью OpenGL. Это моя карта, сгенерированная в моем редакторе карт:

Редактор карт

Эти вершины относятся к моей координате мира декартового происхождения (вверху рисунка), и я применяю эту формулу, чтобы преобразовать ее в координату объекта OpenGL:

Размер мира: 800×600

x = (X / 800) -0.5
y = (Y / 600) -0.5

Получение этого результата:

(Первый объект лица)

−0.48625, 0.068333333
0.12625, 0.07
0.12875, −0.481666667
−0.4875, −0.486666667

Построив этот буфер вершин в OpenGL, я получил очень странный результат. Итак, как я могу получить 3D-модель из этих позиций вершин? Понравилась эта картинка:

Кладовка

Я рендеринг OpenGL в режиме треугольников и использую этот пример в качестве отправной точки: https://github.com/JoeyDeVries/LearnOpenGL/blob/master/src/1.getting_started/7.4.camera_class/camera_class.cpp

Используя формулу преобразования + тесселяция Earcut (https://github.com/mapbox/earcut.hpp), Я наконец-то правильно отрисовал этот прямоугольник внутри OpenGL. Теперь, когда две плоскости имеют только одну ось Z, проблема заключается в том, как визуализировать ее боковые стороны, поскольку Earcut работает только с 2D-координатами …

Planes

1

Решение

Если я правильно понял, у вас есть некоторые плоские 2D многоугольник и что добавить к нему некоторую постоянную толщину (в виде трехмерной сетки). Это выполнимо довольно легко. Как вы правильно поняли, вам нужно сначала триангулировать. Таким образом, вы должны иметь этот вход:

  1. таблица баллов pnt[pnts]

    список всех точек вашего объекта.

  2. многоугольник pol[pols] (окружность вашего объекта)

    просто упорядоченный список точек индексов, ссылающихся на таблицу точек

  3. результат триангуляции fac[facs]

    упорядоченный список 3-х точечных индексов, представляющих все треугольники.

Теперь, чтобы сделать из него меш, нам нужно сделать это:

  1. скопируйте все точки и вытяните их с помощью некоторого перевода.

    все эти новые очки будут добавлены к текущему pnt[pnts] Таблица. Не забудьте запомнить оригинальный размер стола pnts0 как это будет нужно позже.

  2. скопируйте / отмените триангуляцию.

    Противоположная сторона треугольного многоугольника будет такой же, как и в обратной обмотке многоугольника. Так что просто скопируйте его в fac[facs] как новые треугольники в обратном порядке индексов … Не забудьте добавить исходный размер таблицы точек ко всем новым граням. Это будет использовать новые точки … Из ваших изображений вы уже достигли этой точки.

  3. создать недостающие боковые грани.

    Для этого мы можем использовать оригинальный многоугольник. Поскольку мы просто скопировали точки, то мы знаем, что pnt[3*i] противоположно pnt[pnts0+3*i], Таким образом, мы просто создаем грани треугольника, соединяющие противоположные края многоугольника.

Вот небольшой пример C ++, который я сейчас использовал для этого:

//---------------------------------------------------------------------------
#include <vcl.h>
#include <math.h>
#pragma hdrstop
#include "Unit1.h"#include "gl_simple.h"//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"TForm1 *Form1;
//---------------------------------------------------------------------------
const int N=128;
int pnts=6*3;                   // 3* number of points
float pnt[N]=                   // x,y per each point
{
-0.5,-0.5,0.0,              //   6 ------ 9
-0.4, 0.0,0.0,              //    +      +
-0.5,+0.5,0.0,              //     3   12
+0.5,+0.5,0.0,              //    +      +
+0.4, 0.0,0.0,              //   0 ----- 15
+0.5,-0.5,0.0,
};
int pol[N]={ 0,3,6,9,12,15 }, pols=6; // original polygon (3*pnt index), number of its vertexes
int fac[N]=                     // triangulation result (3*pnt index)
{
0,3,15,
3,12,15,
3,6,12,
6,9,12,
}, facs=4*3;                // number of triangles*3
//---------------------------------------------------------------------------
void extrude(float dz)
{
int i,i0,pnts0=pnts;
// copy and reverse triangulation
for (i=0;i<facs;i++)
fac[facs+facs-1-i]=fac[i]+pnts; facs+=facs;
// duplicate points
for (i=0;i<pnts;i++) pnt[pnts0+i]=pnt[i]; pnts+=pnts;
// extrude points
for (i=      2;i<pnts0;i+=3) pnt[i]-=dz;
for (         ;i<pnts ;i+=3) pnt[i]+=dz;
// side faces
for (i0=pols-1,i=0;i<pols;i0=i,i++)
{
fac[facs]=pol[i ]+pnts0; facs++;
fac[facs]=pol[i ];       facs++;
fac[facs]=pol[i0];       facs++;

fac[facs]=pol[i0]+pnts0; facs++;
fac[facs]=pol[i ]+pnts0; facs++;
fac[facs]=pol[i0];       facs++;
}
}
//---------------------------------------------------------------------------
void gl_draw()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glDisable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
glEnable(GL_COLOR_MATERIAL);
/*
glPolygonMode(GL_FRONT,GL_FILL);
glPolygonMode(GL_BACK,GL_LINE);
glDisable(GL_CULL_FACE);
*/

// set view
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0,0.0,-5.0);
static float ang=0.0;
glRotatef(ang,0.2,0.7,0.1); ang+=5.0; if (ang>=360.0) ang-=360.0;

// render mesh
float *p0,*p1,*p2,n[3],a[3],b[3],c;
glColor3f(0.7,0.7,0.7);

glBegin(GL_TRIANGLES);
for (int i=0;i+3<=facs;i+=3)
{
// points
p0=pnt+fac[i+0];
p1=pnt+fac[i+1];
p2=pnt+fac[i+2];
// compute normal
a[0]=p1[0]-p0[0]; a[1]=p1[1]-p0[1]; a[2]=p1[2]-p0[2];
b[0]=p2[0]-p1[0]; b[1]=p2[1]-p1[1]; b[2]=p2[2]-p1[2];
n[0]=(a[1]*b[2])-(a[2]*b[1]);
n[1]=(a[2]*b[0])-(a[0]*b[2]);
n[2]=(a[0]*b[1])-(a[1]*b[0]);
c=1.0/sqrt((n[0]*n[0])+(n[1]*n[1])+(n[2]*n[2]));
n[0]*=c; n[1]*=c; n[2]*=c;
// render
glNormal3fv(n);
glVertex3fv(p0);
glVertex3fv(p1);
glVertex3fv(p2);
}
glEnd();

//  glFlush();
glFinish();
SwapBuffers(hdc);
}
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner)
{
// Init of program
gl_init(Handle);    // init OpenGL
extrude(0.2);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
// Exit of program
gl_exit();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
{
// repaint
gl_draw();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormResize(TObject *Sender)
{
// resize
gl_resize(ClientWidth,ClientHeight);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::tim_redrawTimer(TObject *Sender)
{
gl_draw();
}
//---------------------------------------------------------------------------

это VCL на основе так игнорировать все VCL вещи и портировать события, которые вы хотите / нужно и GL контекст материал для вашего стиля программирования. Единственные важные вещи здесь:

столы pnt,fac,pol который содержит вход и последний также вывод. extrude(dz) создаст сетку (назовите ее только один раз!), и gl_draw отобразит таблицы как сетку (используя старый стиль GL API для простоты).

Для вещей GL я использовал свой gl_simple.h который вы можете найти в этом QA:

Вот предварительный просмотр кода выше:

предварительный просмотр

choppynes из-за моего захвата GIF, рендеринг плавный. Я использовал статическое распределение и на ходу обычные вычисления, поэтому код прост и понятен. Для реальной сделки вам нужно реализовать динамические списки и VAO / VBO … если вы хотите хорошую производительность

2

Другие решения

Трудно сказать наверняка, но кажется, что ваш объект имеет только две визуализированные грани, потому что вы не добавили другие грани в указатель.

Потому что у вас есть вершины, но вы также должны сказать, есть треугольники для сторон. Если это треугольники, вам нужно нарисовать 16 треугольников.
Если вы не используете индекс, вам нужно продублировать свои вершины для каждого треугольника и в итоге получить 48 вершин для рисования.

Что касается алгоритма зашифровки для работы в 3D, если вы точно знаете, что у вашего многоугольника есть все точки в одном плане, вы можете взять 3 вершины, вывести его план и создать матрицу преобразования, чтобы привести все эти точки к ( х, у, 0), который похож на 2D-координаты.

0

По вопросам рекламы [email protected]