Earth3D.cpp
上传用户:lbr_007
上传日期:2019-05-31
资源大小:282k
文件大小:28k
- // ogl3d.cpp
- //
- #include "stdafx.h"
- #include "earth3d.h"
- #include <math.h>
- #include <vector>
- #include <arraycontainer.h>
- #include <geo.h>
- namespace E3D {
- const INT32 BaseMapList = 111;
- const INT32 OverlayList = 112;
- const INT32 HeaderList = 113;
- const INT32 PickList = 114;
- const INT32 AircraftList = 115;
- const UINT32 CellSize = 8; // 8x8 rectangles
- const UINT32 PickCellSize = 2;
- const double hdrSize = 0.2;
- const double AircraftLength = 0.000050;
- }
- class V3D {
- public:
- double x;
- double y;
- double z;
- V3D(void){ x = y = z = 0.0;}
- V3D(const V3D& v){ x = y = z = 0.0; Copy(v);}
- V3D(double * p){ x = p[0]; y = p[1]; z = p[2];}
- ~V3D(void){}
- void Create(double x1, double x2, double x3){ x = x1; y = x2; z = x3;}
- void Create(double * p){ x = p[0]; y = p[1]; z = p[2];}
- void Copy(const V3D& v)
- {
- x = v.x;
- y = v.y;
- z = v.z;
- }
- V3D& operator = (const V3D& v)
- {
- Copy(v);
- return *this;
- }
- void Init(void){ x = y = z = 0.0;}
- };
- //
- // arbitrary rotation of the point p theta radians around the axis r to
- // produce the point q
- //
- void ArbitraryRotate(V3D& p, double theta, V3D& r, V3D& q)
- {
- double costheta,sintheta;
- costheta = cos(theta);
- sintheta = sin(theta);
- q.x = (costheta + (1 - costheta) * r.x * r.x) * p.x;
- q.x += ((1 - costheta) * r.x * r.y - r.z * sintheta) * p.y;
- q.x += ((1 - costheta) * r.x * r.z + r.y * sintheta) * p.z;
- q.y = ((1 - costheta) * r.x * r.y + r.z * sintheta) * p.x;
- q.y += (costheta + (1 - costheta) * r.y * r.y) * p.y;
- q.y += ((1 - costheta) * r.y * r.z - r.x * sintheta) * p.z;
- q.z = ((1 - costheta) * r.x * r.z - r.y * sintheta) * p.x;
- q.z += ((1 - costheta) * r.y * r.z + r.x * sintheta) * p.y;
- q.z += (costheta + (1 - costheta) * r.z * r.z) * p.z;
- }
- void GEOTex::CreateTexture(DIBSection& dib, UTMProjection * pj)
- {
- UINT32 width = dib.Width();
- UINT32 height = dib.Height();
- UINT32 w, h;
- if (width >= 1024) w = 1024;
- else if (width >= 512) w = 512;
- else if (width >= 256) w = 256;
- else if (width >= 128) w = 128;
- else if (width >= 64) w = 64;
- else if (width >= 32) w = 32;
- else w = 16;
- if (height >= 1024) h = 1024;
- else if (height >= 512) h = 512;
- else if (height >= 256) h = 256;
- else if (height >= 128) h = 128;
- else if (height >= 64) h = 64;
- else if (height >= 32) h = 32;
- else h = 16;
- DIBSection tmpDIB;
- dib.ResizeImage(tmpDIB, w, h);
- UINT32 totalSize = w * h * 3; // 24-bit
- m_imgData.CreateArray(totalSize);
- memcpy(m_imgData.GetData(), tmpDIB.GetBits(), totalSize);
- m_hScale = (double)width / (double)w;
- m_vScale = (double)height / (double)h;
- m_gr = dib.GetConstGeoReference();
- m_pj = pj;
- m_texWidth = w;
- m_texHeight = h;
- }
- void GEOTex::DrawTexture(void)
- {
- }
- Earth3D::Earth3D(void)
- {
- InitEarth3D();
- }
- Earth3D::~Earth3D(void)
- {
- }
- void Earth3D::GeoToXYZ(double lat, double lon, double& x, double& y, double& z, double R)
- {
- //
- // its necessary to use the negative of the longitude because the OpenGL
- // (x,y,z) coordinate system is essentially backwards from the lat/long coordinate system
- // where we assume negative longitudes mean west and positive means eastern hemisphere
- //
- x = R * cos((-lon*GEO::DE2RA)) * cos((lat*GEO::DE2RA));
- y = R * sin((lat*GEO::DE2RA));
- z = R * sin((-lon*GEO::DE2RA)) * cos((lat*GEO::DE2RA));
- }
- void Earth3D::SetGeoImage(DIBSection * dib, UTMProjection * pj)
- {
- m_gt.CreateTexture(*dib, pj);
- double x1, y1;
- double EL = m_model_matrix.XRot();
- double elev = m_eyeDist * sin(EL * GEO::DE2RA);
- double southLat, southLon, eastLat, eastLon, M;
- double southPt[3], eastPt[3];
- x1 = m_gt.m_gr.m_tieX + (m_gt.m_gr.m_resX * (m_gt.m_gr.m_cols/2.0));
- y1 = m_gt.m_gr.m_tieY - (m_gt.m_gr.m_resY * (m_gt.m_gr.m_rows/2.0));
- m_gt.m_pj->inverse(x1,y1,m_centerLat,m_centerLon);
- m_eyeDist = 1.5 * sqrt((y1 - m_gt.m_gr.m_tieY)*(y1 - m_gt.m_gr.m_tieY)) / 1000.0;
- GeoToXYZ(m_centerLat, m_centerLon, m_centerPt[0], m_centerPt[1], m_centerPt[2]);
- // setting up the rectangular block at the northern extent of the
- // image that says "North"
- m_northHdr.Create(64, 32, 24);
- CRect r;
- m_northHdr.GetDC()->DrawText("North", -1, &r, DT_CALCRECT);
- m_northHdr.GetDC()->PatBlt(0,0,64,32,WHITENESS);
- m_northHdr.GetDC()->TextOut(32-r.Width()/2, 16, "North", 5);
- // calculate south and eastern coordinates
- GeoCalc::GCDistanceAzimuth(m_centerLat, m_centerLon, m_eyeDist, 180, southLat, southLon);
- GeoCalc::GCDistanceAzimuth(m_centerLat, m_centerLon, m_eyeDist, 90, eastLat, eastLon);
- // calculate southern and eastern points in the model coordinate system
- GeoToXYZ(southLat,southLon, southPt[0],southPt[1],southPt[2]);
- GeoToXYZ(eastLat,eastLon, eastPt[0],eastPt[1],eastPt[2]);
- // make unitSouthPt a unit vector in the southern direction (model coord sys)
- m_unitSouthPt[0] = southPt[0] - m_centerPt[0];
- m_unitSouthPt[1] = southPt[1] - m_centerPt[1];
- m_unitSouthPt[2] = southPt[2] - m_centerPt[2];
- M = sqrt(m_unitSouthPt[0]*m_unitSouthPt[0] + m_unitSouthPt[1]*m_unitSouthPt[1] +
- m_unitSouthPt[2]*m_unitSouthPt[2]);
- m_unitSouthPt[0] /= M;
- m_unitSouthPt[1] /= M;
- m_unitSouthPt[2] /= M;
- // make unitEastPt a unit vector in the eastern direction (model coord sys)
- m_unitEastPt[0] = eastPt[0] - m_centerPt[0];
- m_unitEastPt[1] = eastPt[1] - m_centerPt[1];
- m_unitEastPt[2] = eastPt[2] - m_centerPt[2];
- M = sqrt(m_unitEastPt[0]*m_unitEastPt[0] + m_unitEastPt[1]*m_unitEastPt[1] +
- m_unitEastPt[2]*m_unitEastPt[2]);
- m_unitEastPt[0] /= M;
- m_unitEastPt[1] /= M;
- m_unitEastPt[2] /= M;
- // make unitCenterPt a unit vector pointing from the origin to the center point
- // (model coord sys)
- m_unitCenterPt[0] = m_centerPt[0];
- m_unitCenterPt[1] = m_centerPt[1];
- m_unitCenterPt[2] = m_centerPt[2];
- M = sqrt(m_centerPt[0]*m_centerPt[0] + m_centerPt[1]*m_centerPt[1] +
- m_centerPt[2]*m_centerPt[2]);
- m_unitCenterPt[0] /= M;
- m_unitCenterPt[1] /= M;
- m_unitCenterPt[2] /= M;
- }
- void Earth3D::SetOrientation(void)
- {
- if (m_flyMode && m_flyFirstPerson)
- {
- //
- // if we're flying then the orientation is simple: our eye point is the
- // current fly point and we're looking at the next fly point, our up
- // vector is the next fly point
- //
- gluLookAt(m_flyPt[0], m_flyPt[1], m_flyPt[2],
- m_flyTo[0], m_flyTo[1], m_flyTo[2],
- m_flyTo[0], m_flyTo[1], m_flyTo[2]);
- }
- else
- {
- double upVec[3];
- // dividing by the Earth radius essentially scales from a world
- // coordinate system to this OpenGL coordinate system where the
- // radius of the Earth equals 1.0
- double D = (m_eyeDist / m_model_matrix.XScale())/GEO::ERAD;
- V3D p(m_unitSouthPt);
- V3D u(m_unitCenterPt);
- V3D q, v, w, x;
- // rotate the south vector around the center vector
- ArbitraryRotate(p,(-m_model_matrix.YRot())*GEO::DE2RA,u,q);
- v.Create(m_unitEastPt);
- // rotate the east vector around the center vector
- ArbitraryRotate(v,(-m_model_matrix.YRot())*GEO::DE2RA,u,w);
- p = q;
- // rotate the (formerly) south vector around the (formerly) east vector
- ArbitraryRotate(p,-m_model_matrix.XRot()*GEO::DE2RA,w,q);
- // calculate the eye point
- m_eyePt[0] = m_centerPt[0] + D * q.x;
- m_eyePt[1] = m_centerPt[1] + D * q.y;
- m_eyePt[2] = m_centerPt[2] + D * q.z;
- p.Create(m_unitCenterPt);
- // rotate the center vector around the (formerly) east vector
- ArbitraryRotate(p,-m_model_matrix.XRot()*GEO::DE2RA,w,q);
- upVec[0] = q.x;
- upVec[1] = q.y;
- upVec[2] = q.z;
- gluLookAt( m_eyePt[0], m_eyePt[1], m_eyePt[2],
- m_centerPt[0], m_centerPt[1], m_centerPt[2],
- upVec[0], upVec[1], upVec[2]);
- }
- }
- void RenderCylinder(double * startPt, double * endPt, double r = 0.0000075, UINT32 steps = 100)
- {
- if (steps > 1)
- {
- int i, j;
- double d[3], n[3], c1[3], c2[3], u[3], v[3], w[3];
- double dIncr[3], angle1, D, N;
- d[0] = endPt[0] - startPt[0];
- d[1] = endPt[1] - startPt[1];
- d[2] = endPt[2] - startPt[2];
- D = sqrt(d[0]*d[0] + d[1]*d[1] + d[2]*d[2]);
- dIncr[0] = (endPt[0] - startPt[0]) / (double)(steps - 1);
- dIncr[1] = (endPt[1] - startPt[1]) / (double)(steps - 1);
- dIncr[2] = (endPt[2] - startPt[2]) / (double)(steps - 1);
- n[0] = (endPt[1]*startPt[2] - endPt[2]*startPt[1]);
- n[1] = (endPt[2]*startPt[0] - endPt[0]*startPt[2]);
- n[2] = (endPt[0]*startPt[1] - endPt[1]*startPt[0]);
- // making the n-vector a unit vector
- N = sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);
- n[0] /= N;
- n[1] /= N;
- n[2] /= N;
- n[0] *= r;
- n[1] *= r;
- n[2] *= r;
- const int numAngles = 36;
- double perp[numAngles][3];
- V3D p, t, q;
- p.x = n[0]; p.y = n[1]; p.z = n[2];
- t.x = d[0]/D; t.y = d[1]/D; t.z = d[2]/D;
- double dTheta = 360.0 / (numAngles - 1);
- for (i = 0; i < numAngles; i++){
- angle1 = (double)i*dTheta;
- ArbitraryRotate(p,angle1*GEO::DE2RA,t,q);
- perp[i][0] = q.x;
- perp[i][1] = q.y;
- perp[i][2] = q.z;
- }
- glBegin( GL_TRIANGLES );
- for (j = 0; j < (steps - 1); j++){
- c1[0] = startPt[0] + (double)j * dIncr[0];
- c1[1] = startPt[1] + (double)j * dIncr[1];
- c1[2] = startPt[2] + (double)j * dIncr[2];
- c2[0] = startPt[0] + (double)(j+1) * dIncr[0];
- c2[1] = startPt[1] + (double)(j+1) * dIncr[1];
- c2[2] = startPt[2] + (double)(j+1) * dIncr[2];
- for (i = 0; i < (numAngles-1); i++){
- u[0] = c1[0] + perp[i][0];
- u[1] = c1[1] + perp[i][1];
- u[2] = c1[2] + perp[i][2];
- v[0] = c2[0] + perp[i][0];
- v[1] = c2[1] + perp[i][1];
- v[2] = c2[2] + perp[i][2];
- w[0] = c1[0] + perp[i+1][0];
- w[1] = c1[1] + perp[i+1][1];
- w[2] = c1[2] + perp[i+1][2];
- glNormal3dv(perp[i]);
- glVertex3dv(u);
- glVertex3dv(v);
- glVertex3dv(w);
- u[0] = c2[0] + perp[i+1][0];
- u[1] = c2[1] + perp[i+1][1];
- u[2] = c2[2] + perp[i+1][2];
- glNormal3dv(perp[i+1]);
- glVertex3dv(w);
- glVertex3dv(v);
- glVertex3dv(u);
- }
- }
- glEnd();
- }
- }
- void Earth3D::SetTexture(DIBSection& dib)
- {
- if (dib.IsCreated())
- {
- GenTexture(dib);
- }
- }
- void Earth3D::GenTexture(DIBSection& dib)
- {
- UINT32 width = dib.Width();
- UINT32 height = dib.Height();
- int w, h;
- UINT32 max_dimension = width > height ? width : height;
- if (width >= 512) w = 512;
- else if (width >= 256) w = 256;
- else if (width >= 128) w = 128;
- else if (width >= 64) w = 64;
- else if (width >= 32) w = 32;
- else w = 16;
- if (height >= 512) h = 512;
- else if (height >= 256) h = 256;
- else if (height >= 128) h = 128;
- else if (height >= 64) h = 64;
- else if (height >= 32) h = 32;
- else h = 16;
- dib.ResizeImage(m_texture_dib,w,h);
- }
- void Earth3D::RenderPrimaryImage(void)
- {
- glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
- if (m_pickMode)
- {
- glCallList( E3D::PickList );
- m_pickPoint = false;
- if (m_dib.IsCreated())
- {
- COLORREF clr;
- m_dib.GetPixel(m_pickX, m_pickY, clr);
- INT32 horzCells = (m_gt.m_texWidth - E3D::PickCellSize)/E3D::PickCellSize;
- INT32 vertCells = (m_gt.m_texHeight - E3D::PickCellSize)/E3D::PickCellSize;
-
- INT32 row = clr / horzCells;
- INT32 col = clr - (row * horzCells);
- if ((row >= 0) && (row < vertCells) && (col >= 0) && (col < horzCells))
- {
- double x = m_gt.m_gr.m_tieX + (double)col * m_gt.m_gr.m_resX * m_gt.m_hScale*E3D::PickCellSize;
- x += m_gt.m_gr.m_tieX + (double)(col+E3D::PickCellSize) * m_gt.m_gr.m_resX * m_gt.m_hScale*E3D::PickCellSize;
- x /= 2.0;
- double y = m_gt.m_gr.m_tieY - (double)row * m_gt.m_gr.m_resY * m_gt.m_vScale*E3D::PickCellSize;
- y += m_gt.m_gr.m_tieY - (double)(row+E3D::PickCellSize) * m_gt.m_gr.m_resY * m_gt.m_vScale*E3D::PickCellSize;
- y /= 2.0;
- m_gt.m_pj->inverse(x,y,m_pickLat,m_pickLon);
- m_pickPoint = true;
- }
- }
- }
- else
- {
- if (m_flyMode)
- {
- RenderDirectionHeaders(m_northHdr, 0);
- RenderEarthImage(); // shows the earth underneath image
- RenderGEOImage();
- if (!m_flyFirstPerson)
- {
- RenderAircraftImage();
- }
- }
- else
- {
- RenderPickImage();
- RenderDirectionHeaders(m_northHdr, 0);
- RenderEarthImage(); // shows the earth underneath image
- RenderGEOImage();
- }
- }
- }
- void Earth3D::SetFlyPosition(double u[3], double v[3], bool firstPerson)
- {
- m_flyPt[0] = u[0];
- m_flyPt[1] = u[1];
- m_flyPt[2] = u[2];
- m_flyTo[0] = v[0];
- m_flyTo[1] = v[1];
- m_flyTo[2] = v[2];
- m_flyFirstPerson = firstPerson;
- }
- void Earth3D::RenderGEOImage(void)
- {
- if (m_gt.IsCreated() && m_gt.m_pj)
- {
- if (m_rebuildTexture)
- {
- glNewList( E3D::OverlayList, GL_COMPILE);
- UINT32 row, col;
- double x1, x2, y1, y2;
- double lat[4], lon[4];
- GLdouble u[3], v[3], w[3], n[3], tx1, tx2, ty1, ty2;
- GLdouble R = 1.0000;
- glColor3ub(32,32,32);
-
- glTexImage2D(GL_TEXTURE_2D,0,3, m_gt.m_texWidth, m_gt.m_texHeight,
- 0,GL_BGR_EXT,GL_UNSIGNED_BYTE,(GLvoid *)m_gt.m_imgData.GetData());
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
- glEnable( GL_TEXTURE_2D );
- {
- glBegin( GL_TRIANGLES );
- {
- //
- // Notes:
- // 1. each texture mapping point is like a spot weld so
- // most of the time we don't need to texture map every point,
- // instead we will break up the image into 2D cells.
- // 2. all four points of the cell must be un-projected for
- // accuracy...inverting a projection is slow...another reason
- // we don't want to texture map every point.
- // 3. each cell will be broken into 2 triangles and we have to be
- // careful that the normal vector for the 2 triangles are both
- // pointing the same direction and that direction must be up.
- // 4. one optimization i use below is to re-use the v & w points
- // from the first triangle in the second triangle because those
- // points are used in both. you may be able to come up with much
- // more re-use of points and improve performance of this code, but
- // keep in mind we are only building an OpenGL call list here so
- // this code does not get executed on each and every re-draw, the
- // non-opengl code only gets executed when this model is re-built.
- // this fact pushes us more towards using high resolution up to the
- // point that we are creating too much opengl code.
- // 5. set the texture coordinate before setting the vertex. the
- // texture coordinate is handled like a state when the vertex coordinates
- // get set.
- // 6. upper left texture coordinate is (1.0,1.0) as you go right and down
- // the texture coordinate moves towards (0.0, 0.0)
- //
- for (row = 0; row < (m_gt.m_texHeight - E3D::CellSize); row += E3D::CellSize){
- //
- // x1, y1, x2, y2 are based off the coordinate system of the
- // original geotiff image
- //
- y1 = m_gt.m_gr.m_tieY - m_gt.m_gr.m_resY * ((double)row * m_gt.m_vScale);
- y2 = m_gt.m_gr.m_tieY - m_gt.m_gr.m_resY * ((double)(row+E3D::CellSize) * m_gt.m_vScale);
- //
- // tx1, ty1, tx2, ty2 are based off the image data that was re-sized to
- // meet OpenGL requirements for image dimensions that are powers of two.
- //
- ty1 = 1.0 - (double)row/(double)m_gt.m_texHeight;
- ty2 = 1.0 - (double)(row + E3D::CellSize)/(double)m_gt.m_texHeight;
-
- for (col = 0; col < (m_gt.m_texWidth - E3D::CellSize); col += E3D::CellSize){
- x1 = m_gt.m_gr.m_tieX + m_gt.m_gr.m_resX * ((double)col * m_gt.m_hScale);
- x2 = m_gt.m_gr.m_tieX + m_gt.m_gr.m_resX * ((double)(col + E3D::CellSize) * m_gt.m_hScale);
- tx1 = (double)col/(double)(m_gt.m_texWidth);
- tx2 = (double)(col + E3D::CellSize)/(double)(m_gt.m_texWidth);
- //
- // going clockwise around this rectangle for inverse projections
- //
- m_gt.m_pj->inverse( x1, y1, lat[0], lon[0]);
- m_gt.m_pj->inverse( x2, y1, lat[1], lon[1]);
- m_gt.m_pj->inverse( x1, y2, lat[2], lon[2]);
- m_gt.m_pj->inverse( x2, y2, lat[3], lon[3]);
- GeoToXYZ(lat[0],lon[0],u[0],u[1],u[2]);
- GeoToXYZ(lat[1],lon[1],v[0],v[1],v[2]);
- GeoToXYZ(lat[2],lon[2],w[0],w[1],w[2]);
- //
- // i'm switching the order of the coordinates u,w,v instead of
- // u,v,w so that we get counter-clockwise direction. using the right
- // hand rule this means that the normal vector will point up. here
- // we do upper-left, lower-left, upper-right
- //
- NormalVector(u,w,v,n);
-
- glNormal3dv(n);
- glTexCoord2d(tx1, ty1);
- glVertex3dv(u);
- glTexCoord2d(tx1, ty2);
- glVertex3dv(w);
- glTexCoord2d(tx2, ty1);
- glVertex3dv(v);
- GeoToXYZ(lat[3],lon[3],u[0],u[1],u[2]);
- //
- // again, we want to go counter clockwise for the second triangle
- // (the lower right triangle) to keep our normal vector going up.
- // so we want the latitude & longitude of points lower-left then
- // lower-right, then upper-right...and this completes our cell.
- //
- NormalVector(w,u,v,n);
- glNormal3dv(n);
- glTexCoord2d(tx1, ty2);
- glVertex3dv(w);
- glTexCoord2d(tx2, ty2);
- glVertex3dv(u);
- glTexCoord2d(tx2, ty1);
- glVertex3dv(v);
- }
- }
- }
- glEnd();
- }
- glDisable( GL_TEXTURE_2D );
- glEndList();
- m_rebuildTexture = false;
- }
- glCallList( E3D::OverlayList );
- }
- }
- void Earth3D::RenderAircraftImage(void)
- {
- glPushMatrix();
- {
- //
- // we're going to draw a simple aircraft made up of
- // 3 triangles: a fuselage, wings, and rudder. First
- // we have to get unit vectors for the aircraft's orientation
- // and direction.
- //
- GLdouble u[3], v[3], w[3], n1[3], n2[3], n3[3], norm[3], m;
- u[0] = m_flyTo[0] - m_flyPt[0];
- u[1] = m_flyTo[1] - m_flyPt[1];
- u[2] = m_flyTo[2] - m_flyPt[2];
- m = sqrt(u[0]*u[0] + u[1]*u[1] + u[2]*u[2]);
- // u is the unit vector for the direction of the aircraft
- u[0] /= m;
- u[1] /= m;
- u[2] /= m;
- v[0] = m_flyPt[0];
- v[1] = m_flyPt[1];
- v[2] = m_flyPt[2];
- m = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
- // v is the unit vector pointing up
- v[0] /= m;
- v[1] /= m;
- v[2] /= m;
- // cross product of the up vector and the forward vector should
- // the vector to the left wing.
- w[0] = v[1]*u[2] - v[2]*u[1];
- w[1] = v[2]*u[0] - v[0]*u[2];
- w[2] = v[0]*u[1] - v[1]*u[0];
- m = sqrt(w[0]*w[0] + w[1]*w[1] + w[2]*w[2]);
- // w is the unit vector from the flight point to the left wing
- w[0] /= m;
- w[1] /= m;
- w[2] /= m;
- glTranslated( m_flyTo[0], m_flyTo[1], m_flyTo[2]);
- //if (m_buildAircraft)
- //{
- //glNewList( E3D::AircraftList, GL_COMPILE);
- //m_buildAircraft = false;
- glBegin( GL_TRIANGLES );
- {
- glColor3ub(64,64,224); // light blue...i think???
- // first six vertices will be the aircraft fuselage
- n1[0] = E3D::AircraftLength*u[0];
- n1[1] = E3D::AircraftLength*u[1];
- n1[2] = E3D::AircraftLength*u[2];
- n2[0] = E3D::AircraftLength*w[0]*0.20;
- n2[1] = E3D::AircraftLength*w[1]*0.20;
- n2[2] = E3D::AircraftLength*w[2]*0.20;
-
- n3[0] = E3D::AircraftLength*u[0]*0.20;
- n3[1] = E3D::AircraftLength*u[1]*0.20;
- n3[2] = E3D::AircraftLength*u[2]*0.20;
- NormalVector(n1,n2,n3,norm);
- glNormal3dv(norm);
- glVertex3dv(n1);
- glVertex3dv(n2);
- glVertex3dv(n3);
- n1[0] = E3D::AircraftLength*u[0];
- n1[1] = E3D::AircraftLength*u[1];
- n1[2] = E3D::AircraftLength*u[2];
- n2[0] = E3D::AircraftLength*(-w[0])*0.20;
- n2[1] = E3D::AircraftLength*(-w[1])*0.20;
- n2[2] = E3D::AircraftLength*(-w[2])*0.20;
- NormalVector(n1,n3,n2,norm);
- glNormal3dv(norm);
- glVertex3dv(n1);
- glVertex3dv(n3);
- glVertex3dv(n2);
- // next lets do the wings
- glColor3ub(64,64,128);
- n1[0] = E3D::AircraftLength*u[0]*0.75;
- n1[1] = E3D::AircraftLength*u[1]*0.75;
- n1[2] = E3D::AircraftLength*u[2]*0.75;
- n2[0] = -E3D::AircraftLength*w[0]*0.50 + E3D::AircraftLength*u[0]*0.20;
- n2[1] = -E3D::AircraftLength*w[1]*0.50 + E3D::AircraftLength*u[1]*0.20;
- n2[2] = -E3D::AircraftLength*w[2]*0.50 + E3D::AircraftLength*u[2]*0.20;
- n3[0] = E3D::AircraftLength*(w[0])*0.50 + E3D::AircraftLength*u[0]*0.20;
- n3[1] = E3D::AircraftLength*(w[1])*0.50 + E3D::AircraftLength*u[1]*0.20;
- n3[2] = E3D::AircraftLength*(w[2])*0.50 + E3D::AircraftLength*u[2]*0.20;
- NormalVector(n1,n2,n3,norm);
- glNormal3dv(norm);
- glVertex3dv(n1);
- glVertex3dv(n2);
- glVertex3dv(n3);
- // next lets do the rudders
- glColor3ub(192,192,192);
- n1[0] = E3D::AircraftLength*u[0]*0.50;
- n1[1] = E3D::AircraftLength*u[1]*0.50;
- n1[2] = E3D::AircraftLength*u[2]*0.50;
- n2[0] = 0.0;
- n2[1] = 0.0;
- n2[2] = 0.0;
- n3[0] = E3D::AircraftLength*v[0]*0.15;
- n3[1] = E3D::AircraftLength*v[1]*0.15;
- n3[2] = E3D::AircraftLength*v[2]*0.15;
- NormalVector(n1,n2,n3,norm);
- glNormal3dv(norm);
- glVertex3dv(n1);
- glVertex3dv(n2);
- glVertex3dv(n3);
- }
- glEnd();
- //glEndList();
- //}
- //else
- //{
- // glCallList( E3D::AircraftList );
- //}
- }
- glPopMatrix();
- }
- void Earth3D::RenderPickImage(void)
- {
- if (m_gt.IsCreated() && m_gt.m_pj)
- {
- if (m_rebuildTexture)
- {
- glNewList( E3D::PickList, GL_COMPILE);
- glShadeModel(GL_FLAT);
- glDisable(GL_LIGHT0);
- glDisable(GL_LIGHTING);
- glDisable( GL_TEXTURE_2D );
- UINT32 row, col;
- double x1, x2, y1, y2;
- double lat[4], lon[4];
- GLdouble u[3], v[3], w[3];
- COLORREF clr = 0;
- glBegin( GL_TRIANGLES );
- {
- for (row = 0; row < (m_gt.m_texHeight - E3D::PickCellSize); row+=E3D::PickCellSize){
- //
- // x1, y1, x2, y2 are based off the coordinate system of the
- // original geotiff image
- //
- y1 = m_gt.m_gr.m_tieY - m_gt.m_gr.m_resY * ((double)row * m_gt.m_vScale);
- y2 = m_gt.m_gr.m_tieY - m_gt.m_gr.m_resY * ((double)(row+E3D::PickCellSize) * m_gt.m_vScale);
-
- for (col = 0; col < (m_gt.m_texWidth - E3D::PickCellSize); col+=E3D::PickCellSize){
- x1 = m_gt.m_gr.m_tieX + m_gt.m_gr.m_resX * ((double)col * m_gt.m_hScale);
- x2 = m_gt.m_gr.m_tieX + m_gt.m_gr.m_resX * ((double)(col + E3D::PickCellSize) * m_gt.m_hScale);
- //
- // going clockwise around this rectangle for inverse projections
- //
- m_gt.m_pj->inverse( x1, y1, lat[0], lon[0]);
- m_gt.m_pj->inverse( x2, y1, lat[1], lon[1]);
- m_gt.m_pj->inverse( x1, y2, lat[2], lon[2]);
- m_gt.m_pj->inverse( x2, y2, lat[3], lon[3]);
- GeoToXYZ(lat[0],lon[0],u[0],u[1],u[2]);
- GeoToXYZ(lat[1],lon[1],v[0],v[1],v[2]);
- GeoToXYZ(lat[2],lon[2],w[0],w[1],w[2]);
- glColor3ub(GetRValue(clr),GetGValue(clr),GetBValue(clr));
- clr++;
- glVertex3dv(u);
- glVertex3dv(w);
- glVertex3dv(v);
- GeoToXYZ(lat[3],lon[3],u[0],u[1],u[2]);
- glVertex3dv(w);
- glVertex3dv(u);
- glVertex3dv(v);
- }
- }
- }
- glEnd();
- glEndList();
- }
- }
- }
- void Earth3D::RenderDirectionHeaders(DIBSection& dib, int direction)
- {
- if (m_gt.IsCreated() && m_gt.m_pj)
- {
- if (m_rebuildTexture)
- {
- glNewList( E3D::HeaderList, GL_COMPILE);
- double x1, x2, y1, y2;
- double lat[4], lon[4];
- GLdouble u[3], v[3], w[3], n[3], e1[3], e2[3];
- GLdouble R = 1.0;
-
- glTexImage2D(GL_TEXTURE_2D,0,3, dib.Width(), dib.Height(),
- 0,GL_BGR_EXT,GL_UNSIGNED_BYTE,(GLvoid *)dib.GetBits());
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
- glEnable( GL_TEXTURE_2D );
- {
- glBegin( GL_TRIANGLES );
- {
- x1 = m_gt.m_gr.m_tieX;
- x2 = x1 + m_gt.m_gr.m_resX * m_gt.m_gr.m_cols;
- y1 = m_gt.m_gr.m_tieY;
- y2 = y1 - m_gt.m_gr.m_resY * m_gt.m_gr.m_rows;
- m_gt.m_pj->inverse( x1, y1, lat[0], lon[0]);
- m_gt.m_pj->inverse( x2, y1, lat[1], lon[1]);
- m_gt.m_pj->inverse( x1, y2, lat[2], lon[2]);
- m_gt.m_pj->inverse( x2, y2, lat[3], lon[3]);
- NormalVector(u,w,v,n);
- glNormal3dv(n);
- switch (direction){
- case 0: // north
- {
- GeoToXYZ(lat[0], lon[0],u[0],u[1],u[2]);
- GeoToXYZ(lat[1], lon[1],v[0],v[1],v[2]);
- GeoToXYZ(lat[2], lon[2],w[0],w[1],w[2]);
- glTexCoord2d(0.0, 0.0);
- glVertex3dv(u);
- glTexCoord2d(1.0, 0.0);
- glVertex3dv(v);
- e1[0] = u[0] + E3D::hdrSize * (u[0] - w[0]);
- e1[1] = u[1] + E3D::hdrSize * (u[1] - w[1]);
- e1[2] = u[2] + E3D::hdrSize * (u[2] - w[2]);
- GeoToXYZ(lat[3], lon[3],w[0],w[1],w[2]);
- e2[0] = v[0] + E3D::hdrSize * (v[0] - w[0]);
- e2[1] = v[1] + E3D::hdrSize * (v[1] - w[1]);
- e2[2] = v[2] + E3D::hdrSize * (v[2] - w[2]);
- glTexCoord2d(1.0, 1.0);
- glVertex3dv(e2);
- glTexCoord2d(0.0, 0.0);
- glVertex3dv(u);
- glTexCoord2d(1.0, 1.0);
- glVertex3dv(e2);
- glTexCoord2d(0.0, 1.0);
- glVertex3dv(e1);
- }
- break;
- case 1: // south
- {
- }
- break;
- case 2: // east
- {
- }
- break;
- case 3: // west
- {
- }
- break;
- }
- }
- glEnd();
- }
- glDisable( GL_TEXTURE_2D );
- glEndList();
- }
- glCallList( E3D::HeaderList );
- }
- }
- void Earth3D::RenderEarthImage(void)
- {
- if (m_rebuildEarth)
- {
- glNewList( E3D::BaseMapList, GL_COMPILE);
- const int NumLatitudes = 90;
- const int NumLongitudes = 180;
- double start_lat, start_lon;
- double theta1, phi1, theta2, phi2, lat_incr, lon_incr;
- GLdouble u[3], v[3], w[3], n[3];
- GLdouble R;
- glColor3ub(224,224,224);
- /*
- if (m_texture_dib.IsCreated())
- {
- glTexImage2D(GL_TEXTURE_2D,0,3,m_texture_dib.Width(),m_texture_dib.Height(),
- 0,GL_BGR_EXT,GL_UNSIGNED_BYTE,(GLvoid *)m_texture_dib.GetBits());
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
- glEnable( GL_TEXTURE_2D );
- }
- else
- {
- glDisable( GL_TEXTURE_2D );
- }
- */
- start_lat = -90.0;
- start_lon = -180.0;
- R = 1.0;
- lat_incr = 180.0 / (double)NumLatitudes;
- lon_incr = 360.0 / (double)NumLongitudes;
- int row, col;
- //GLdouble tx1, tx2, ty1, ty2;
- glBegin( GL_TRIANGLES );
- {
- for (col = 0; col < NumLongitudes; col++){
- phi1 = (start_lon + col * lon_incr);
- phi2 = (start_lon + (col + 1) * lon_incr);
- //tx1 = (180.0 + phi1)/360.0;
- //tx2 = (180.0 + phi2)/360.0;
- for (row = 0; row < NumLatitudes; row++){
- theta1 = (start_lat + row * lat_incr);
- theta2 = (start_lat + (row + 1) * lat_incr);
- //ty1 = (90.0 + theta1)/180.0;
- //ty2 = (90.0 + theta2)/180.0;
- GeoToXYZ(theta1,phi1,u[0],u[1],u[2]);
- GeoToXYZ(theta2,phi1,v[0],v[1],v[2]);
- GeoToXYZ(theta2,phi2,w[0],w[1],w[2]);
- NormalVector(u,v,w,n);
- glNormal3dv(n);
- //glTexCoord2d(tx1,ty1);
- glVertex3dv(u);
- //glTexCoord2d(tx1,ty2);
- glVertex3dv(v);
- //glTexCoord2d(tx2,ty2);
- glVertex3dv(w);
- GeoToXYZ(theta1,phi2,v[0],v[1],v[2]);
- NormalVector(u,w,v,n);
- glNormal3dv(n);
- //glTexCoord2d(tx1,ty1);
- glVertex3dv(u);
- //glTexCoord2d(tx2,ty2);
- glVertex3dv(w);
- //glTexCoord2d(tx2,ty1);
- glVertex3dv(v);
- }
- }
- }
- glEnd();
- //glDisable( GL_TEXTURE_2D );
- glEndList();
- m_rebuildEarth = false;
- }
- glCallList( E3D::BaseMapList );
- }