www.pudn.com > opengl_pick_sample.rar > ogl3d.cpp
// ogl3d.cpp // #include "stdafx.h" #include "ogl3d.h" #include "bmpreader.h" #include#include const int OGL3D_EARTH_LIST = 111; const int OGL3D_EARTH_LINES = 222; const int SOLAR_SYSTEM_LIST = 333; namespace GEO { const double PI = 3.14159265359; const double TWOPI = 6.28318530718; const double DE2RA = 0.01745329252; const double RA2DE = 57.2957795129; const double FLATTENING = 1.0/298.26; const double PIOVER2 = 1.570796326795; } OGL3D::OGL3D(void) { InitOGL3D(); } OGL3D::~OGL3D(void) { } void OGL3D::SetTexture(DIBSection& dib) { if (dib.IsCreated()) { GenTexture(dib); } } void OGL3D::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); if (m_texture_dib.IsCreated()) { m_have_texture = 1; } } void OGL3D::RenderPrimaryImage(void) { const int NumLatitudes = 36; const int NumLongitudes = 72; 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; if (!m_model_built) { glNewList( OGL3D_EARTH_LIST, GL_COMPILE); glColor3ub(0,0,224); if (m_have_texture) { 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); //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glEnable( GL_TEXTURE_2D ); } else { glDisable( GL_TEXTURE_2D ); } m_model_built = 1; if ( m_draw_mode == DrawLines ) { glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); } else { glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); } glBegin( GL_TRIANGLES ); start_lat = -90; start_lon = 0.0; R = 1.0; lat_incr = 180.0 / NumLatitudes; lon_incr = 360.0 / NumLongitudes; int row, col; for (col = 0; col < NumLongitudes; col++){ phi1 = (start_lon + col * lon_incr) * GEO::DE2RA; phi2 = (start_lon + (col + 1) * lon_incr) * GEO::DE2RA; for (row = 0; row < NumLatitudes; row++){ theta1 = (start_lat + row * lat_incr) * GEO::DE2RA; theta2 = (start_lat + (row + 1) * lat_incr) * GEO::DE2RA; u[0] = R * cos(phi1) * cos(theta1);//x u[1] = R * sin(theta1);//y u[2] = R * sin(phi1) * cos(theta1);//z v[0] = R * cos(phi1) * cos(theta2);//x v[1] = R * sin(theta2);//y v[2] = R * sin(phi1) * cos(theta2);//z w[0] = R * cos(phi2) * cos(theta2);//x w[1] = R * sin(theta2);//y w[2] = R * sin(phi2) * cos(theta2);//z NormalVector(u,v,w,n); glNormal3dv(n); glTexCoord2d((180.0 - phi1*GEO::RA2DE)/360.0,(theta1 + GEO::PIOVER2)*GEO::RA2DE/180.0); glVertex3dv(u); glTexCoord2d((180.0 - phi1*GEO::RA2DE)/360.0,(theta2 + GEO::PIOVER2)*GEO::RA2DE/180.0); glVertex3dv(v); glTexCoord2d((180.0 - phi2*GEO::RA2DE)/360.0,(theta2 + GEO::PIOVER2)*GEO::RA2DE/180.0); glVertex3dv(w); v[0] = R * cos(phi2) * cos(theta1);//x v[1] = R * sin(theta1);//y v[2] = R * sin(phi2) * cos(theta1);//z NormalVector(u,w,v,n); glNormal3dv(n); glTexCoord2d((180.0 - phi1*GEO::RA2DE)/360.0,(theta1 + GEO::PIOVER2)*GEO::RA2DE/180.0); glVertex3dv(u); glTexCoord2d((180.0 - phi2*GEO::RA2DE)/360.0,(theta2 + GEO::PIOVER2)*GEO::RA2DE/180.0); glVertex3dv(w); glTexCoord2d((180.0 - phi2*GEO::RA2DE)/360.0,(theta1 + GEO::PIOVER2)*GEO::RA2DE/180.0); glVertex3dv(v); } } glEnd(); if (m_have_texture) { glDisable( GL_TEXTURE_2D ); } GLView3D::RenderPrimaryImage(); glEndList(); } glCallList( OGL3D_EARTH_LIST ); } void SolarSystem3D::RenderSun(void) { } void SolarSystem3D::RenderMercury(void) { } void SolarSystem3D::RenderVenus(void) { } void SolarSystem3D::RenderEarth(void) { } void SolarSystem3D::RenderMars(void) { } void SolarSystem3D::RenderJupiter(void) { } void SolarSystem3D::RenderSaturn(void) { } void SolarSystem3D::RenderUranus(void) { } void SolarSystem3D::RenderNeptune(void) { } void SolarSystem3D::RenderPluto(void) { } SolarSystem3D::SolarSystem3D(void) { m_model_built = 0; m_draw_mode = OGL3D::DrawTriangles; DIBSection dib; ReadBMPFile("et.bmp",dib); GenTexture(dib,m_earth_texture); ReadBMPFile("mt.bmp",dib); GenTexture(dib,m_mars_texture); ReadBMPFile("jt.bmp",dib); GenTexture(dib,m_jupiter_texture); ReadBMPFile("st.bmp",dib); GenTexture(dib,m_saturn_texture); } SolarSystem3D::~SolarSystem3D(void) { } void SolarSystem3D::RenderTexturedSphere(DIBSection& dib, double radius) { 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 ); double start_lat = -90; double start_lon = 0.0; double R = radius; const int NumLatitudes = 36; const int NumLongitudes = 72; double lat_incr = 180.0 / NumLatitudes; double lon_incr = 360.0 / NumLongitudes; double phi1, phi2, theta1, theta2; GLdouble u[3], v[3], w[3], n[3]; int row, col; for (col = 0; col < NumLongitudes; col++){ phi1 = (start_lon + col * lon_incr) * GEO::DE2RA; phi2 = (start_lon + (col + 1) * lon_incr) * GEO::DE2RA; for (row = 0; row < NumLatitudes; row++){ theta1 = (start_lat + row * lat_incr) * GEO::DE2RA; theta2 = (start_lat + (row + 1) * lat_incr) * GEO::DE2RA; u[0] = R * cos(phi1) * cos(theta1);//x u[1] = R * sin(theta1);//y u[2] = R * sin(phi1) * cos(theta1);//z v[0] = R * cos(phi1) * cos(theta2);//x v[1] = R * sin(theta2);//y v[2] = R * sin(phi1) * cos(theta2);//z w[0] = R * cos(phi2) * cos(theta2);//x w[1] = R * sin(theta2);//y w[2] = R * sin(phi2) * cos(theta2);//z NormalVector(u,v,w,n); glNormal3dv(n); glTexCoord2d((180.0 - phi1*GEO::RA2DE)/360.0,(theta1 + GEO::PIOVER2)*GEO::RA2DE/180.0); glVertex3dv(u); glTexCoord2d((180.0 - phi1*GEO::RA2DE)/360.0,(theta2 + GEO::PIOVER2)*GEO::RA2DE/180.0); glVertex3dv(v); glTexCoord2d((180.0 - phi2*GEO::RA2DE)/360.0,(theta2 + GEO::PIOVER2)*GEO::RA2DE/180.0); glVertex3dv(w); v[0] = R * cos(phi2) * cos(theta1);//x v[1] = R * sin(theta1);//y v[2] = R * sin(phi2) * cos(theta1);//z NormalVector(u,w,v,n); glNormal3dv(n); glTexCoord2d((180.0 - phi1*GEO::RA2DE)/360.0,(theta1 + GEO::PIOVER2)*GEO::RA2DE/180.0); glVertex3dv(u); glTexCoord2d((180.0 - phi2*GEO::RA2DE)/360.0,(theta2 + GEO::PIOVER2)*GEO::RA2DE/180.0); glVertex3dv(w); glTexCoord2d((180.0 - phi2*GEO::RA2DE)/360.0,(theta1 + GEO::PIOVER2)*GEO::RA2DE/180.0); glVertex3dv(v); } } glDisable( GL_TEXTURE_2D ); glEnd(); } void SolarSystem3D::RenderColoredSphere(COLORREF cr, double radius) { glDisable( GL_TEXTURE_2D ); glBegin( GL_TRIANGLES ); glColor3ub(GetRValue(cr),GetGValue(cr),GetBValue(cr)); double start_lat = -90; double start_lon = 0.0; double R = radius; const int NumLatitudes = 18; const int NumLongitudes = 36; double lat_incr = 180.0 / NumLatitudes; double lon_incr = 360.0 / NumLongitudes; double phi1, phi2, theta1, theta2; GLdouble u[3], v[3], w[3], n[3]; int row, col; for (col = 0; col < NumLongitudes; col++){ phi1 = (start_lon + col * lon_incr) * GEO::DE2RA; phi2 = (start_lon + (col + 1) * lon_incr) * GEO::DE2RA; for (row = 0; row < NumLatitudes; row++){ theta1 = (start_lat + row * lat_incr) * GEO::DE2RA; theta2 = (start_lat + (row + 1) * lat_incr) * GEO::DE2RA; u[0] = R * cos(phi1) * cos(theta1);//x u[1] = R * sin(theta1);//y u[2] = R * sin(phi1) * cos(theta1);//z v[0] = R * cos(phi1) * cos(theta2);//x v[1] = R * sin(theta2);//y v[2] = R * sin(phi1) * cos(theta2);//z w[0] = R * cos(phi2) * cos(theta2);//x w[1] = R * sin(theta2);//y w[2] = R * sin(phi2) * cos(theta2);//z NormalVector(u,v,w,n); glNormal3dv(n); glVertex3dv(u); glVertex3dv(v); glVertex3dv(w); v[0] = R * cos(phi2) * cos(theta1);//x v[1] = R * sin(theta1);//y v[2] = R * sin(phi2) * cos(theta1);//z NormalVector(u,w,v,n); glNormal3dv(n); glVertex3dv(u); glVertex3dv(w); glVertex3dv(v); } } glEnd(); } void SolarSystem3D::GenTexture(DIBSection& dib, DIBSection& texture_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(texture_dib,w,h); } int SolarSystem3D::PickPlanet(int x, int y, CString& msg) { int result = -1; if ( m_draw_mode == OGL3D::DrawLines ) { glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); } else { glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); } glShadeModel(GL_FLAT); glDisable(GL_LIGHT0); glDisable(GL_LIGHTING); glClearColor((float)1.00,(float)1.00, (float)1.00,1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glTranslated(m_model_matrix.X(),m_model_matrix.Y(),m_model_matrix.Z()); glRotated(m_model_matrix.XRot(), 1.0, 0.0, 0.0); glRotated(m_model_matrix.YRot(), 0.0, 1.0, 0.0); glRotated(m_model_matrix.ZRot(), 0.0, 0.0, 1.0); glScaled(m_model_matrix.XScale(),m_model_matrix.YScale(),m_model_matrix.ZScale()); glScaled(0.40,0.40,0.40); COLORREF cr; std::vector colorVector; cr = 1; RenderColoredSphere(cr,0.55); colorVector.push_back(cr); glPushMatrix(); glRotated(90.0, 0.0, 1.0, 0.0); glTranslated(1.0,0.0,0.0); cr = 2; RenderColoredSphere(cr,0.10); colorVector.push_back(cr); glPopMatrix(); glPushMatrix(); glRotated(180.0, 0.0, 1.0, 0.0); glTranslated(1.5,0.0,0.0); cr = 3; RenderColoredSphere(cr,0.15); colorVector.push_back(cr); glPopMatrix(); glPushMatrix(); glRotated(270.0, 0.0, 1.0, 0.0); glTranslated(2.0,0.0,0.0); cr = 4; RenderColoredSphere(cr,0.20); colorVector.push_back(cr); glPopMatrix(); glPushMatrix(); glRotated(0.0, 0.0, 1.0, 0.0); glTranslated(2.5,0.0,0.0); cr = 5; RenderColoredSphere(cr,0.15); colorVector.push_back(cr); glPopMatrix(); glPushMatrix(); glRotated(45.0, 0.0, 1.0, 0.0); glTranslated(3.5,0.0,0.0); cr = 6; RenderColoredSphere(cr,0.40); colorVector.push_back(cr); glPopMatrix(); glPushMatrix(); glRotated(135.0, 0.0, 1.0, 0.0); glTranslated(4.5,0.0,0.0); cr = 7; RenderColoredSphere(cr,0.25); colorVector.push_back(cr); glPopMatrix(); glPushMatrix(); glRotated(225.0, 0.0, 1.0, 0.0); glTranslated(5.0,0.0,0.0); cr = 8; RenderColoredSphere(cr,0.15); colorVector.push_back(cr); glPopMatrix(); glPushMatrix(); glRotated(315.0, 0.0, 1.0, 0.0); glTranslated(5.5,0.0,0.0); cr = 9; RenderColoredSphere(cr,0.15); colorVector.push_back(cr); glPopMatrix(); glPushMatrix(); glRotated(15.0, 0.0, 1.0, 0.0); glTranslated(6.0,0.0,0.0); cr = 10; RenderColoredSphere(cr,0.15); colorVector.push_back(cr); glPopMatrix(); glPopMatrix(); cr = 0; m_dib.GetPixel(x,y,cr); msg = "missed"; char * planets[10] = {"Sun","Mercury","Venus","Earth","Mars", "Jupiter","Saturn","Uranus","Neptune","Pluto"}; int color_size = colorVector.size(); for (int i=0;i