RenderView.cpp
上传用户:zbjingming
上传日期:2010-01-02
资源大小:2436k
文件大小:17k
- // RenderView.cpp
- #include "stdafx.h"
- #include "Tool.h"
- #include <string.h>
- #include <time.h>
- #include <math.h>
- #include "ToolDoc.h"
- #include "RenderView.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- extern void Render(void);
- // This is the holding space for the landscape colours.
- int WinWidth, WinHeigth;
- unsigned short int comp = 32; // Scale modifier.
- unsigned short int temp, texture_mapping = FALSE,
- land_fogging = TRUE, flat_shading = TRUE;
- float angle, Near, ex, ey, ez, cx, cy, cz;
- // Initial eye position and vector of sight.
- static GLfloat speed = 0;
- // The following code for mouse routines was contributed.
- // These are used for the motion function.
- #define FORWARD 1
- #define UP 2
- #define TURNLEFT 3
- #define LOOKUP 5
- // Mouse position and button.
- int oldmx = 0, oldmy = 0, mb;
- // CRenderView
- IMPLEMENT_DYNCREATE(CRenderView, CView)
- BEGIN_MESSAGE_MAP(CRenderView, CView)
- //{{AFX_MSG_MAP(CRenderView)
- ON_WM_DESTROY()
- ON_WM_SIZE()
- ON_WM_LBUTTONDOWN()
- ON_WM_LBUTTONUP()
- ON_WM_MOUSEMOVE()
- ON_WM_PAINT()
- ON_WM_CREATE()
- //}}AFX_MSG_MAP
- // Standard printing commands
- ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
- ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
- ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
- END_MESSAGE_MAP()
- // CRenderView construction/destruction
- CRenderView::CRenderView()
- {
- // OpenGL
- m_hGLContext = NULL;
- m_GLPixelIndex = 0;
-
- // Mouse
- m_LeftButtonDown = FALSE;
- m_RightButtonDown = FALSE;
- m_CursorRotation = AfxGetApp()->LoadCursor(IDC_CURSOR_ROTATION);
- // Colors
- CToolApp *pApp = (CToolApp *)AfxGetApp();
- m_ClearColorRed = GetRValue(pApp->m_OptionColorGlBack);
- m_ClearColorGreen = GetGValue(pApp->m_OptionColorGlBack);
- m_ClearColorBlue = GetBValue(pApp->m_OptionColorGlBack);
- ReadData();
- WinWidth=1000;
- WinHeigth=800;
- LoadAllTexture();
- InitLookAt();
- }
- //============================================
- // InitGeometry
- //============================================
- void CRenderView::InitGeometry(void)
- {
- GLfloat fogColor[4] = {0.75, 0.75, 1.0, 1.0};
- speed = 0;
- srand(224);
- srand((unsigned)time(NULL));
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glEnable(GL_DEPTH_TEST);
- glShadeModel(GL_FLAT);
- glFogi(GL_FOG_MODE, GL_LINEAR);
- glFogfv(GL_FOG_COLOR, fogColor);
- glFogf(GL_FOG_DENSITY, 0.8f);
- glFogf(GL_FOG_START, 400.0f);
- glFogf(GL_FOG_END, 500.0f);
- glClearColor(0.75f, 0.75f, 1.0f, 1.0f);
- }
- CRenderView::~CRenderView()
- {
- FreeAllTexture();
- freelist();
- }
- BOOL CRenderView::PreCreateWindow(CREATESTRUCT& cs)
- {
- return CView::PreCreateWindow(cs);
- }
- // CRenderView drawing
- void CRenderView::OnDraw(CDC* pDC)
- {
- }
- BOOL CRenderView::OnPreparePrinting(CPrintInfo* pInfo)
- {
- return DoPreparePrinting(pInfo);
- }
- void CRenderView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
- {
- }
- void CRenderView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
- {
- }
- // CRenderView diagnostics
- #ifdef _DEBUG
- void CRenderView::AssertValid() const
- {
- CView::AssertValid();
- }
- void CRenderView::Dump(CDumpContext& dc) const
- {
- CView::Dump(dc);
- }
- CToolDoc* CRenderView::GetDocument() // non-debug version is inline
- {
- if (m_pDocument){
- ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CToolDoc)));
- return (CToolDoc*)m_pDocument;
- }
- else return NULL;
- }
- #endif //_DEBUG
- // Create OpenGL rendering context
- int CRenderView::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
- if (CView::OnCreate(lpCreateStruct) == -1)
- return -1;
-
- HWND hWnd = GetSafeHwnd();
- HDC hDC = ::GetDC(hWnd);
- if(SetWindowPixelFormat(hDC)==FALSE)
- return 0;
-
- if(CreateViewGLContext(hDC)==FALSE)
- return 0;
-
- // Default mode
- glPolygonMode(GL_FRONT,GL_FILL);
- glPolygonMode(GL_BACK,GL_FILL);
- glShadeModel(GL_FLAT);
-
- // light must be disabled
- // while rendering the terrain
- // because it has no normal definition
- InitGeometry();
- glEnable(GL_TEXTURE_2D);
- glDisable(GL_LIGHTING);
- return 0;
- }
- BOOL CRenderView::SetWindowPixelFormat(HDC hDC)
- {
- PIXELFORMATDESCRIPTOR pixelDesc;
-
- pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
- pixelDesc.nVersion = 1;
-
- pixelDesc.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
- PFD_DOUBLEBUFFER | PFD_STEREO_DONTCARE;
-
- pixelDesc.iPixelType = PFD_TYPE_RGBA;
- pixelDesc.cColorBits = 32;
- pixelDesc.cRedBits = 8;
- pixelDesc.cRedShift = 16;
- pixelDesc.cGreenBits = 8;
- pixelDesc.cGreenShift = 8;
- pixelDesc.cBlueBits = 8;
- pixelDesc.cBlueShift = 0;
- pixelDesc.cAlphaBits = 0;
- pixelDesc.cAlphaShift = 0;
- pixelDesc.cAccumBits = 64;
- pixelDesc.cAccumRedBits = 16;
- pixelDesc.cAccumGreenBits = 16;
- pixelDesc.cAccumBlueBits = 16;
- pixelDesc.cAccumAlphaBits = 0;
- pixelDesc.cDepthBits = 32;
- pixelDesc.cStencilBits = 8;
- pixelDesc.cAuxBuffers = 0;
- pixelDesc.iLayerType = PFD_MAIN_PLANE;
- pixelDesc.bReserved = 0;
- pixelDesc.dwLayerMask = 0;
- pixelDesc.dwVisibleMask = 0;
- pixelDesc.dwDamageMask = 0;
-
- m_GLPixelIndex = ChoosePixelFormat(hDC,&pixelDesc);
- if(m_GLPixelIndex == 0) // Choose default
- {
- m_GLPixelIndex = 1;
- if(DescribePixelFormat(hDC,m_GLPixelIndex,
- sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==0)
- return FALSE;
- }
-
- if(!SetPixelFormat(hDC,m_GLPixelIndex,&pixelDesc))
- return FALSE;
-
- return TRUE;
- }
- // Create an OpenGL rendering context
- BOOL CRenderView::CreateViewGLContext(HDC hDC)
- {
- m_hGLContext = wglCreateContext(hDC);
-
- if(m_hGLContext==NULL)
- return FALSE;
-
- if(wglMakeCurrent(hDC,m_hGLContext)==FALSE)
- return FALSE;
-
- return TRUE;
- }
- // Cleanup every OpenGL rendering context
- void CRenderView::OnDestroy()
- {
- if(wglGetCurrentContext() != NULL)
- wglMakeCurrent(NULL,NULL);
-
- if(m_hGLContext != NULL)
- {
- wglDeleteContext(m_hGLContext);
- m_hGLContext = NULL;
- }
- CView::OnDestroy();
- }
- void CRenderView::OnSize(UINT nType, int cx, int cy)
- {
- CView::OnSize(nType, cx, cy);
-
- // Set OpenGL perspective, viewport and mode
- CSize size(cx,cy);
- double aspect;
- aspect = (cy == 0) ? (double)size.cx : (double)size.cx/(double)size.cy;
- glViewport(0, 0, (GLsizei) cx, (GLsizei) cy);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(60.0, (GLfloat) cx/(GLfloat) cy, 1.0f, 500.0f);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- gluLookAt (ex, ey, ez, cx, cy, cz, 0.0f, 1.0f, 0.0f);
- }
- void CRenderView::OnLButtonDown(UINT nFlags, CPoint point)
- {
- m_LeftButtonDown = TRUE;
- m_LeftDownPos = point;
- CView::OnLButtonDown(nFlags, point);
- }
- void CRenderView::OnLButtonUp(UINT nFlags,
- CPoint point)
- {
- m_LeftButtonDown = FALSE;
- CView::OnLButtonUp(nFlags, point);
- }
- void CRenderView::OnMouseMove(UINT nFlags, CPoint point)
- {
- switch(nFlags){
- case(MK_LBUTTON):
- MoveEye(FORWARD,(GLfloat)(oldmy-point.y)/5.0f,1);
- break;
- case(MK_RBUTTON):
- MoveEye(TURNLEFT, (GLfloat)(oldmx-point.x), 1);
- break;
- }
- oldmy = point.y;
- oldmx = point.x;
- Invalidate(FALSE);
- CView::OnMouseMove(nFlags, point);
- }
- void CRenderView::OnPaint()
- {
- // Device context for painting
- CPaintDC dc(this);
-
- // Useful in singledoc templates
- HWND hWnd = GetSafeHwnd();
- HDC hDC = ::GetDC(hWnd);
- wglMakeCurrent(hDC,m_hGLContext);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glClearColor(m_ClearColorRed,m_ClearColorGreen,m_ClearColorBlue,1.0f);
- glPushMatrix();
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- InitRenderWin();
- Render();
- // Double buffers
- SwapBuffers(hDC);
- }
- // Function that moves the eye or turns the angle of sight.
- // Updates scene if update != 0.
- void CRenderView::MoveEye(int type, GLfloat amount, int update)
- {
- GLfloat a;
- switch(type){
- case FORWARD:
- a = sqrt((cx-ex)*(cx-ex)+(cz-ez)*(cz-ez));
- ex = (amount*(cx-ex)+a*ex) / a;
- ez = (amount*(cz-ez)+a*ez) / a;
- cx = (amount*(cx-ex)+a*cx) / a;
- cz = (amount*(cz-ez)+a*cz) / a;
- break;
- case TURNLEFT:
- cx = (cx-ex)*(float)cos(amount/360.0f) + (cz-ez)*(float)sin(amount/360.0f)+ex;
- cz = (cz-ez)*(float)cos(amount/360.0f) - (cx-ex)*(float)sin(amount/360.0f)+ez;
- break;
- case UP:
- ey += amount;
- break;
- case LOOKUP:
- cy += amount;
- break;
- }
- if (update){
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- gluLookAt(ex, ey, ez, cx, cy, cz, 0.0f,1.0f,0.0f);
- }
- }
- TEXTURE_2D **TextureList;
- OBJECT *ObjectList; /* ObjectList[0]:isolated surfaces*/
- INT4S ObjectNum;
- char gEnergyFile[30];
- char sLookAtFN[100];
- char ImageName[30];
-
- void CRenderView::ReadData()
- {
- int i,j,l;
- FILE *fp;
- char stemp[100];
- POINT3D *plist;
- INT4U nAllVertexNum;
- INT4U *pchlist;
- strcpy(gEnergyFile,"room.ed");
- fp = fopen( gEnergyFile, "r" );
- if ( fp == NULL )
- {
- printf( "n Can not open energy data file:%sn", gEnergyFile);
- exit(0);
- }
- fseek( fp, 0, SEEK_SET);
-
- /****** read texture list ******/
- fscanf( fp, "%s", stemp);
- while( strcmp( stemp,"texnum" ) != 0) fscanf( fp, "%s", stemp);
- fscanf( fp, "%d", &texnum );
- TextureList = (TEXTURE_2D **)malloc( sizeof(TEXTURE_2D)*(texnum+1));
- for(i=1; i<=texnum; i++)
- {
- TextureList[i] = (TEXTURE_2D *)malloc( sizeof(TEXTURE_2D));
- fscanf( fp, "%s%s", TextureList[i]->fname, stemp );
- if ( strcmp( stemp,"REPEAT_TEXTURE" ) == 0)
- TextureList[i]->type = 1;
- else if ( strcmp( stemp,"CLAMP_TEXTURE" ) == 0)
- TextureList[i]->type = 0;
- }
- /****** Read object list ******/
- fscanf( fp, "%s", stemp);
- while( strcmp( stemp,"ObjectNum" ) != 0) fscanf(fp,"%s",stemp);
- fscanf( fp, "%ld", &ObjectNum);
- ObjectList = (OBJECT *)malloc( sizeof(OBJECT ) * ObjectNum);
- for(i = 0; i < ObjectNum; i ++ )
- {
- fscanf( fp, "%s", stemp);
- while( strcmp( stemp,"SurfaceNum" ) != 0) fscanf(fp,"%s",stemp);
- fscanf( fp, "%ld", &(ObjectList[i].SurfNum) );
- ObjectList[i].surflist = (SURFACE *)malloc( sizeof(SURFACE) * ObjectList[i].SurfNum);
- for(j = 0; j < ObjectList[i].SurfNum; j ++ )
- {
- /****** Read surface infor ******/
- fscanf( fp, "%s", stemp);
- while( strcmp( stemp,"TextureId" ) != 0) fscanf(fp,"%s",stemp);
- fscanf( fp, "%d", &(ObjectList[i].surflist[j].texId) );
- fscanf( fp, "%s", stemp);
- while( strcmp( stemp,"pointnum" ) != 0) fscanf(fp,"%s",stemp);
- fscanf( fp, "%d", &(ObjectList[i].surflist[j].pointn) );
- fscanf( fp, "%s", stemp);
- while( strcmp( stemp,"triangle" ) != 0) fscanf(fp,"%s",stemp);
- fscanf( fp, "%d", &(ObjectList[i].surflist[j].triangle) );
- fscanf( fp, "%s", stemp);
- while( strcmp( stemp,"quadrangle" ) != 0) fscanf(fp,"%s",stemp);
- fscanf( fp, "%d", &(ObjectList[i].surflist[j].quadric) );
-
- /****** Read point list ******/
- ObjectList[i].surflist[j].pointlist = (POINT3D*)malloc(sizeof(POINT3D) *
- ObjectList[i].surflist[j].pointn);
- plist = ObjectList[i].surflist[j].pointlist;
- for( l = 0; l < ObjectList[i].surflist[j].pointn ; l ++ )
- fscanf( fp, "%f%f%f%f%f%f%f%f",
- &(plist[l].r), &(plist[l].g), &(plist[l].b),
- &(plist[l].u), &(plist[l].v),
- &(plist[l].x), &(plist[l].y), &(plist[l].z) );
- /****** Read patchlist ******/
- nAllVertexNum = ObjectList[i].surflist[j].triangle * 3 +
- ObjectList[i].surflist[j].quadric *4 ;
- ObjectList[i].surflist[j].patchlist = (INT4U *)malloc( sizeof(INT4U) * nAllVertexNum);
- pchlist = ObjectList[i].surflist[j].patchlist;
- for( l = 0; l < nAllVertexNum; l ++ )
- fscanf( fp, "%ld", &(pchlist[l]) );
- }
-
- }
- fclose(fp);
- }
- void CRenderView::InitLookAt()
- {
- FILE *fp;
- strcpy(sLookAtFN,"room.lk");
- fp = fopen(sLookAtFN, "rb");
- if (fp == NULL)
- {
- ex = ey = ez =1.0f;
- cx = cy = cz =0.0f;
- Near = 0.1f;
- angle = 30.0f;
- }
- else fscanf(fp, "%f%f%f%f%f%f%f%f", &angle, &Near, &ex, &ey, &ez, &cx, &cy, &cz);
- fclose(fp);
- }
- void CRenderView::InitRenderWin()
- {
- glShadeModel ( GL_SMOOTH );
- glDepthFunc ( GL_LESS );
- glEnable ( GL_DEPTH_TEST );
- glMatrixMode ( GL_PROJECTION );
- glLoadIdentity();
- glMatrixMode ( GL_MODELVIEW );
- glLoadIdentity();
- gluPerspective ( angle, (float)WinWidth/(float)WinHeigth, Near, 1000000000.0);
- gluLookAt( ex, ey, ez, cx, cy, cz, 0.0, 1.0, 0.0);
- }
- void CRenderView::Render(void)
- {
- int i, j, k, l, m, TexIndex;
- POINT3D *plist;
- INT4U *pchlist;
-
- glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ACCUM_BUFFER_BIT);
- for(i = 0; i < ObjectNum; i ++ )
- for(j = 0; j < ObjectList[i].SurfNum; j ++ )
- {
- TexIndex = ObjectList[i].surflist[j].texId;
- if( TexIndex > 0 )
- InitTex( TexIndex );
- plist = ObjectList[i].surflist[j].pointlist;
- pchlist = ObjectList[i].surflist[j].patchlist;
-
- l = 0;
- for ( k = 0; k < ObjectList[i].surflist[j].triangle; k ++)
- {
- glBegin( GL_TRIANGLES );
- for( m = 0; m < 3; m ++ )
- {
- glColor3f ( plist[pchlist[l]].r,
- plist[pchlist[l]].g,
- plist[pchlist[l]].b );
- glTexCoord2f( plist[pchlist[l]].u,
- plist[pchlist[l]].v );
- glVertex3f( plist[pchlist[l]].x,
- plist[pchlist[l]].y,
- plist[pchlist[l]].z );
- l ++;
- }/* m */
- glEnd();
- }/* k */
-
- for ( k = 0; k < ObjectList[i].surflist[j].quadric; k ++)
- {
- glBegin( GL_QUADS );
- for( m = 0; m < 4; m ++ )
- {
- glColor3f ( plist[pchlist[l]].r,
- plist[pchlist[l]].g,
- plist[pchlist[l]].b );
- glTexCoord2f( plist[pchlist[l]].u,
- plist[pchlist[l]].v );
- glVertex3f( plist[pchlist[l]].x,
- plist[pchlist[l]].y,
- plist[pchlist[l]].z );
- l ++;
- }/* m */
- glEnd();
- }/* k */
- glFlush();
- CloseTex();
- }
- }
- void CRenderView::freelist()
- {
- int i, j;
-
- for( i=0; i<ObjectNum; i++)
- {
- for( j=0; j<ObjectList[i].SurfNum; j++)
- {
- free(ObjectList[i].surflist[j].pointlist);
- free(ObjectList[i].surflist[j].patchlist);
- }
- free( ObjectList[i].surflist );
- }
- free(ObjectList);
- for(i=1; i<=texnum; i++)
- free(TextureList[i]);
- free(TextureList);
- }
- extern TEXTURE_2D **TextureList;
- /********************************/
- /* function : OpenTexImage */
- /********************************/
- unsigned char *CRenderView::OpenTexImage( INT2U TexIndex, INT2U *rslx, INT2U *rsly )
- {
- unsigned char *image;
- FILE *fp;
- INT2U srcx, srcy;
- INT4U i, j;
- char ImageName[30];
- unsigned char *SImageData;
- int rc;
- int width, height;
- strcpy( ImageName, TextureList[TexIndex]->fname);
-
- /* load a image */
- fp = fopen(ImageName,"rb");
- if(!fp) return 0;
- fseek(fp,18L,0);
- rc=fread(&width,sizeof(long),1,fp);
- rc=fread(&height,sizeof(long),1,fp);
- *rslx=srcx=width; *rsly=srcy=height;
- fseek(fp,54L,0);
- image = (unsigned char *)malloc(width*height*3);
- rc=fread(image,width*height*3,1,fp);
- fclose(fp);
- SImageData = (unsigned char *)malloc(srcx*srcy*3);
- for(i=0; i<srcx; i++) {
- for(j=0; j<srcy; j++) {
- (unsigned char)*(SImageData+i*srcx*3+j*3+0) = (unsigned char)*(image+i*srcx*3+j*3+2);
- (unsigned char)*(SImageData+i*srcx*3+j*3+1) = (unsigned char)*(image+i*srcx*3+j*3+1);
- (unsigned char)*(SImageData+i*srcx*3+j*3+2) = (unsigned char)*(image+i*srcx*3+j*3+0);
- }
- }
- free(image);
- printf("%s : %ld=%ldn", ImageName, srcx*srcy*3,i*j*3);
- return( SImageData );
- }
- /********************************/
- /* function : InitTex */
- /********************************/
- void CRenderView::InitTex( int TexIndex )
- {
- INT2U TextType;
- unsigned char *ImageData;
- static int OldIndex = -1;
- if(TexIndex<=0) return;
- if(TexIndex == OldIndex)
- {
- glEnable(GL_TEXTURE_2D);
- return;
- }
-
- ImageData = ImageDatas[TexIndex-1];
- TextType = TextureList[TexIndex]->type;
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- if( TextType == CLAMP_TEXTURE )
- {
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- }
- else
- {
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- }
- glTexImage2D( GL_TEXTURE_2D, 0, 3, rslxs[TexIndex-1], rslys[TexIndex-1],
- 0,GL_RGB, GL_UNSIGNED_BYTE, ImageData );
- glEnable(GL_TEXTURE_2D);
- OldIndex = TexIndex;
- }
- /********************************/
- /* function : CloseTex */
- /********************************/
- void CRenderView::CloseTex()
- {
- glDisable(GL_TEXTURE_2D);
- }
- void CRenderView::LoadAllTexture()
- {
- int i;
-
- for (i=0; i <texnum ; i++)
- ImageDatas[i] = OpenTexImage( i+1, &rslxs[i], &rslys[i] );
- }
- void CRenderView::FreeAllTexture()
- {
- int i;
-
- for (i=0; i <texnum ; i++)
- free(ImageDatas[i]);
- }