利用opengl+MFC读取并显示文本与二进制格式的stl

本文档详细介绍了如何配置OpenGL与Visual Studio 2015,包括OpenGLView类的接口、窗口像素格式设置、OpenGL环境创建和初始化,以及关键的绘图和控制函数。适合OpenGL初学者和开发人员参考。

一、 配置opengl与vs2015
参考:https://blog.youkuaiyun.com/qq_24990189/article/details/89631111
二、所有代码:


// OpenGLView.h : COpenGLView 类的接口
//

#pragma once


#if !defined(AFX_2OPENGLVIEW_H__093AEC68_AF1D_4180_B7AE_BE30F4E3A904__INCLUDED_)
#define AFX_2OPENGLVIEW_H__093AEC68_AF1D_4180_B7AE_BE30F4E3A904__INCLUDED_

#if _MSC_VER > 1000
#endif // _MSC_VER > 1000
#include <GL/glew.h>
#include <GLFW/glfw3.h>

#include "GL/gl.h"
#include "GL/glaux.h"
#include "GL/glu.h"
 #include "GL/glut.h"
#include "resource.h"

#include<vector>
#include<iostream>

using namespace std;
using std::vector;

class COpenGLView : public CView
{
protected: // 仅从序列化创建
	COpenGLView();
	DECLARE_DYNCREATE(COpenGLView)

// 特性
public:
	COpenGLDoc* GetDocument() const;

	//
	//void readSTL();
// 操作
public:

// 重写
public:
	virtual void OnDraw(CDC* pDC);  // 重写以绘制该视图
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
	virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
	virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
	virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);

// 实现
public:
	virtual ~COpenGLView();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// 生成的消息映射函数
protected:
	
	afx_msg void OnFilePrintPreview();
	afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
	DECLARE_MESSAGE_MAP()
public:
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	void RenderScene();
	BOOL SetWindowPixelFormat(HDC hDC);//设置像素格式
	BOOL CreateViewGLContext(HDC hDC);//创建绘制环境(RC)并使之成为当前绘制环境
	BOOL InitGL(GLvoid);//初始化openGL
	//int DrawGLScene(GLvoid);//绘图代码区
	int m_GLPixelIndex;
	HGLRC m_hGLContext;//绘制环境

					   //{{AFX_MSG(CMy2OpenGLView)
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void OnDestroy();
	afx_msg void OnSize(UINT nType, int cx, int cy);
	//}}AFX_MSG
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

	BOOL m_bLine;        //Status of Line
	BOOL m_bPolygon;    //Status of Polygon
	BOOL m_bTriangle;    //Status of Triangle

	BOOL m_bSimpleCube;
	BOOL m_b2DSimpleShape;

	BOOL m_bOpenStl;

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

	afx_msg void OnObjectsSimplecube();
	afx_msg void On2dSimpleshape();
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnMouseHWheel(UINT nFlags, short zDelta, CPoint pt);
	afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	//旋转、移动、缩放
public:
	CClientDC *m_pDC;
	HGLRC m_hglrc;
	GLfloat m_yAngle;
	GLfloat m_xAngle;
	GLfloat m_zAngle;
	GLfloat m_xPos;
	GLfloat m_yPos;
	GLfloat m_zPos;
	CPoint m_MouseDownPoint;
	float m_Scale;
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg void OnFileOpen();
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
	CString Path;
	vector<float>verts;	//存放点坐标
	vector<float>vnorms;//存放法矢
	afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
};

#ifndef _DEBUG  // OpenGLView.cpp 中的调试版本
inline COpenGLDoc* COpenGLView::GetDocument() const
   { return reinterpret_cast<COpenGLDoc*>(m_pDocument); }
#endif

#endif

// OpenGLView.cpp : COpenGLView 类的实现
//

#include "stdafx.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "OpenGL.h"
#endif

#include "OpenGLDoc.h"
#include "OpenGLView.h"
#include <fstream>
#define GLEW_STATIC




#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


// COpenGLView

IMPLEMENT_DYNCREATE(COpenGLView, CView)

BEGIN_MESSAGE_MAP(COpenGLView, CView)
	//{{AFX_MSG_MAP(CMy2OpenGLView)
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_WM_SIZE()
	//}}AFX_MSG_MAP
	// 标准打印命令
	ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &COpenGLView::OnFilePrintPreview)
	ON_WM_CONTEXTMENU()
	ON_WM_RBUTTONUP()
	ON_COMMAND(ID_OBJECTS_SIMPLECUBE, &COpenGLView::OnObjectsSimplecube)
	ON_COMMAND(ID_2D_SIMPLESHAPE, &COpenGLView::On2dSimpleshape)
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEHWHEEL()
	ON_WM_KEYDOWN()
	ON_WM_MOUSEMOVE()
	ON_COMMAND(ID_FILE_OPEN, &COpenGLView::OnFileOpen)
	ON_WM_MOUSEWHEEL()
END_MESSAGE_MAP()

// COpenGLView 构造/析构

COpenGLView::COpenGLView()
{
	// TODO: 在此处添加构造代码
	//+++++++++++++++++++++
	m_bSimpleCube = FALSE;
	m_b2DSimpleShape = FALSE;
	m_bOpenStl = FALSE;
	//++++++++++++++++++++++
	//旋转、移动、缩放

	m_xPos = 0.0f;
	m_yPos = 0.0f;
	m_zPos = 0.0f;
	m_xAngle = 0.0f;
	m_yAngle = 0.0f;
	m_zAngle = 0.0f;
	m_Scale = 1.0f;
	verts.clear();
	vnorms.clear();
	//readSTL();

    //++++++++++++++++++++++++++++++++
}

COpenGLView::~COpenGLView()
{
}

BOOL COpenGLView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: 在此处通过修改
	//  CREATESTRUCT cs 来修改窗口类或样式
	//++++++++++++++++++++++++++++++++++++++++++++++++
	cs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS);//openGL必需的
	//+++++++++++++++++++++++++++++++++++++++++++++++
	return CView::PreCreateWindow(cs);
}

// COpenGLView 绘制

void COpenGLView::OnDraw(CDC* pDC)
{
	COpenGLDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// TODO: 在此处为本机数据添加绘制代码
	//++++++++++++++++++++++++++++++++++++++
	//清除缓存
	::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	//++++++++++++++++++++++++++++++++++++++++
	//设定初始值
	glLoadIdentity();					//恢复初始坐标系
	glTranslatef(0.0f, 0.0f, -5.0f);        //平移函数
	glRotatef(-30.0f, 1.0f, 1.0f, 0.0f);    //旋转函数
	//+++++++++++++++++++++++++++++++++++++++++++++++++++
	//鼠标控制旋转移动
	glTranslatef(m_xPos, m_yPos, m_zPos);		//移动
	glRotatef(m_xAngle, 1.0f, 0.0f, 0.0f);		//x轴旋转
	glRotatef(m_yAngle, 0.0f, 1.0f, 0.0f);		//y轴旋转
	glScalef(m_Scale, m_Scale, m_Scale);		//缩放
	//glColor3f(1.0, 1.0, 0.0);
	//++++++++++++++++++++++++++++++++++++++++++++
	RenderScene();//渲染
	// Tell OpenGL to flush its pipeline
	::glFinish();
	// Now Swap the buffers 交换缓冲区
	::SwapBuffers(pDC->GetSafeHdc());
	//+++++++++++++++++++++++++++++++++++++++++
}

// COpenGLView 打印

void COpenGLView::OnFilePrintPreview()
{
#ifndef SHARED_HANDLERS
	AFXPrintPreview(this);
#endif
}

BOOL COpenGLView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// 默认准备
	return DoPreparePrinting(pInfo);
}

void COpenGLView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加额外的打印前进行的初始化过程
}

void COpenGLView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加打印后进行的清理过程
}


void COpenGLView::OnRButtonUp(UINT /* nFlags */, CPoint point)
{
	ClientToScreen(&point);
	OnContextMenu(this, point);
}

void COpenGLView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
	theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}


// COpenGLView 诊断

#ifdef _DEBUG
void COpenGLView::AssertValid() const
{
	CView::AssertValid();
}

void COpenGLView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

COpenGLDoc* COpenGLView::GetDocument() const // 非调试版本是内联的
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(COpenGLDoc)));
	return (COpenGLDoc*)m_pDocument;
}
//#endif //_DEBUG

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// COpenGLView 消息处理程序
//设置窗口像素表
BOOL COpenGLView::SetWindowPixelFormat(HDC hDC)
{
	//定义窗口的像素格式
	PIXELFORMATDESCRIPTOR pixelDesc =
	{
		sizeof(PIXELFORMATDESCRIPTOR),
		1,
		PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
		PFD_DOUBLEBUFFER | PFD_SUPPORT_GDI,
		PFD_TYPE_RGBA,
		24,
		0,0,0,0,0,0,
		0,
		0,
		0,
		0,0,0,0,
		32,
		0,
		0,
		PFD_MAIN_PLANE,
		0,
		0,0,0
	};

	this->m_GLPixelIndex = ChoosePixelFormat(hDC, &pixelDesc);//选择最相近的像素格式
	if (this->m_GLPixelIndex == 0)
	{//选择失败
		this->m_GLPixelIndex = 1;//默认的像素格式
		if (DescribePixelFormat(hDC, this->m_GLPixelIndex, sizeof(PIXELFORMATDESCRIPTOR), &pixelDesc) == 0)
		{//用默认的像素格式进行设置
			return FALSE;
		}
	}

	if (SetPixelFormat(hDC, this->m_GLPixelIndex, &pixelDesc) == FALSE)
	{
		return FALSE;
	}
	return TRUE;
}

BOOL COpenGLView::InitGL(GLvoid)                                        // All Setup For OpenGL Goes Here OpenGL的所有设置都在这
{
	glShadeModel(GL_SMOOTH);                            // Enable Smooth Shading 使用光滑材质
	glClearColor(0.0, 0.0, 0.0, 0.0);					// Black Background  黑色背景
	glClearDepth(1.0f);                                 // Depth Buffer Setup 深度缓冲设置
	glEnable(GL_DEPTH_TEST);                            // Enables Depth Testing 启用深度测试
	glDepthFunc(GL_LEQUAL);                             // The Type Of Depth Testing To Do 要做的深度测试类型
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);  // Really Nice Perspective Calculations 非常好的透视计算
	return TRUE;                                        // Initialization Went OK 初始化成功
}
BOOL COpenGLView::CreateViewGLContext(HDC hDC)
{
	this->m_hGLContext = wglCreateContext(hDC);//创建RC
	if (this->m_hGLContext == NULL)
	{//创建失败
		return FALSE;
	}

	if (wglMakeCurrent(hDC, this->m_hGLContext) == FALSE)
	{//选为当前RC失败
		return FALSE;
	}
	return TRUE;
}
#endif //_DEBUG


// CMy2OpenGLView message handlers

int COpenGLView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO: Add your specialized creation code here
	HWND hWnd = this->GetSafeHwnd();
	HDC hDC = ::GetDC(hWnd);

	if (this->SetWindowPixelFormat(hDC) == FALSE)
	{//设置像素格式
		return 0;
	}
	if (this->CreateViewGLContext(hDC) == FALSE)
	{//创建RC并选为所用
		return 0;
	}
	if (!this->InitGL())
	{//初始化openGL
		return 0;
	}
	return 0;
}

void COpenGLView::OnDestroy()
{
	CView::OnDestroy();

	// TODO: Add your message handler code here
	if (wglGetCurrentContext() != NULL)
	{
		wglMakeCurrent(NULL, NULL);
	}
	if (this->m_hGLContext != NULL)
	{
		wglDeleteContext(this->m_hGLContext);
		this->m_hGLContext = NULL;
	}
}

void COpenGLView::OnSize(UINT nType, int cx, int cy)
{
	CView::OnSize(nType, cx, cy);

	// TODO: Add your message handler code here
	GLdouble aspect_ratio; // width/height ratio

	if (0 >= cx || 0 >= cy)
	{
		return;
	}
	// select the full client area
	::glViewport(0, 0, (GLint)cx, (GLint)cy);
	// compute the aspect ratio 计算长宽比
	// this will keep all dimension scales equal 这将保持所有维度尺度相等
	aspect_ratio = (GLdouble)cx / (GLdouble)cy;
	// select the projection matrix and clear it
	::glMatrixMode(GL_PROJECTION);
	::glLoadIdentity();
	// select the viewing volume 选择投影矩阵并清除它
	
	//gluPerspective(40.0f, aspect_ratio, 4.0f, -10.0f);
	//gluPerspective(45.0f, aspect_ratio, 0.1f, -100.0f);
	glOrtho(-3000.0, 3000.0, -3000.0,3000.0, -3000.0, 3000.0);

	/*
	if(cx < cy)
		glOrtho(-1000.0, 10000.0, -1000.0*(GLfloat)cy / (GLfloat)cx, 1000.0*(GLfloat)cy / (GLfloat)cx, -1000.0, 10000.0);
	else
		glOrtho(-1000.0*(GLfloat)cx / (GLfloat)cy, 1000.0*(GLfloat)cx / (GLfloat)cy, -1000.0, 1000.0, -1000.0, 10000.0);
	*/
	
	/*
	if (cx < cy)
		glOrtho(-10.0, 100.0, -10.0*(GLfloat)cy / (GLfloat)cx, 10.0*(GLfloat)cy / (GLfloat)cx, -100.0, 100.0);
	else
		glOrtho(-10.0*(GLfloat)cx / (GLfloat)cy, 10.0*(GLfloat)cx / (GLfloat)cy, -10.0, 10.0, -100.0, 100.0);
	*/
	::glMatrixMode(GL_MODELVIEW);
	::glLoadIdentity();                              // Reset The Modelview Matrix 重置Modelview矩阵
	::glDrawBuffer(GL_BACK);
}


void COpenGLView::RenderScene()
{
	// Here's Where We Do All The Drawing
	if (m_b2DSimpleShape == TRUE)
	{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    // Clear Screen And Depth Buffer
	glLoadIdentity();                                    // Reset The Current Modelview Matrix 重置Modelview矩阵
	glTranslatef(-1.5f, 0.0f, -6.0f);//物体左移1.5,向内移6,相当于移动镜头一样,让物体进入镜头中
	glBegin(GL_TRIANGLES);                            // 绘制三角形
	glColor3f(255.0f, 0.0f, 0.0f);
	glVertex3f(0.0f, 1.0f, 0.0f);                    // 上顶点
	glColor3f(0.0f, 255.0f, 0.0f);
	glVertex3f(-1.0f, -1.0f, 0.0f);                    // 左下
	glColor3f(0.0f, 0.0f, 255.0f);
	glVertex3f(1.0f, -1.0f, 0.0f);                    // 右下
	glEnd();                                // 三角形绘制结束
	glTranslatef(3.0f, 0.0f, 0.0f);
	glBegin(GL_QUADS);                            //  绘制正方形
	glColor3f(255.0f, 0.0f, 0.0f);
	glVertex3f(-1.0f, 1.0f, 0.0f);                    // 左上
	glColor3f(0.0f, 255.0f, 0.0f);
	glVertex3f(1.0f, 1.0f, 0.0f);                    // 右上
	glColor3f(0.0f, 0.0f, 255.0f);
	glVertex3f(1.0f, -1.0f, 0.0f);                    // 左下
	glColor3f(255.255f, 255.0f, 255.0f);
	glVertex3f(-1.0f, -1.0f, 0.0f);                    // 右下
	glEnd();                                // 正方形绘制结束
	glFlush();
	}
	else if (m_bSimpleCube == TRUE)
	{
		
		//front face
		glBegin(GL_POLYGON);
		glColor3f(1.0f, 0.0f, 1.0f);
		glVertex3f(-100.0, -100.0, 0.0);
		glColor3f(1.0f, 1.0f, 1.0f);
		glVertex3f(-100.0, 100.0, 0.0);
		glColor3f(1.0f, 1.0f, 0.0f);
		glVertex3f(100.0, 100.0, 0.0);
		glColor3f(0.0f, 0.8f, 1.0f);
		glVertex3f(100.0, -100.0, 0.0);
		glEnd();

		//back face
		glBegin(GL_POLYGON);
		glColor3f(0.0f, 0.5f, 0.0f);
		glVertex3f(-100.0, -100.0, -100.0);
		glColor3f(1.0f, 0.8f, 10.0f);
		glVertex3f(-100.0, 100.0, -100.0);
		glColor3f(0.0f, 0.0f, 1.0f);
		glVertex3f(100.0, 100.0, -100.0);
		glColor3f(1.0f, 1.0f, 0.0f);
		glVertex3f(100.0, -100.0, -100.0);
		glEnd();

		//left face
		glBegin(GL_POLYGON);
		glColor3f(1.0f, 0.5f, 0.0f);
		glVertex3f(-100.0, -100.0, 0.0);
		glColor3f(0.8f, 0.0f, 0.0f);
		glVertex3f(-100.0, 100.0, 0.0);
		glColor3f(0.0f, 0.0f, 1.0f);
		glVertex3f(-100.0, 100.0, -100.0);
		glColor3f(0.0f, 0.6f, 1.0f);
		glVertex3f(-100.0, -100.0, -100.0);
		glEnd();

		//right face
		glBegin(GL_POLYGON);
		glColor3f(1.0f, 0.0f, 0.0f);
		glVertex3f(100.0, -100.0, 0.0);
		glColor3f(0.0f, 1.0f, 1.0f);
		glVertex3f(100.0, 100.0, 0.0);
		glColor3f(0.0f, 0.0f, 1.0f);
		glVertex3f(100.0, 100.0, -100.0);
		glColor3f(1.0f, 0.0f, 1.0f);
		glVertex3f(100.0, -100.0, -100.0);
		glEnd();

		//top face
		glBegin(GL_POLYGON);
		glColor3f(0.0f, 1.0f, 0.0f);
		glVertex3f(-100.0, 100.0, 0.0);
		glColor3f(0.0f, 0.0f, 1.0f);
		glVertex3f(-100.0, 100.0, -100.0);
		glColor3f(1.0f, 0.0f, 0.0f);
		glVertex3f(100.0, 100.0, -100.0);
		glColor3f(0.0f, 0.5f, 0.8f);
		glVertex3f(100.0, 100.0, 0.0);
		glEnd();

		//bottom face
		glBegin(GL_POLYGON);
		glColor3f(0.0f, 1.0f, 0.0f);
		glVertex3f(-100.0, -100.0, 0.0);
		glColor3f(0.0f, 0.0f, 1.0f);
		glVertex3f(-100.0, -100.0, -100.0);
		glColor3f(1.0f, 0.0f, 0.0f);
		glVertex3f(100.0, -100.0, -100.0);
		glColor3f(0.0f, 0.5f, 0.8f);
		glVertex3f(100.0, -100.0, 0.0);
		glEnd();
		

	}
	else if(m_bOpenStl = TRUE)//画stl
	{
		
		//*int m_div = 1;
		for (int i = 0; i < vnorms.size(); i++)
		{
			
			glBegin(GL_TRIANGLES);
			glColor3f(1.0f, 0.0f, 0.0f);
			glNormal3f(vnorms[i] , vnorms[i + 1], vnorms[i + 2] );
			glVertex3f(verts[i] ,verts[i + 1] , verts[i + 2] );
			i += 3;
			glColor3f(0.0f, 1.0f, 0.0f);
			glNormal3f(vnorms[i], vnorms[i + 1], vnorms[i + 2]);
			glVertex3f(verts[i], verts[i + 1], verts[i + 2]);
			i += 3;
			glColor3f(0.0f, 0.0f, 1.0f);
			glNormal3f(vnorms[i], vnorms[i + 1], vnorms[i + 2]);
			glVertex3f(verts[i], verts[i + 1], verts[i + 2]);
			i +=2;
			glEnd();

		}
		//glPopMatrix();
	}

}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void COpenGLView::On2dSimpleshape()
{
	// TODO: 在此添加命令处理程序代码
	m_b2DSimpleShape = TRUE;
	m_bSimpleCube = FALSE;
	m_bOpenStl = FALSE;

	InvalidateRect(NULL, FALSE);
}


void COpenGLView::OnObjectsSimplecube()
{
	// TODO: 在此添加命令处理程序代码
	m_b2DSimpleShape = FALSE;
	m_bSimpleCube = TRUE;
	m_bOpenStl = FALSE;
	//++++++++++++++++++
	InvalidateRect(NULL, FALSE);

}





void COpenGLView::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	//+++++++++++++++++++++++++++++++++++++++++
	m_MouseDownPoint = point;
	SetCapture();
	//+++++++++++++++++++++++++++++++++++++
	CView::OnLButtonDown(nFlags, point);
}


void COpenGLView::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	//+++++++++++++++++++++++++++++++++++++++++++
	m_MouseDownPoint = CPoint(0, 0);
	ReleaseCapture();
	//++++++++++++++++++++++++++++++++++++++++++
	CView::OnLButtonUp(nFlags, point);
}


void COpenGLView::OnMouseHWheel(UINT nFlags, short zDelta, CPoint pt)
{
	// 此功能要求 Windows Vista 或更高版本。
	// _WIN32_WINNT 符号必须 >= 0x0600。
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++

	CView::OnMouseHWheel(nFlags, zDelta, pt);
}


void COpenGLView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	//+++++++++++++++++++++++++++++++++++++++++++++++
	switch (nChar)
	{
	case VK_UP:        m_yPos = m_yPos + 1.0f;
		break;
	case VK_DOWN:    m_yPos = m_yPos - 1.0f;
		break;
	case VK_LEFT:    m_xPos = m_xPos - 1.0f;
		break;
	case VK_RIGHT:  m_xPos = m_xPos + 1.0f;
		break;
	default:        MessageBox("Press the arrow keys only");
		break;
	}

	InvalidateRect(NULL, FALSE);
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++

	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}


void COpenGLView::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	//++++++++++++++++++++++++++++++++++++++++++++++++++
	if (GetCapture() == this)
	{
		//Increment the object rotation angles  
		m_xAngle += (point.y - m_MouseDownPoint.y) / 3.6;
		m_yAngle += (point.x - m_MouseDownPoint.x) / 3.6;
		//Redraw the view  
		InvalidateRect(NULL, FALSE);
		//Set the mouse point  
		m_MouseDownPoint = point;
	};
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++

	CView::OnMouseMove(nFlags, point);
}


void COpenGLView::OnFileOpen()
{
	// TODO: 在此添加命令处理程序代码
	CFileDialog fDlg(TRUE, _TEXT("txt"), NULL, 4 | 2,
		_TEXT("全部文件(*.*)|*.*|(*.stp*)|*.*|(*.rbs_App*)|*.rbs_App*|文本文件(*.txt,*.ini,*.log)|*.txt;*.ini;*.log||"));
	if (fDlg.DoModal() == IDOK)
	{
		Path = fDlg.GetPathName();//获取文件路径
		CString str;
		CStdioFile fFile;

		fFile.Open(Path, CStdioFile::modeReadWrite/*|CStdioFile::modeCreate|CStdioFile::modeWrite*/);
		
		FILE *fStl = nullptr;
		//errno_t abc = fopen_s(&fStl, Path, "r");
		//fclose(fStl);
		fFile.ReadString(str);//读一行文件

		if(str.Find("solid") == 0)//读取文本格式stl
		{
			
			while (fFile.ReadString(str))
			{
				
				if ((str.Find("solid") == -1) && (str.Find("outer loop") == -1) && (str.Find("endloop") == -1) && (str.Find("endfacet") == -1) && (str.Find("endsolid") == -1))
				{
					if (str.Find("facet normal") != -1)
					{
						float a, b, c;
						sscanf_s(str, "%*s %*s %f %f %f", &a, &b, &c);
						vnorms.push_back(a);
						vnorms.push_back(b);
						vnorms.push_back(c);
						vnorms.push_back(a);
						vnorms.push_back(b);
						vnorms.push_back(c);
						vnorms.push_back(a);
						vnorms.push_back(b);
						vnorms.push_back(c);
					}
					else
					{
						float a, b, c;
						sscanf_s(str, "%*s  %f %f %f", &a, &b, &c);
						verts.push_back(a);
						verts.push_back(b);
						verts.push_back(c);

					}
				}
			}
			fFile.Close();
			m_bSimpleCube = FALSE;
			m_b2DSimpleShape = FALSE;
			m_bOpenStl = TRUE;
		}
		else//读取二进制格式stl
		{
		
			fFile.Close();
			//打开文档并读取文档中共有多少个字符
			errno_t nRes = fopen_s(&fStl, Path, "rb");
			fseek(fStl, 0L, SEEK_END);
			int file_size = ftell(fStl);//返回fStl指针当前位置。
			rewind(fStl);//把fStl指针重新指向开头
			//定义数组
			char *buffer;
			buffer = new char[file_size];
			//读取文件中的字符保存到buffer
			fread(buffer, 1, file_size, fStl);

			for (int i = 0; i < (file_size - 84) / 50; i++) //i代表三角形个数
			{
				float a[13];
				for (int j = 0; j < 50; j += 4) //j代表字节数
				{
					unsigned char s[4];
					s[0] = buffer[84 + i * 50 + j];
					s[1] = buffer[85 + i * 50 + j];
					s[2] = buffer[86 + i * 50 + j];
					s[3] = buffer[87 + i * 50 + j];
					float *pf1 = (float*)s;
					int c = j / 4; //c代表第几个数
					memcpy_s(&a[c], sizeof(float), s, 4);
				}
				for (int x = 0; x < 3; x++) //前三个数为法向量 存三遍,保证法向量的下标与顶点的下标对应
				{
					vnorms.push_back(a[0]);
					vnorms.push_back(a[1]);
					vnorms.push_back(a[2]);
				}
				for (int y = 3; y < 12; y++) //后九个数为顶点信息
				{
					verts.push_back(a[y]);
				}
			}
			fclose(fStl);
			m_bSimpleCube = FALSE;
			m_b2DSimpleShape = FALSE;
			m_bOpenStl = TRUE;	
		}	
	}	
	else
	{
		AfxMessageBox("打开失败!");
		return;
	}
	
	InvalidateRect(NULL, FALSE);
}


BOOL COpenGLView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++
	if (m_Scale >= 0)
	{
		m_Scale += 0.05 *zDelta / 120;
	}
	else
	{
		if (zDelta > 0)
		{
			m_Scale += 0.05 *zDelta / 120;
		}
	}
	InvalidateRect(NULL, FALSE);
	//+++++++++++++++++++++++++++++++++++++++++++++++++++
	return CView::OnMouseWheel(nFlags, zDelta, pt);
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值