📄 triselectview.cpp
字号:
// TriSelectView.cpp : implementation of the CTriSelectView class
//
#include "stdafx.h"
#include "TriSelect.h"
#include "TriSelectDoc.h"
#include "TriSelectView.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <time.h>
struct object {
float v1[2];
float v2[2];
float v3[2];
float color[3];
} objects[MAXOBJS];
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CTriSelectView
IMPLEMENT_DYNCREATE(CTriSelectView, CView)
BEGIN_MESSAGE_MAP(CTriSelectView, CView)
//{{AFX_MSG_MAP(CTriSelectView)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_ERASEBKGND()
ON_WM_SIZE()
ON_WM_LBUTTONDOWN()
ON_WM_RBUTTONDOWN()
ON_WM_LBUTTONDBLCLK()
ON_WM_KEYDOWN()
//}}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()
/////////////////////////////////////////////////////////////////////////////
// CTriSelectView construction/destruction
CTriSelectView::CTriSelectView()
{
m_pDC = NULL;
windW = 300; windH = 300;
zRotation = 90.0;
zoom = 1.0;
linePoly = GL_FALSE;
}
CTriSelectView::~CTriSelectView()
{
}
BOOL CTriSelectView::PreCreateWindow(CREATESTRUCT& cs)
{
//add down
cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
//add up
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CTriSelectView drawing
void CTriSelectView::OnDraw(CDC* pDC)
{
CTriSelectDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
//add down
DrawScene();
//add up
}
/////////////////////////////////////////////////////////////////////////////
// CTriSelectView printing
BOOL CTriSelectView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CTriSelectView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CTriSelectView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CTriSelectView diagnostics
#ifdef _DEBUG
void CTriSelectView::AssertValid() const
{
CView::AssertValid();
}
void CTriSelectView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CTriSelectDoc* CTriSelectView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTriSelectDoc)));
return (CTriSelectDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CTriSelectView message handlers
int CTriSelectView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
//add down
Init(); //初始化OpenGL
//add up
return 0;
}
void CTriSelectView::OnDestroy()
{
//add down
HGLRC hrc;
hrc = ::wglGetCurrentContext();
::wglMakeCurrent(NULL, NULL);
if (hrc)
::wglDeleteContext(hrc);
if (m_pDC)
delete m_pDC;
//add up
CView::OnDestroy();
}
BOOL CTriSelectView::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
void CTriSelectView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
windW = cx;
windH = cy;
glViewport(0, 0, windW, windH);
glGetIntegerv(GL_VIEWPORT, vp);
}
//add down
void CTriSelectView::Init()
{
PIXELFORMATDESCRIPTOR pfd;
int n;
HGLRC hrc;
m_pDC = new CClientDC(this);
ASSERT(m_pDC != NULL);
if (!bSetupPixelFormat())
return;
n = ::GetPixelFormat(m_pDC->GetSafeHdc());
::DescribePixelFormat(m_pDC->GetSafeHdc(), n, sizeof(pfd), &pfd);
hrc = wglCreateContext(m_pDC->GetSafeHdc());
wglMakeCurrent(m_pDC->GetSafeHdc(), hrc);
numObjects = 10;
InitObjects(numObjects);
}
BOOL CTriSelectView::bSetupPixelFormat()
{
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
1, // version number
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER, // double buffered
PFD_TYPE_RGBA, // RGBA type
24, // 24-bit color depth
0, 0, 0, 0, 0, 0, // color bits ignored
0, // no alpha buffer
0, // shift bit ignored
0, // no accumulation buffer
0, 0, 0, 0, // accum bits ignored
32, // 32-bit z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
};
int pixelformat;
if ( (pixelformat = ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd)) == 0 )
{
MessageBox("ChoosePixelFormat failed");
return FALSE;
}
if (SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd) == FALSE)
{
MessageBox("SetPixelFormat failed");
return FALSE;
}
return TRUE;
}
void CTriSelectView::DrawScene()
{
glPushMatrix();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-175, 175, -175, 175);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glScalef(zoom, zoom, zoom);
glRotatef(zRotation, 0, 0, 1);
Render(GL_RENDER);
glPopMatrix();
glFinish();
SwapBuffers(wglGetCurrentDC());
}
void CTriSelectView::InitObjects(GLint num)
{
GLint i;
float x, y;
if (num > MAXOBJS) {
num = MAXOBJS;
}
if (num < 1) {
num = 1;
}
objectCount = num;
srand((unsigned int) time(NULL));
for (i = 0; i < num; i++) {
x = (rand() % 300) - 150;
y = (rand() % 300) - 150;
objects[i].v1[0] = x + (rand() % 50) - 25;
objects[i].v2[0] = x + (rand() % 50) - 25;
objects[i].v3[0] = x + (rand() % 50) - 25;
objects[i].v1[1] = y + (rand() % 50) - 25;
objects[i].v2[1] = y + (rand() % 50) - 25;
objects[i].v3[1] = y + (rand() % 50) - 25;
objects[i].color[0] = ((rand() % 100) + 50) / 150.0;
objects[i].color[1] = ((rand() % 100) + 50) / 150.0;
objects[i].color[2] = ((rand() % 100) + 50) / 150.0;
}
}
void CTriSelectView::Render(GLenum mode)
{
GLint i;
for (i = 0; i < objectCount; i++) {
if (mode == GL_SELECT) {
glLoadName(i);
}
glColor3fv(objects[i].color);
glBegin(GL_POLYGON);
glVertex2fv(objects[i].v1);
glVertex2fv(objects[i].v2);
glVertex2fv(objects[i].v3);
glEnd();
}
}
GLint CTriSelectView::DoSelect(GLint x, GLint y)
{
GLint hits;
glSelectBuffer(MAXSELECT, selectBuf);
glRenderMode(GL_SELECT);
glInitNames();
glPushName(~0);
glPushMatrix();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPickMatrix(x, windH - y, 4, 4, vp);
gluOrtho2D(-175, 175, -175, 175);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glScalef(zoom, zoom, zoom);
glRotatef(zRotation, 0, 0, 1);
Render(GL_SELECT);
glPopMatrix();
hits = glRenderMode(GL_RENDER);
if (hits <= 0) {
return -1;
}
return selectBuf[(hits - 1) * 4 + 3];
}
void CTriSelectView::RecolorTri(GLint h)
{
objects[h].color[0] = ((rand() % 100) + 50) / 150.0;
objects[h].color[1] = ((rand() % 100) + 50) / 150.0;
objects[h].color[2] = ((rand() % 100) + 50) / 150.0;
}
void CTriSelectView::DeleteTri(GLint h)
{
objects[h] = objects[objectCount - 1];
objectCount--;
}
void CTriSelectView::GrowTri(GLint h)
{
float v[2];
float *oldV;
GLint i;
v[0] = objects[h].v1[0] + objects[h].v2[0] + objects[h].v3[0];
v[1] = objects[h].v1[1] + objects[h].v2[1] + objects[h].v3[1];
v[0] /= 3;
v[1] /= 3;
for (i = 0; i < 3; i++) {
switch (i) {
case 0:
oldV = objects[h].v1;
break;
case 1:
oldV = objects[h].v2;
break;
case 2:
oldV = objects[h].v3;
break;
}
oldV[0] = 1.5 * (oldV[0] - v[0]) + v[0];
oldV[1] = 1.5 * (oldV[1] - v[1]) + v[1];
}
}
void CTriSelectView::DumpFeedbackVert(GLint * i, GLint n)
{
GLint index;
index = *i;
if (index + 7 > n) {
*i = n;
printf(" ???\n");
return;
}
printf(" (%g %g %g), color = (%4.2f %4.2f %4.2f)\n",
feedBuf[index],
feedBuf[index + 1],
feedBuf[index + 2],
feedBuf[index + 3],
feedBuf[index + 4],
feedBuf[index + 5]);
index += 7;
*i = index;
}
void CTriSelectView::DrawFeedback(GLint n)
{
GLint i;
GLint verts;
printf("Feedback results (%d floats):\n", n);
for (i = 0; i < n; i++) {
switch ((GLint) feedBuf[i]) {
case GL_POLYGON_TOKEN:
printf("Polygon");
i++;
if (i < n) {
verts = (GLint) feedBuf[i];
i++;
printf(": %d vertices", verts);
} else {
verts = 0;
}
printf("\n");
while (verts) {
DumpFeedbackVert(&i, n);
verts--;
}
i--;
break;
case GL_LINE_TOKEN:
printf("Line:\n");
i++;
DumpFeedbackVert(&i, n);
DumpFeedbackVert(&i, n);
i--;
break;
case GL_LINE_RESET_TOKEN:
printf("Line Reset:\n");
i++;
DumpFeedbackVert(&i, n);
DumpFeedbackVert(&i, n);
i--;
break;
default:
printf("%9.2f\n", feedBuf[i]);
break;
}
}
if (i == MAXFEED) {
printf("...\n");
}
printf("\n");
}
void CTriSelectView::DoFeedback(void)
{
GLint x;
glFeedbackBuffer(MAXFEED, GL_3D_COLOR, feedBuf);
(void) glRenderMode(GL_FEEDBACK);
glPushMatrix();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-175, 175, -175, 175);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glScalef(zoom, zoom, zoom);
glRotatef(zRotation, 0, 0, 1);
Render(GL_FEEDBACK);
glPopMatrix();
x = glRenderMode(GL_RENDER);
if (x == -1) {
x = MAXFEED;
}
DrawFeedback((GLint) x);
}
void CTriSelectView::OnLButtonDown(UINT nFlags, CPoint point)
{
hit = DoSelect((GLint) point.x, (GLint) point.y);
RecolorTri(hit);
InvalidateRect(FALSE);
CView::OnLButtonDown(nFlags, point);
}
void CTriSelectView::OnRButtonDown(UINT nFlags, CPoint point)
{
hit = DoSelect((GLint) point.x, (GLint) point.y);
DeleteTri(hit);
InvalidateRect(FALSE);
CView::OnRButtonDown(nFlags, point);
}
void CTriSelectView::OnLButtonDblClk(UINT nFlags, CPoint point)
{
hit = DoSelect((GLint) point.x, (GLint) point.y);
GrowTri(hit);
InvalidateRect(FALSE);
CView::OnLButtonDblClk(nFlags, point);
}
void CTriSelectView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
switch (nChar) {
case VK_LEFT:
zoom /= 0.75;
InvalidateRect(FALSE);
break;
case VK_RIGHT:
zoom *= 0.75;
InvalidateRect(FALSE);
break;
case VK_UP:
DoFeedback();
InvalidateRect(FALSE);
break;
case VK_DOWN:
linePoly = !linePoly;
if (linePoly) {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
} else {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
InvalidateRect(FALSE);
break;
}
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -