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





