Click here to Skip to main content
15,893,588 members
Articles / Desktop Programming / MFC

SolidGraph CAD System

Rate me:
Please Sign up or sign in to vote.
4.97/5 (78 votes)
12 Sep 20062 min read 375.7K   29.8K   209  
A SolidGraph CAD system source code.
#include "stdafx.h"
#include "background_xD.h"
#include "math.h"
#include <io.h>
#include <fcntl.h>
#include <gl\glu.h>

//-----------------------------------------------------------//
//                         public                            //
//-----------------------------------------------------------//

//-------------------------------------------------------------
//constructor
//public
#define FAR_CLIP 2000.0

CBackground::CBackground()
{
    m_depth = FAR_CLIP;
    m_row_num = 1;
    m_col_num = 1;

	m_corners[0].r = 0.2f;
	m_corners[0].g = 0.2f;
	m_corners[0].b = 0.6f;
	m_corners[0].a = 1.0f; 

	m_corners[1].r = 0.2f;
	m_corners[1].g = 0.2f;
	m_corners[1].b = 0.6f;
	m_corners[1].a = 1.0f; 

    m_corners[2].r = 0.9f;
    m_corners[2].g = 0.9f;
    m_corners[2].b = 1.0f;
    m_corners[2].a = 1.0f; 

    m_corners[3].r = 0.9f;
    m_corners[3].g = 0.9f;
    m_corners[3].b = 1.0f;
    m_corners[3].a = 1.0f; 
    
    m_mirror_type = MIRROR11;
    m_textureID = 0;
    m_texture_file.Empty();
}
//-------------------------------------------------------------
//destructor
//public
CBackground::~CBackground()
{
    if(m_textureID)
    {
        glDeleteTextures(1, &m_textureID);
        m_textureID = 0;
    }  
}
//-------------------------------------------------------------
//set background params	
//public
void CBackground::SetParams(SBACKGROUND_PARAMS *params)
{
    if(!params)        return;
    if(m_textureID)
    {
        glDeleteTextures(1, &m_textureID);
        m_textureID = 0;
    }  
    m_row_num = params->row_num;
    m_col_num = params->col_num;
    m_mirror_type = params->mirror_type;
    m_texture_file = params->texture_file;
    for( int i=0; i<4; i++)
    {
        m_corners[i].r = params->corner[i].r;
        m_corners[i].g = params->corner[i].g;
        m_corners[i].b = params->corner[i].b;
        m_corners[i].a = params->corner[i].a;
    }
}
//-------------------------------------------------------------
//get background params	
//public
void CBackground::GetParams(SBACKGROUND_PARAMS *params)
{
    if(!params)        return;
    params->row_num = m_row_num;
    params->col_num = m_col_num;
    params->mirror_type = m_mirror_type;
    params->texture_file = m_texture_file;
    for( int i=0; i<4; i++)
    {
        params->corner[i].r = m_corners[i].r;
        params->corner[i].g = m_corners[i].g;
        params->corner[i].b = m_corners[i].b;
        params->corner[i].a = m_corners[i].a;
    }
}
//-------------------------------------------------------------
//set z coordinate of the background
//this function is called in CScene::SetBackgroung(CBackground *background)
//public
void CBackground::SetDepth(float depth)
{
    m_depth = depth;
}
//-------------------------------------------------------------
//showing background
//called in CScene::Display()
//public
void CBackground::Display()
{
    int i, j;

    if(m_textureID==0 && !m_texture_file.IsEmpty())
    {
        CreateTexture();
        if(m_textureID==0)
        {    
            ASSERT(0);
            return;
        }
    }

    glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();
		
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	glOrtho(0, 1, 0, 1, 0, -(m_depth+1));
			
    glPushAttrib(GL_ENABLE_BIT| GL_TEXTURE_BIT | GL_POLYGON_BIT);
    glDisable(GL_CULL_FACE);
    glDisable(GL_BLEND);  
    glDisable(GL_LIGHTING);
    //if we have texture (*.bmp file) then show texture
	if(m_textureID)
    {
        bool vert_mirror_status=false;
	    bool hor_mirror_status=true;

        glBindTexture(GL_TEXTURE_2D, m_textureID);
	    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
			
	    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
        for(i=0; i<m_col_num; i++)
		{
			for(j=0; j<m_row_num; j++)
			{
				glBegin(GL_QUADS);
					if(!vert_mirror_status && !hor_mirror_status)
						glTexCoord2f(0.f,0.f);
					if(vert_mirror_status && !hor_mirror_status)
						glTexCoord2f(1.f,0.f);
					if(!vert_mirror_status && hor_mirror_status)
						glTexCoord2f(0.f,1.f);
					if(vert_mirror_status && hor_mirror_status)
						glTexCoord2f(1.f,1.f);
                    glVertex3f((float)i/(float)m_col_num, (float)(j+1)/(float)m_row_num, m_depth);
                    
					if(!vert_mirror_status && !hor_mirror_status)
						glTexCoord2f(1.f,0.f);
					if(vert_mirror_status && !hor_mirror_status)
						glTexCoord2f(0.f,0.f);
					if(!vert_mirror_status && hor_mirror_status)
						glTexCoord2f(1.f,1.f);
					if(vert_mirror_status && hor_mirror_status)
						glTexCoord2f(0.f,1.f);
    				glVertex3f((float)(i+1)/(float)m_col_num, (float)(j+1)/(float)m_row_num, m_depth);
                    

					if(!vert_mirror_status && !hor_mirror_status)
						glTexCoord2f(1.f,1.f);
					if(vert_mirror_status && !hor_mirror_status)
						glTexCoord2f(0.f,1.f);
					if(!vert_mirror_status && hor_mirror_status)
						glTexCoord2f(1.f,0.f);
					if(vert_mirror_status && hor_mirror_status)
						glTexCoord2f(0.f,0.f);
    				glVertex3f((float)(i+1)/(float)m_col_num, (float)j/(float)m_row_num, m_depth);
	
					if(!vert_mirror_status && !hor_mirror_status)
						glTexCoord2f(0.f,1.f);
					if(vert_mirror_status && !hor_mirror_status)
						glTexCoord2f(1.f,1.f);
					if(!vert_mirror_status && hor_mirror_status)
						glTexCoord2f(0.f,0.f);
					if(vert_mirror_status && hor_mirror_status)
						glTexCoord2f(1.f,0.f);
					glVertex3f((float)i/(float)m_col_num, (float)j/(float)m_row_num,m_depth);


				glEnd();
			
			    if(m_mirror_type == MIRROR01 || m_mirror_type == MIRROR11)
				    hor_mirror_status=!hor_mirror_status;
		    }
            if(m_mirror_type == MIRROR10 || m_mirror_type == MIRROR11)
			    vert_mirror_status=!vert_mirror_status;

            hor_mirror_status=true;
		}
	}
	else
	{
        bool vert_mirror_status=false;
	    bool hor_mirror_status=false;

        glEnable(GL_BLEND);
		glDisable(GL_TEXTURE_2D);

		for(i=0; i<m_col_num; i++)
		{
			for(j=0; j<m_row_num; j++)
			{
				glBegin(GL_QUADS);
			    	if(!vert_mirror_status && !hor_mirror_status)
			    		glColor4f(m_corners[0].r, m_corners[0].g, m_corners[0].b,1.0f);
			    	if(vert_mirror_status && !hor_mirror_status)
			    		glColor4f(m_corners[1].r, m_corners[1].g, m_corners[1].b,1.0f);
			    	if(vert_mirror_status && hor_mirror_status)
			    		glColor4f(m_corners[2].r, m_corners[2].g, m_corners[2].b,1.0f);
                    if(!vert_mirror_status && hor_mirror_status)
			    		glColor4f(m_corners[3].r, m_corners[3].g, m_corners[3].b,1.0f);
                    glVertex3f((float)i/(float)m_col_num, (float)(j+1)/(float)m_row_num,m_depth);
                    //glVertex2f((float)i/(float)m_col_num, (float)(j+1)/(float)m_row_num);
                
			    	if(vert_mirror_status && !hor_mirror_status)
			    		glColor4f(m_corners[0].r, m_corners[0].g, m_corners[0].b,1.0f);			
                    if(!vert_mirror_status && !hor_mirror_status)
			    		glColor4f(m_corners[1].r, m_corners[1].g, m_corners[1].b,1.0f);			
			    	if(!vert_mirror_status && hor_mirror_status)
			    		glColor4f(m_corners[2].r, m_corners[2].g, m_corners[2].b,1.0f);			
			    	if(vert_mirror_status && hor_mirror_status)
			    		glColor4f(m_corners[3].r, m_corners[3].g, m_corners[3].b,1.0f);		
			    	glVertex3f((float)(i+1)/(float)m_col_num, (float)(j+1)/(float)m_row_num,m_depth);
                    //glVertex2f((float)(i+1)/(float)m_col_num, (float)(j+1)/(float)m_row_num);
                    
                
			    	if(vert_mirror_status && hor_mirror_status)
			    		glColor4f(m_corners[0].r, m_corners[0].g, m_corners[0].b,1.0f);			
			    	if(!vert_mirror_status && hor_mirror_status)
			    		glColor4f(m_corners[1].r, m_corners[1].g, m_corners[1].b,1.0f);			
                    if(!vert_mirror_status && !hor_mirror_status)
			    		glColor4f(m_corners[2].r, m_corners[2].g, m_corners[2].b,1.0f);			
			    	if(vert_mirror_status && !hor_mirror_status)
			    		glColor4f(m_corners[3].r, m_corners[3].g, m_corners[3].b,1.0f);			
                    glVertex3f((float)(i+1)/(float)m_col_num, (float)j/(float)m_row_num,m_depth);
                    //glVertex2f((float)(i+1)/(float)m_col_num, (float)j/(float)m_row_num);
                
			    	if(!vert_mirror_status && hor_mirror_status)
			    		glColor4f(m_corners[0].r, m_corners[0].g, m_corners[0].b,1.0f);			
			    	if(vert_mirror_status && hor_mirror_status)
			    		glColor4f(m_corners[1].r, m_corners[1].g, m_corners[1].b,1.0f);				
			    	if(vert_mirror_status && !hor_mirror_status)
			    		glColor4f(m_corners[2].r, m_corners[2].g, m_corners[2].b,1.0f);			
                    if(!vert_mirror_status && !hor_mirror_status)
			    		glColor4f(m_corners[3].r, m_corners[3].g, m_corners[3].b,1.0f);	
                    glVertex3f((float)i/(float)m_col_num, (float)j/(float)m_row_num,m_depth);
                    //glVertex2f((float)i/(float)m_col_num, (float)j/(float)m_row_num);
    		    	
			    glEnd();
			
			    if(m_mirror_type == MIRROR01 || m_mirror_type == MIRROR11)
				    hor_mirror_status=!hor_mirror_status;
		    }
            if(m_mirror_type == MIRROR10 || m_mirror_type == MIRROR11)
			    vert_mirror_status=!vert_mirror_status;

            hor_mirror_status=false;
	    }
    }

	glPopAttrib();
	glPopMatrix();
		
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();
}

//-----------------------------------------------------------//
//                         private                           //
//-----------------------------------------------------------//

//creating background texture from *.bmp file
//private
bool CBackground::CreateTexture()
{
    if(m_texture_file.IsEmpty())
    {
        if(m_textureID)
        {
            glDeleteTextures(1, &m_textureID);
            m_textureID = 0;
        }
        return false;
    }

    if(m_textureID)
        if(m_textureID)
		    glDeleteTextures(1, &m_textureID);
  
    //glGenTextures(1, &m_textureID);
        m_textureID = 10067;

    ASSERT(m_textureID>0);
			
    int textuere_width;
    int texture_height;
    int tmp_width;
    int tmp_height;
    BYTE *pTexture = NULL;
    BYTE *pTmpData = NULL;
    char path[MAX_PATH];

    sprintf(path, "%s", (LPCTSTR) m_texture_file);
    
	pTmpData = LoadFromBmp(path, &tmp_width, &tmp_height);
				
	if(pTmpData)
	{
    	textuere_width=32;
		textuere_width = (int)pow((float)2.0f,(float)
			((log((float)tmp_width)/log(2.0f))+
				1.0-
				(log((float)m_col_num)/log(2.0f))));
		if(textuere_width<32)
		    textuere_width=32;
		if(textuere_width>1024)
			textuere_width=1024;

		texture_height=32;
		texture_height = (int)pow((float)2.0f,
			(float)((log((float)tmp_height)/log(2.0f))+1.0-(log((float)m_row_num)/log(2.0f))));
		if(texture_height<32)
		    texture_height=32;
		if(texture_height>1024)
			texture_height=1024;

		pTexture = new BYTE[texture_height*textuere_width*3];
		if(pTexture)
		{
		    gluScaleImage(GL_RGB, tmp_width, tmp_height, GL_UNSIGNED_BYTE, pTmpData, textuere_width, texture_height, GL_UNSIGNED_BYTE, pTexture);
			
            glBindTexture(GL_TEXTURE_2D, m_textureID);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textuere_width, texture_height, 0, GL_RGB, GL_UNSIGNED_BYTE, (GLubyte*) pTexture);
			delete[] pTmpData;
            delete[] pTexture;
		}
        else
        {
            return false;
        }
    }
    else
    {
        return false;
    }
    return true;
}
//-------------------------------------------------------------
//this function loads *.bmp file and returns width and height 
//pointer to the picture storage (rgbrgbrgb...), 
//size of this storage is bmpWidth*bmpHeight*3*sizeof(unsigned char)
//this memory shoud be free after using; 
//this function is used in CBackground::CreateTexture()
//private
unsigned char *CBackground::LoadFromBmp(char *filename, int* bmpWidth, int* bmpHeight)
{
    LPRGBQUAD   ptrToPalette;  
    char*       ptrToPixels;   
    long        bitmapRow, bitmapColumn;  
	LPBITMAPINFOHEADER PtrToBmpHdr;
	LPBITMAPFILEHEADER PtrToFileHdr;
	unsigned char *Texels;
	unsigned char *texture_pixels;

	int    size_texture;
	unsigned char *ptex;

	int    length;
	char  *texture_file;
	UINT  nBytesRead;
	int    fh;
	char errorstr[_MAX_PATH+25]="Can't open bmp file ";

   /* Open file for input: */
	if( (fh = _open(filename, _O_RDONLY )) == -1 )  
	{
		::MessageBox(NULL, strcat(errorstr,filename),"Error",MB_OK);
        return NULL;
	}
	length = _filelength(fh);

	texture_file = (char*)malloc(length);

	if(texture_file == NULL)
		::MessageBox(NULL, "Can not load picture. \nPicture is too large.","Error",MB_OK);

	if( ( nBytesRead = _read( fh, texture_file, length ) ) <= 0 ) 
	{
		_close( fh );
		::MessageBox(NULL, "Read texture file","Error",MB_OK);
		exit(-3);
	}
	_close( fh );

	PtrToFileHdr = (LPBITMAPFILEHEADER)texture_file;
	PtrToBmpHdr = (LPBITMAPINFOHEADER)(texture_file+sizeof(BITMAPFILEHEADER));
  
	if (!PtrToBmpHdr) 
	{
		DWORD err = GetLastError();
		goto ErrorExit;
	}

    Texels = (unsigned char *)malloc(PtrToBmpHdr->biWidth * 3);

    ptrToPalette = (LPRGBQUAD) ((LPSTR) PtrToBmpHdr + PtrToBmpHdr->biSize);
    ptrToPixels  = (char*) PtrToBmpHdr + (PtrToBmpHdr->biSize + 
                           PtrToBmpHdr->biClrUsed * sizeof(RGBQUAD));

	if ( PtrToBmpHdr->biBitCount == 4) 
	{
            ptrToPixels += ((PtrToBmpHdr->biHeight - 1) * (long )((PtrToBmpHdr->biWidth/2+3) & ~3));
	} 
	else 
	{
		if ( PtrToBmpHdr->biBitCount == 8) 
		{
            ptrToPixels += ((PtrToBmpHdr->biHeight - 1) * (long )((PtrToBmpHdr->biWidth+3) & ~3));
		} 
		else 
		{
			if ( PtrToBmpHdr->biBitCount == 24) 
			{
				ptrToPixels += ((PtrToBmpHdr->biHeight - 1) * (long )((PtrToBmpHdr->biWidth*3+3) & ~3));
			}
		}
	}
	size_texture = PtrToBmpHdr->biWidth*PtrToBmpHdr->biHeight;
	ptex = (unsigned char*)malloc(3*size_texture);
	if (ptex == NULL) 
	{
		goto ErrorExit;
	}

	*bmpWidth = PtrToBmpHdr->biWidth;
	*bmpHeight = PtrToBmpHdr->biHeight;
  /*if ( ((*bmpWidth-1) & *bmpWidth)||((*bmpHeight-1) & *bmpHeight) )
	  ::MessageBox(NULL, "Texture dimension has to be power of 2","Error",MB_OK);
  */  
	texture_pixels = ptex;

    for (bitmapRow = 0;  bitmapRow < PtrToBmpHdr->biHeight; bitmapRow++) 
	{
		LPSTR   rowPtr;
		rowPtr = (LPSTR)ptrToPixels;

        for (bitmapColumn = 0; bitmapColumn < PtrToBmpHdr->biWidth; ) 
		{
            unsigned char p;
			if ( PtrToBmpHdr->biBitCount == 4) 
			{
				p = *rowPtr;
				rowPtr++;
				Texels[bitmapColumn*3  ] = ptrToPalette[p>>4].rgbRed;
				Texels[bitmapColumn*3+1] = ptrToPalette[p>>4].rgbGreen;
				Texels[bitmapColumn*3+2] = ptrToPalette[p>>4].rgbBlue;
				bitmapColumn++;
				Texels[bitmapColumn*3  ] = ptrToPalette[p&0xf].rgbRed;
				Texels[bitmapColumn*3+1] = ptrToPalette[p&0xf].rgbGreen;
				Texels[bitmapColumn*3+2] = ptrToPalette[p&0xf].rgbBlue;
				bitmapColumn++;
			} 
			else 
				if ( PtrToBmpHdr->biBitCount == 8) 
				{
					p = *rowPtr;
					rowPtr++;
					Texels[bitmapColumn*3  ] = ptrToPalette[p].rgbRed;
					Texels[bitmapColumn*3+1] = ptrToPalette[p].rgbGreen;
					Texels[bitmapColumn*3+2] = ptrToPalette[p].rgbBlue;
					bitmapColumn++;
				} 
				else 
					if ( PtrToBmpHdr->biBitCount == 24) 
					{
						Texels[bitmapColumn*3+2] = *rowPtr++;
						Texels[bitmapColumn*3+1] = *rowPtr++;
						Texels[bitmapColumn*3  ] = *rowPtr++;
						bitmapColumn++;
					}
		}
        
		if (PtrToBmpHdr->biBitCount==4) 
		{
			ptrToPixels -= ((PtrToBmpHdr->biWidth >> 1)+3) & ~3;
		} 
		else 
		{
			if(PtrToBmpHdr->biBitCount==8) 
			{
				ptrToPixels -= (PtrToBmpHdr->biWidth+3) & ~3;
			} 
			else 
			{
				if(PtrToBmpHdr->biBitCount==24) 
				{
					ptrToPixels -= ((PtrToBmpHdr->biWidth*3+3) & ~3);
				}
			}
		}
		memcpy( ptex, &Texels[0], 3 * PtrToBmpHdr->biWidth);
		ptex += 3 * PtrToBmpHdr->biWidth;
    } 

	free(texture_file); 
	free(Texels);

	return texture_pixels;
    
	ErrorExit:
	free(texture_file);
	return NULL;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions