/ / swift sphere combine les données des étoiles - swift, astronomy

la sphère rapide combine les données étoiles - rapide, astronomie

je veux construire une application stargazing. Et maintenant, j'ai déjà construit une sphère et la recouvre d'une carte d'étoiles (basée sur les coordonnées célestes). ( https://svs.gsfc.nasa.gov/cgi-bin/details.cgi?aid=3895 )

Maintenant, j'ai un fichier JSON qui a le catalogue star de YBS. (également basé sur les coordonnées célestes). ( http://tdc-www.harvard.edu/catalogs/bsc5.html )

je veux combiner les données avec star map, souhaitantla carte pour afficher le nom de Constellation chaque fois que mon nœud de caméra se tourne vers cet endroit. mais je ne sais pas comment combiner les données et la sphère. La sphère tournera en raison de la latitude et de la durée de l’utilisateur. Les coordonnées de l’étoile doivent également changer.

Est-ce que quelqu'un a des suggestions?

Réponses:

1 pour la réponse № 1

Pas sûr dans votre environnement mais dans votre cas je voudrais:

  1. rendre la sphère texturée (avec la carte profonde)

    La sphère doit être centrée dans la position de votre caméra et avoir un grand rayon couvrant toute la zone de vue. Pour éviter cela semble dans les régions polaires, vous pouvez utiliser ceci:

  2. puis rendre le BSC

    Commencez avec des points (points). Quoi qu’il en soit, si vous souhaitez zoomer et / ou mieux visualiser la magnitude des étoiles, vous devez disposer des capacités de fusion et les transformer en disque semi-transparent faisant face à la caméra (panneaux d’affichage) avec un rayon et une intensité fonction du zoom et de la magnitude.

    J'utilise habituellement cette texture pour l'étoile locale (D = 1/3 de largeur, le reste est en couronne):

    star locale

    Et ceci pour les étoiles BSC (D = presque 100% largeur):

    étoile lointaine

    le alpha est calculé en intensité de couleur alpha=r+g+b/3.

    De cette façon, les binaires visuels et physiques se mélangerontensemble en ajoutant leur magnitude visuelle comme dans la réalité. Cela évitera également le scintillement lors de tout changement de vue dû au repliement entre étoiles très proches.

    Ici, l’animation GIF du zoom (les couleurs sont tramées, d’où le bruit verdâtre) pour que vous ayez l’impression suivante:

    zoom étoile lointaine

[Edit1] exemple simple complet VCL C ++ OpenGL complet

J'utilise les cartes profondes de votre lien. Elles sont rendues avec une distorsion sphérique, de sorte que la triangulation Sphère n’a aucun point (elle n’améliorera rien car les données source sont déjà fausses). Cela implique l'utilisation d'un maillage sphérique standard avec des singularités sur les pôles. le JPG les fichiers sont inutilisables en raison d'artefacts de compression avec perte qui gâchent tout (surtout près des pôles). Je utilise l TIF et redimensionner toutes les textures pour 4096x2048 résolution. Basse résolution ne me semble pas juste.

Ensuite, il ne reste plus qu’à mélanger la skybox de la sphère avec chaque texture. Le résultat est comme ça:

vue d'ensemble

Ce qui montre la surface du pôle Nord pour que vous puissiez voir que les distorsions ne sont pas si mauvaises (à moins que vous ne zoomiez grossièrement).

Après cela, vous pouvez ajouter les étoiles qui ne sont pas présentes dans la carte profonde. Mais comme la carte profonde a déjà le BSC inclus, je ne vois pas l'intérêt de l'ajouter à nouveau (à moins que vous ne souhaitiez calibrer votre rendu pour qu'il soit identique à celui avec lequel la carte profonde a été créée).

Comme demandé ici Exemple complet en C ++ / GL C'était écrit dans BDS2006 il est donc basé sur l'application du formulaire VCL avecunique minuterie 20ms dessus. Vous pouvez ignorer tous les éléments de la VCL (la seule chose qui est utilisée, c’est le chargeur de bitmap et j’ai confiance que vous l’avez déjà) et utiliser uniquement le code d’événement dont vous avez besoin.

//---------------------------------------------------------------------------
#include <vcl.h>
#include <Math.h>
#include <gl/gl.h>
#include <gl/glu.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
// key codes (Arrows + Space), pressed state
WORD key_left =37; bool _left =false;
WORD key_right=39; bool _right=false;
WORD key_up   =38; bool _up   =false;
WORD key_down =40; bool _down =false;
WORD key_reset=32; bool _reset=false;
//---------------------------------------------------------------------------
GLfloat rep[16],inv[16]; // camera matrix and its pseudo inverse
void pseudo_inverse(GLfloat *a,GLfloat *b)  // a = inverse(b)
{
// this works only for orthonormal matrices with origin (0,0,0) and no projections
a[ 0]=b[ 0]; a[ 4]=b[ 1]; a[ 8]=b[ 2]; a[12]=b[ 3];
a[ 1]=b[ 4]; a[ 5]=b[ 5]; a[ 9]=b[ 6]; a[13]=b[ 7];
a[ 2]=b[ 8]; a[ 6]=b[ 9]; a[10]=b[10]; a[14]=b[11];
a[ 3]=b[12]; a[ 7]=b[13]; a[11]=b[14]; a[15]=b[15];
}
//---------------------------------------------------------------------------
const int nb=64;        // slices
const int na=nb<<1;     // points per equator
const int _skybox_textures=4;
class skybox
{
public:
bool _init;             // has been initiated ?
GLfloat pos[na][nb][3]; // vertex
GLfloat txr[na][nb][2]; // texcoord
GLuint  txrid[_skybox_textures]; // texture ids
skybox() { _init=false; }
~skybox() { if (_init) glDeleteTextures(_skybox_textures,txrid); }
void init();        // call after OpenGL is already working !!!
void draw();
};
void skybox::init()
{
if (!_init) { _init=true; glGenTextures(_skybox_textures,txrid); }
GLfloat x,y,z,a,b,da,db,r=99.9;
GLfloat tx0,tdx,ty0,tdy;// just correction if CLAMP_TO_EDGE is not available
int ia,ib;

// a,b to texture coordinate system
tx0=0.0;
ty0=0.5;
tdx=0.5/M_PI;
tdy=1.0/M_PI;

// load textures to GPU memory
Graphics::TBitmap *bmp=new Graphics::TBitmap;   // new bmp
#ifndef GL_CLAMP_TO_EDGE
#define GL_CLAMP_TO_EDGE 0x812F
#endif
for (int i=0;i<_skybox_textures;i++)
{
Byte q;
unsigned int *pp;
int xs,ys,x,y,adr,*txr;
union { unsigned int c32; Byte db[4]; } c;
// load bmp from file
if (i==0) bmp->LoadFromFile("skybox_grid.bmp");
else if (i==1) bmp->LoadFromFile("skybox_sectors.bmp");
else if (i==2) bmp->LoadFromFile("skybox_figures.bmp");
else if (i==3) bmp->LoadFromFile("skybox_stars.bmp");
else break;
bmp->HandleType=bmDIB;      // allow direct access to pixels
bmp->PixelFormat=pf32bit;   // set pixel to 32bit so int is the same size as pixel
xs=bmp->Width;              // resolution should be power of 2
ys=bmp->Height;
txr=new int[xs*ys];         // create 1D txr[] array and store texture in it in GL manner
for(adr=0,y=0;y<ys;y++)
{
pp=(unsigned int*)bmp->ScanLine[y];
for(x=0;x<xs;x++,adr++)
{
// rgb2bgr and copy bmp -> txr[]
c.c32=pp[x];
q      =c.db[2];
c.db[2]=c.db[0];
c.db[0]=q;
txr[adr]=c.c32;
}
}
glEnable(GL_TEXTURE_2D);    // copy txr[] to GL
glBindTexture(GL_TEXTURE_2D,txrid[i]);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_MODULATE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, xs, ys, 0, GL_RGBA, GL_UNSIGNED_BYTE, txr);
glDisable(GL_TEXTURE_2D);
delete[] txr;               // release memory
}
delete bmp;
// generate sphere mesh
da=(2.0*M_PI)/GLfloat(na-1);
db=     M_PI /GLfloat(nb-1);
for (ib=0,b=-0.5*M_PI;ib<nb;ib++,b+=db)
for (ia=0,a= 0.0     ;ia<na;ia++,a+=da)
{
x=cos(b)*cos(a);
y=cos(b)*sin(a);
z=sin(b);
pos[ia][ib][0]=r*x;
pos[ia][ib][1]=r*y;
pos[ia][ib][2]=r*z;
txr[ia][ib][0]=tx0+(a*tdx);
txr[ia][ib][1]=ty0+(b*tdy);
}
}
void skybox::draw()
{
if (!_init) return;
int i,ia,ib0,ib1;
// color table
GLfloat col[_skybox_textures][3]=
{
// R   G   B
{ 0.3,0.2,0.4 },    // Ra,Dec grid
{ 0.0,0.2,0.3 },    // sectors
{ 0.0,0.3,0.4 },    // figures
{ 1.0,1.0,1.0 },    // stars
};
// modlevie = inverse of camera matrix to allow local coordinate system rotations
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadMatrixf(inv);
// set rendering pipeline
glDisable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR);
// render mesh once per each texture layer (stars are last)
for (i=0;i<_skybox_textures;i++)
{
glBindTexture(GL_TEXTURE_2D,txrid[i]);
glColor3fv(col[i]);
for (ib0=0,ib1=1;ib1<nb;ib0=ib1,ib1++)
{
glBegin(GL_QUAD_STRIP);
for (ia=0;ia<na;ia++)
{
glTexCoord2fv(txr[ia][ib0]);
glVertex3fv  (pos[ia][ib0]);
glTexCoord2fv(txr[ia][ib1]);
glVertex3fv  (pos[ia][ib1]);
}
glEnd();
}
}
// restore states ...
glEnable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
//---------------------------------------------------------------------------
skybox sky;
//---------------------------------------------------------------------------
int TForm1::ogl_init()
{
if (ogl_inicialized) return 1;
hdc = GetDC(Form1->Handle);             // get device context
PIXELFORMATDESCRIPTOR pfd;
ZeroMemory( &pfd, sizeof( pfd ) );      // set the pixel format for the DC
pfd.nSize = sizeof( pfd );
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 24;
pfd.iLayerType = PFD_MAIN_PLANE;
SetPixelFormat(hdc,ChoosePixelFormat(hdc, &pfd),&pfd);
hrc = wglCreateContext(hdc);            // create current rendering context
if(hrc == NULL)
{
ShowMessage("Could not initialize OpenGL Rendering context !!!");
ogl_inicialized=0;
return 0;
}
if(wglMakeCurrent(hdc, hrc) == false)
{
ShowMessage("Could not make current OpenGL Rendering context !!!");
wglDeleteContext(hrc);          // destroy rendering context
ogl_inicialized=0;
return 0;
}
ogl_resize();
glEnable(GL_DEPTH_TEST);                // Zbuf
glDisable(GL_CULL_FACE);                // vynechavaj odvratene steny
glDisable(GL_TEXTURE_2D);               // pouzivaj textury, farbu pouzivaj z textury
glDisable(GL_BLEND);                    // priehladnost
glShadeModel(GL_SMOOTH);                // gourard shading
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);   // background color
ogl_inicialized=1;

return 1;
}
//---------------------------------------------------------------------------
void TForm1::ogl_exit()
{
if (!ogl_inicialized) return;
wglMakeCurrent(NULL, NULL);     // release current rendering context
wglDeleteContext(hrc);          // destroy rendering context
ogl_inicialized=0;
}
//---------------------------------------------------------------------------
void TForm1::ogl_draw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

sky.draw();

glFlush();
SwapBuffers(hdc);
}
//---------------------------------------------------------------------------
void TForm1::ogl_resize()
{
xs=ClientWidth;
ys=ClientHeight;
if (xs<=0) xs = 1;                  // Prevent a divide by zero
if (ys<=0) ys = 1;
if (!ogl_inicialized) return;
glViewport(0,0,xs,ys);              // Set Viewport to window dimensions
glMatrixMode(GL_PROJECTION);        // operacie s projekcnou maticou
glLoadIdentity();                   // jednotkova matica projekcie
gluPerspective(60,float(xs)/float(ys),0.1,100.0); // matica=perspektiva,120 stupnov premieta z viewsize do 0.1
glMatrixMode(GL_TEXTURE);           // operacie s texturovou maticou
glLoadIdentity();                   // jednotkova matica textury
glMatrixMode(GL_MODELVIEW);         // operacie s modelovou maticou
glLoadIdentity();                   // jednotkova matica modelu (objektu)
ogl_draw();
}
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner)
{
ogl_inicialized=0;
hdc=NULL;
hrc=NULL;
ogl_init();
sky.init();
int i;  // unit matrices at start
for (i=0;i<16;i++) rep[i]=0.0;
for (i=0;i<16;i+=5) rep[i]=1.0;
for (i=0;i<16;i++) inv[i]=rep[i];
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)   { ogl_exit(); }
void __fastcall TForm1::FormResize(TObject *Sender)    { ogl_resize(); }
void __fastcall TForm1::Splitter1Moved(TObject *Sender){ ogl_resize(); }
void __fastcall TForm1::FormPaint(TObject *Sender)     { ogl_draw(); }
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
GLfloat da=5.0; // angular turn speed in [deg/timer_iteration]
pseudo_inverse(inv,rep);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadMatrixf(rep);
bool _redraw=false;
if (_left ) { _redraw=true; glRotatef(+da,0.0,1.0,0.0); }
if (_right) { _redraw=true; glRotatef(-da,0.0,1.0,0.0); }
if (_up   ) { _redraw=true; glRotatef(+da,1.0,0.0,0.0); }
if (_down ) { _redraw=true; glRotatef(-da,1.0,0.0,0.0); }
if (_reset) { _redraw=true; glLoadIdentity(); }
if (_redraw)
{
glGetFloatv(GL_MODELVIEW_MATRIX,rep);
pseudo_inverse(inv,rep);
}
glPopMatrix();
if (_redraw) ogl_draw();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormKeyUp(TObject *Sender, WORD &Key, TShiftState Shift)
{
if (Key==key_left ) _left =false;
if (Key==key_right) _right=false;
if (Key==key_up   ) _up   =false;
if (Key==key_down ) _down =false;
if (Key==key_reset) _reset=false;
Key=0;  // key is handled
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
// on key down event
if (Key==key_left ) _left =true;
if (Key==key_right) _right=true;
if (Key==key_up   ) _up   =true;
if (Key==key_down ) _down =true;
if (Key==key_reset) _reset=true;
Key=0;  // key is handled
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormActivate(TObject *Sender)
{
_left =false; // clear key flags after focus change
_right=false; // just to avoid constantly "pressed" keys
_up   =false; // after window focus swaping during key press
_down =false; // many games are ignoring this and you need to
_reset=false; // press&release the stuck key again to stop movement ...
}
//---------------------------------------------------------------------------

Ici démo compilée et source complète avec les textures incluses

Le contrôle s'effectue via les flèches du clavier et l'espace. Maintenant, il ne reste plus qu’à jouer avec les couleurs, à mélanger les fonctions, etc. L’exemple n’utilise que OpenGL 1.0 sans extension (sauf le CLAMP_TO_EDGE).

Vous pouvez échanger plusieurs fois le rendu en un seul passage avec MultiTexturing avec les fonctions de combinaison appropriées, mais je n’utilise pas cette fonctionnalité pendant longtemps (car je passe à GLSL au lieu de cela) donc je ne suis pas confiant pour ajouter un code pour cela.

S'amuser.