numberOfVertices = ((180 / step) + 1) * ((360 / step) + 1)
numberOfIndices = 2 * (numberOfVertices - (360 / step) - 1)
class CScene {
private :
enum {
step = 8,
numberOfVertices = ((180 / step) + 1) * ((360 / step) + 1),
numberOfIndices = 2 * (numberOfVertices - (360 / step) - 1)
}; // enum
struct {
GLfloat x,y,z; //
} m_vertices[numberOfVertices]; //
GLuint m_indices[numberOfIndices]; //
...
}; // class CScene
CScene::CScene( void ) {
///
const GLfloat fRadius = 1.0;
for ( int alpha = 90, index = 0; alpha <= 270; alpha += step) {
const int angleOfVertical = alpha % 360;
for ( int phi = 0; phi <= 360; phi += step, ++index) {
const int angleOfHorizontal = phi % 360;
///
m_vertices[index].x = fRadius * g_tableOfCosines[angleOfVertical] * g_tableOfCosines[angleOfHorizontal];
m_vertices[index].y = fRadius * g_tableOfSinus[angleOfVertical];
m_vertices[index].z = fRadius * g_tableOfCosines[angleOfVertical] * g_tableOfSinus[angleOfHorizontal];
} // for
} // for
///
for ( int index = 0; index < numberOfIndices; index += 2) {
m_indices[index] = index >> 1;
m_indices[index + 1] = m_indices[index] + (360 / step) + 1;
} // for
} // constructor CScene
inline void CScene::InitArrays( void ) {
const GLsizei stride = 3 * sizeof (GLfloat);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, stride, m_vertices);
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, stride, m_vertices);
} // InitArrays
inline void CScene::InitLights( void ) {
const GLfloat pos[] = {1.0, 1.0, 1.0, 0.0};
const GLfloat clr[] = {1.0, 1.0, 1.0, 1.0};
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, pos);
glLightfv(GL_LIGHT0, GL_DIFFUSE, clr);
glLightfv(GL_LIGHT0, GL_SPECULAR, clr);
} // InitLights
void CScene::Init( const int _nWidth, const int _nHeight) {
//
glViewport(0, 0, _nWidth, _nHeight);
///
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(80.0, (GLdouble)_nWidth / (GLdouble)_nHeight, 0.1, 3.0);
///
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( 0.0,1.5,1.5, 0.0,0.0,0.0, 0.0,1.0,0.0);
///
glCullFace(GL_FRONT);
glEnable(GL_CULL_FACE);
//
glEnable(GL_DEPTH_TEST);
//
glEnable(GL_NORMALIZE);
//
glShadeModel(GL_SMOOTH);
// -
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
///
this ->InitLights();
glEnable(GL_LIGHTING);
// -
glClearColor(0.0, 0.0, 0.0, 1.0);
///
const GLfloat clr[] = {1.0, 1.0, 1.0, 1.0};
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, clr);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 50.0);
//
this ->InitArrays();
} // Init
inline void CScene::DrawEarth( void ) {
glDrawElements(GL_QUAD_STRIP, numberOfIndices, GL_UNSIGNED_INT, m_indices);
} // DrawEarth
void CScene::Redraw( void ) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
this ->DrawEarth();
glFinish();
} // Redraw
//
// Texture
//
IDR_TEXTURE_EARTH TEXTURE "Earth.jpg"
inline HBITMAP LoadTextureFromResource(HMODULE _hModule, LPCTSTR _lpName, LPCTSTR _lpType) {
HRSRC hRsrc = FindResource(_hModule, _lpName, _lpType);
if (NULL == hRsrc) return NULL;
HGLOBAL hGlobal = LoadResource(_hModule, hRsrc);
if (NULL == hGlobal) return NULL;
HBITMAP hBitmap = NULL;
DWORD dwSize = SizeofResource(_hModule, hRsrc);
HGLOBAL hData = GlobalAlloc(GMEM_MOVEABLE, dwSize);
CopyMemory(GlobalLock(hData), LockResource(hGlobal), dwSize);
GlobalUnlock(hData);
IStream *pStream = NULL;
HRESULT hr = CreateStreamOnHGlobal(hData, FALSE, &pStream);
if (SUCCEEDED(hr)) {
IPicture *pPicture = NULL;
hr = OleLoadPicture(pStream, dwSize, TRUE, IID_IPicture, (LPVOID*)&pPicture);
if (SUCCEEDED(hr)) {
pPicture->get_Handle((OLE_HANDLE *)&hBitmap);
hBitmap = (HBITMAP)CopyImage(hBitmap, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
pPicture->Release(); pPicture = NULL;
} // if
pStream->Release(); pStream = NULL;
} // if
GlobalFree(hData); hData = NULL;
UnlockResource(hGlobal); hGlobal = NULL;
return hBitmap;
} // LoadTextureFromResource
class CScene {
private :
...
struct {
GLfloat x,y,z; //
GLfloat u,v; //
} m_vertices[numberOfVertices]; //
...
struct {
GLuint id; //
HBITMAP hBitmap; //
} m_textureOfEarth;
...
}; // class CScene
CScene::CScene( void ) {
///
const GLfloat fRadius = 1.0;
for ( int alpha = 90, index = 0; alpha <= 270; alpha += step) {
const int angleOfVertical = alpha % 360;
for ( int phi = 0; phi <= 360; phi += step, ++index) {
const int angleOfHorizontal = phi % 360;
///
...
///
m_vertices[index].u = (360 - phi) / 360.0f;
m_vertices[index].v = (270 - alpha) / 180.0f;
} // for
} // for
///
...
///
HINSTANCE hModule = GetModuleHandle(NULL);
m_textureOfEarth.hBitmap = LoadTextureFromResource(hModule, MAKEINTRESOURCE(IDR_TEXTURE_EARTH), _T( "TEXTURE" ));
} // constructor CScene
CScene::~CScene( void ) {
///
if (NULL != m_textureOfEarth.hBitmap) {
DeleteObject(m_textureOfEarth.hBitmap);
} // if
} // destructor CScene
inline void CScene::InitArrays( void ) {
const GLsizei stride = 5 * sizeof (GLfloat);
...
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, stride, (GLfloat *)m_vertices + 3);
} // InitArrays
inline void CScene::InitTextures( void ) {
///
if (NULL != m_textureOfEarth.hBitmap) {
glGenTextures(1, &m_textureOfEarth.id);
glBindTexture(GL_TEXTURE_2D, m_textureOfEarth.id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
BITMAP bitmap = { 0 };
GetObject(m_textureOfEarth.hBitmap, sizeof (BITMAP), &bitmap);
glTexImage2D(GL_TEXTURE_2D, 0, 3, bitmap.bmWidth, bitmap.bmHeight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, bitmap.bmBits);
} // if
} // InitTextures
void CScene::Init( const int _nWidth, const int _nHeight) {
...
//
this ->InitTextures();
//
glEnable(GL_TEXTURE_2D);
} // Init
inline void CScene::DrawEarth( void ) {
glBindTexture(GL_TEXTURE_2D, m_textureOfEarth.id);
glDrawElements(GL_QUAD_STRIP, numberOfIndices, GL_UNSIGNED_INT, m_indices);
} // DrawEarth
//
// Texture
//
IDR_TEXTURE_EARTH TEXTURE "Earth.jpg"
IDR_TEXTURE_BUMP TEXTURE "bump.jpg"
class CScene {
private :
...
struct {
GLuint id; //
HBITMAP hBitmap; //
} m_textureOfEarth, m_textureOfBump, m_textureOfBumpInvert;
...
}; // class CScene
...
CScene::CScene( void ) {
///
...
///
...
///
HINSTANCE hModule = GetModuleHandle(NULL);
m_textureOfEarth.hBitmap = LoadTextureFromResource(hModule, MAKEINTRESOURCE(IDR_TEXTURE_EARTH), _T( "TEXTURE" ));
m_textureOfBump.hBitmap = LoadTextureFromResource(hModule, MAKEINTRESOURCE(IDR_TEXTURE_BUMP), _T( "TEXTURE" ));
m_textureOfBumpInvert.hBitmap = LoadTextureFromResource(hModule, MAKEINTRESOURCE(IDR_TEXTURE_BUMP), _T( "TEXTURE" ));
if (NULL != m_textureOfBumpInvert.hBitmap) {
BITMAP bitmap = { 0 };
GetObject(m_textureOfBumpInvert.hBitmap, sizeof (BITMAP), &bitmap);
//
LPBYTE ptr = (LPBYTE)bitmap.bmBits + (3 * bitmap.bmHeight * bitmap.bmWidth);
while (--ptr >= bitmap.bmBits) (*ptr) = 0xFF - (*ptr);
} // if
} // constructor CScene
CScene::~CScene( void ) {
///
if (NULL != m_textureOfEarth.hBitmap) {
DeleteObject(m_textureOfEarth.hBitmap);
} // if
///
if (NULL != m_textureOfBump.hBitmap) {
DeleteObject(m_textureOfBump.hBitmap);
} // if
///
if (NULL != m_textureOfBumpInvert.hBitmap) {
DeleteObject(m_textureOfBumpInvert.hBitmap);
} // if
} // destructor CScene
inline void CScene::InitTextures( void ) {
///
if (NULL != m_textureOfEarth.hBitmap) {
...
} // if
///
if (NULL != m_textureOfBump.hBitmap) {
glGenTextures(1, &m_textureOfBump.id);
glBindTexture(GL_TEXTURE_2D, m_textureOfBump.id);
glPixelTransferf(GL_RED_SCALE, 0.5); // 50%,
glPixelTransferf(GL_GREEN_SCALE, 0.5); //
glPixelTransferf(GL_BLUE_SCALE, 0.5);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
BITMAP bitmap = { 0 };
GetObject(m_textureOfBump.hBitmap, sizeof (BITMAP), &bitmap);
glTexImage2D(GL_TEXTURE_2D, 0, 3, bitmap.bmWidth, bitmap.bmHeight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, bitmap.bmBits);
} // if
///
if (NULL != m_textureOfBumpInvert.hBitmap) {
glGenTextures(1, &m_textureOfBumpInvert.id);
glBindTexture(GL_TEXTURE_2D, m_textureOfBumpInvert.id);
glPixelTransferf(GL_RED_SCALE, 0.5); // 50%,
glPixelTransferf(GL_GREEN_SCALE, 0.5); //
glPixelTransferf(GL_BLUE_SCALE, 0.5);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
BITMAP bitmap = { 0 };
GetObject(m_textureOfBumpInvert.hBitmap, sizeof (BITMAP), &bitmap);
glTexImage2D(GL_TEXTURE_2D, 0, 3, bitmap.bmWidth, bitmap.bmHeight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, bitmap.bmBits);
} // if
} // InitTextures
glDisable(GL_BLEND);
glDisable(GL_LIGHTING);
glBlendFunc(GL_ONE, GL_ONE);
glDepthFunc(GL_LEQUAL);
glEnable(GL_BLEND);
glEnable(GL_LIGHTING);
glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
inline void CScene::DrawEarth( void ) {
///
glDisable(GL_BLEND);
glDisable(GL_LIGHTING);
glBindTexture(GL_TEXTURE_2D, m_textureOfBump.id);
glPushMatrix();
glScalef(0.99f, 0.99f, 0.99f);
glDrawElements(GL_QUAD_STRIP, numberOfIndices, GL_UNSIGNED_INT, m_indices);
glPopMatrix();
///
glBlendFunc(GL_ONE, GL_ONE);
glDepthFunc(GL_LEQUAL);
glEnable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, m_textureOfBumpInvert.id);
glPushMatrix();
glScalef(0.995f, 0.995f, 0.995f);
glDrawElements(GL_QUAD_STRIP, numberOfIndices, GL_UNSIGNED_INT, m_indices);
glPopMatrix();
///
glEnable(GL_LIGHTING);
glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
glBindTexture(GL_TEXTURE_2D, m_textureOfEarth.id);
glDrawElements(GL_QUAD_STRIP, numberOfIndices, GL_UNSIGNED_INT, m_indices);
} // DrawEarth
Source: https://habr.com/ru/post/77985/
All Articles