camwnd.cpp
字号:
{
m_nCambuttonstate = buttons;
if (!buttons)
return;
m_ptButton.x = x;
m_ptButton.y = y;
if (buttons == (MK_RBUTTON|MK_CONTROL) )
{
Cam_PositionDrag ();
Sys_UpdateWindows (W_XY|W_CAMERA|W_Z);
return;
}
GetCursorPos(&m_ptCursor);
if (buttons & (MK_LBUTTON | MK_MBUTTON) )
{
Drag_MouseMoved (x, y, buttons);
Sys_UpdateWindows (W_XY|W_CAMERA|W_Z);
}
}
void CCamWnd::InitCull()
{
int i;
VectorSubtract (m_Camera.vpn, m_Camera.vright, m_vCull1);
VectorAdd (m_Camera.vpn, m_Camera.vright, m_vCull2);
for (i=0 ; i<3 ; i++)
{
if (m_vCull1[i] > 0)
m_nCullv1[i] = 3+i;
else
m_nCullv1[i] = i;
if (m_vCull2[i] > 0)
m_nCullv2[i] = 3+i;
else
m_nCullv2[i] = i;
}
}
qboolean CCamWnd::CullBrush (brush_t *b)
{
int i;
vec3_t point;
float d;
if (g_PrefsDlg.m_bCubicClipping)
{
float fLevel = g_PrefsDlg.m_nCubicScale * 64;
point[0] = m_Camera.origin[0] - fLevel;
point[1] = m_Camera.origin[1] - fLevel;
point[2] = m_Camera.origin[2] - fLevel;
for (i=0; i<3; i++)
if (b->mins[i] < point[i] && b->maxs[i] < point[i])
return true;
point[0] = m_Camera.origin[0] + fLevel;
point[1] = m_Camera.origin[1] + fLevel;
point[2] = m_Camera.origin[2] + fLevel;
for (i=0; i<3; i++)
if (b->mins[i] > point[i] && b->maxs[i] > point[i])
return true;
}
for (i=0 ; i<3 ; i++)
point[i] = b->mins[m_nCullv1[i]] - m_Camera.origin[i];
d = DotProduct (point, m_vCull1);
if (d < -1)
return true;
for (i=0 ; i<3 ; i++)
point[i] = b->mins[m_nCullv2[i]] - m_Camera.origin[i];
d = DotProduct (point, m_vCull2);
if (d < -1)
return true;
return false;
}
#if 0
void CCamWnd::DrawLightRadius(brush_t* pBrush)
{
// if lighting
int nRadius = Brush_LightRadius(pBrush);
if (nRadius > 0)
{
Brush_SetLightColor(pBrush);
qglEnable (GL_BLEND);
qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
qglDisable (GL_TEXTURE_2D);
qglEnable(GL_TEXTURE_2D);
qglDisable(GL_BLEND);
qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
}
}
#endif
/*
==============
Cam_Draw
==============
*/
void CCamWnd::Cam_Draw()
{
brush_t *brush;
face_t *face;
float screenaspect;
float yfov;
double start, end;
int i;
/*
FILE *f = fopen("g:/nardo/raduffy/editorhack.dat", "w");
if (f != NULL) {
fwrite(&m_Camera.origin[0], sizeof(float), 1, f);
fwrite(&m_Camera.origin[1], sizeof(float), 1, f);
fwrite(&m_Camera.origin[2], sizeof(float), 1, f);
fwrite(&m_Camera.angles[PITCH], sizeof(float), 1, f);
fwrite(&m_Camera.angles[YAW], sizeof(float), 1, f);
fclose(f);
}
*/
if (!active_brushes.next)
return; // not valid yet
if (m_Camera.timing)
start = Sys_DoubleTime ();
//
// clear
//
QE_CheckOpenGLForErrors();
qglViewport(0, 0, m_Camera.width, m_Camera.height);
qglScissor(0, 0, m_Camera.width, m_Camera.height);
qglClearColor (g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][0],
g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][1],
g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][2], 0);
qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//
// set up viewpoint
//
vec5_t lightPos;
if (g_PrefsDlg.m_bGLLighting)
{
qglEnable(GL_LIGHTING);
//qglEnable(GL_LIGHT0);
lightPos[0] = lightPos[1] = lightPos[2] = 3.5;
lightPos[3] = 1.0;
qglLightModelfv(GL_LIGHT_MODEL_AMBIENT, lightPos);
//qglLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
//lightPos[0] = lightPos[1] = lightPos[2] = 3.5;
//qglLightfv(GL_LIGHT0, GL_AMBIENT, lightPos);
}
else
{
qglDisable(GL_LIGHTING);
}
qglMatrixMode(GL_PROJECTION);
qglLoadIdentity ();
screenaspect = (float)m_Camera.width / m_Camera.height;
yfov = 2*atan((float)m_Camera.height / m_Camera.width)*180/Q_PI;
qgluPerspective (yfov, screenaspect, 2, 8192);
qglRotatef (-90, 1, 0, 0); // put Z going up
qglRotatef (90, 0, 0, 1); // put Z going up
qglRotatef (m_Camera.angles[0], 0, 1, 0);
qglRotatef (-m_Camera.angles[1], 0, 0, 1);
qglTranslatef (-m_Camera.origin[0], -m_Camera.origin[1], -m_Camera.origin[2]);
Cam_BuildMatrix ();
//if (m_Camera.draw_mode == cd_light)
//{
// if (g_PrefsDlg.m_bGLLighting)
// {
// VectorCopy(m_Camera.origin, lightPos);
// lightPos[3] = 1;
// qglLightfv(GL_LIGHT0, GL_POSITION, lightPos);
// }
//}
InitCull ();
//
// draw stuff
//
GLfloat lAmbient[] = {1.0, 1.0, 1.0, 1.0};
switch (m_Camera.draw_mode)
{
case cd_wire:
qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
qglDisable(GL_TEXTURE_2D);
qglDisable(GL_TEXTURE_1D);
qglDisable(GL_BLEND);
qglDisable(GL_DEPTH_TEST);
qglColor3f(1.0, 1.0, 1.0);
// qglEnable (GL_LINE_SMOOTH);
break;
case cd_solid:
qglCullFace(GL_FRONT);
qglEnable(GL_CULL_FACE);
qglShadeModel (GL_FLAT);
qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
qglDisable(GL_TEXTURE_2D);
qglDisable(GL_BLEND);
qglEnable(GL_DEPTH_TEST);
qglDepthFunc (GL_LEQUAL);
break;
case cd_texture:
qglCullFace(GL_FRONT);
qglEnable(GL_CULL_FACE);
qglShadeModel (GL_FLAT);
qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
qglEnable(GL_TEXTURE_2D);
qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
qglDisable(GL_BLEND);
qglEnable(GL_DEPTH_TEST);
qglDepthFunc (GL_LEQUAL);
break;
case cd_blend:
qglCullFace(GL_FRONT);
qglEnable(GL_CULL_FACE);
qglShadeModel (GL_FLAT);
qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
qglEnable(GL_TEXTURE_2D);
qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
qglDisable(GL_DEPTH_TEST);
qglEnable (GL_BLEND);
qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
break;
}
qglMatrixMode(GL_TEXTURE);
m_nNumTransBrushes = 0;
for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next)
{
//DrawLightRadius(brush);
if (CullBrush (brush))
continue;
if (FilterBrush (brush))
continue;
if ((brush->brush_faces->texdef.flags & (SURF_TRANS33 | SURF_TRANS66)) || (brush->brush_faces->d_texture->bFromShader && brush->brush_faces->d_texture->fTrans != 1.0))
{
m_TransBrushes [ m_nNumTransBrushes++ ] = brush;
}
else
{
//-- if (brush->patchBrush)
//-- m_TransBrushes [ m_nNumTransBrushes++ ] = brush;
//-- else
Brush_Draw(brush);
}
}
if (g_PrefsDlg.m_bGLLighting)
{
qglDisable (GL_LIGHTING);
}
//
//qglDepthMask ( 0 ); // Don't write to depth buffer
qglEnable ( GL_BLEND );
qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
for ( i = 0; i < m_nNumTransBrushes; i++ )
Brush_Draw (m_TransBrushes[i]);
//qglDepthMask ( 1 ); // Ok, write now
qglMatrixMode(GL_PROJECTION);
//
// now draw selected brushes
//
if (g_PrefsDlg.m_bGLLighting)
{
qglEnable (GL_LIGHTING);
}
qglTranslatef (g_qeglobals.d_select_translate[0], g_qeglobals.d_select_translate[1], g_qeglobals.d_select_translate[2]);
qglMatrixMode(GL_TEXTURE);
brush_t* pList = (g_bClipMode && g_pSplitList) ? g_pSplitList : &selected_brushes;
// draw normally
for (brush = pList->next ; brush != pList ; brush=brush->next)
{
//DrawLightRadius(brush);
//if (brush->patchBrush && g_qeglobals.d_select_mode == sel_curvepoint)
// continue;
Brush_Draw(brush);
}
// blend on top
qglMatrixMode(GL_PROJECTION);
qglDisable (GL_LIGHTING);
qglColor4f(1.0, 0.0, 0.0, 0.3);
qglEnable (GL_BLEND);
qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
qglDisable (GL_TEXTURE_2D);
for (brush = pList->next ; brush != pList ; brush=brush->next)
{
if (brush->patchBrush && g_qeglobals.d_select_mode == sel_curvepoint)
continue;
for (face=brush->brush_faces ; face ; face=face->next)
Face_Draw( face );
}
int nCount = g_ptrSelectedFaces.GetSize();
if (nCount > 0)
{
for (int i = 0; i < nCount; i++)
{
face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(i));
Face_Draw(selFace);
}
}
// non-zbuffered outline
qglDisable (GL_BLEND);
qglDisable (GL_DEPTH_TEST);
qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
qglColor3f (1, 1, 1);
for (brush = pList->next ; brush != pList ; brush=brush->next)
{
if (g_qeglobals.dontDrawSelectedOutlines || (brush->patchBrush && g_qeglobals.d_select_mode == sel_curvepoint))
continue;
for (face=brush->brush_faces ; face ; face=face->next)
Face_Draw( face );
}
// edge / vertex flags
if (g_qeglobals.d_select_mode == sel_vertex)
{
qglPointSize (4);
qglColor3f (0,1,0);
qglBegin (GL_POINTS);
for (i=0 ; i<g_qeglobals.d_numpoints ; i++)
qglVertex3fv (g_qeglobals.d_points[i]);
qglEnd ();
qglPointSize (1);
}
else if (g_qeglobals.d_select_mode == sel_edge)
{
float *v1, *v2;
qglPointSize (4);
qglColor3f (0,0,1);
qglBegin (GL_POINTS);
for (i=0 ; i<g_qeglobals.d_numedges ; i++)
{
v1 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p1];
v2 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p2];
qglVertex3f ( (v1[0]+v2[0])*0.5,(v1[1]+v2[1])*0.5,(v1[2]+v2[2])*0.5);
}
qglEnd ();
qglPointSize (1);
}
//
// draw pointfile
//
qglEnable(GL_DEPTH_TEST);
DrawPathLines ();
if (g_qeglobals.d_pointfile_display_list)
{
Pointfile_Draw();
// glCallList (g_qeglobals.d_pointfile_display_list);
}
// bind back to the default texture so that we don't have problems
// elsewhere using/modifying texture maps between contexts
qglBindTexture( GL_TEXTURE_2D, 0 );
#if 0
// area selection hack
if (g_qeglobals.d_select_mode == sel_area)
{
qglEnable (GL_BLEND);
qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
qglColor4f(0.0, 0.0, 1.0, 0.25);
qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
qglRectfv(g_qeglobals.d_vAreaTL, g_qeglobals.d_vAreaBR);
qglDisable (GL_BLEND);
}
#endif
qglFinish();
QE_CheckOpenGLForErrors();
// Sys_EndWait();
if (m_Camera.timing)
{
end = Sys_DoubleTime ();
Sys_Printf ("Camera: %i ms\n", (int)(1000*(end-start)));
}
}
void CCamWnd::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
CRect rect;
GetClientRect(rect);
m_Camera.width = rect.right;
m_Camera.height = rect.bottom;
InvalidateRect(NULL, false);
}
void CCamWnd::BenchMark()
{
PAINTSTRUCT ps;
CRect rct;
GetWindowRect(rct);
long lStyle = ::GetWindowLong(GetSafeHwnd(), GWL_STYLE);
::SetWindowLong(GetSafeHwnd(), GWL_STYLE, QE3_CHILDSTYLE);
CWnd* pParent = GetParent();
SetParent(g_pParentWnd);
MoveWindow(CRect(30, 30, 400, 400), TRUE);
BeginPaint(&ps);
if (!qwglMakeCurrent(ps.hdc, g_qeglobals.d_hglrcBase))
Error ("wglMakeCurrent failed in Benchmark");
qglDrawBuffer (GL_FRONT);
double dStart = Sys_DoubleTime ();
for (int i=0 ; i < 100 ; i++)
{
m_Camera.angles[YAW] = i*4;
Cam_Draw();
}
qwglSwapBuffers(ps.hdc);
qglDrawBuffer (GL_BACK);
double dEnd = Sys_DoubleTime ();
EndPaint(&ps);
Sys_Printf ("%5.2f seconds\n", dEnd - dStart);
::SetWindowLong(GetSafeHwnd(), GWL_STYLE, lStyle);
SetParent(pParent);
MoveWindow(rct, TRUE);
}
void CCamWnd::ReInitGL()
{
qwglMakeCurrent(0,0);
QEW_SetupPixelFormat(GetDC()->m_hDC, true);
if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase))
Error ("wglMakeCurrent failed");
return;
long lStyle = ::GetWindowLong(GetSafeHwnd(), GWL_STYLE);
int nID = ::GetWindowLong(GetSafeHwnd(), GWL_ID);
CWnd* pParent = GetParent();
CRect rctClient;
GetClientRect(rctClient);
DestroyWindow();
Create(CAMERA_WINDOW_CLASS, "", lStyle, rctClient, pParent, nID);
}
void CCamWnd::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags, false);
}
// Timo
// brush primitive texture shifting, using camera view to select translations :
void CCamWnd::ShiftTexture_BrushPrimit(face_t *f, int x, int y)
{
vec3_t texS,texT;
vec3_t viewX,viewY;
int XS,XT,YS,YT;
int outS,outT;
#ifdef _DEBUG
if (!g_qeglobals.m_bBrushPrimitMode)
{
Sys_Printf("Warning : unexpected call to CCamWnd::ShiftTexture_BrushPrimit with brush primitive mode disbaled\n");
return;
}
#endif
// compute face axis base
ComputeAxisBase( f->plane.normal, texS, texT );
// compute camera view vectors
VectorCopy( m_Camera.vup, viewY );
VectorCopy( m_Camera.vright, viewX );
// compute best vectors
ComputeBest2DVector( viewX, texS, texT, XS, XT );
ComputeBest2DVector( viewY, texS, texT, YS, YT );
// check this is not a degenerate case
if ( ( XS == YS ) && ( XT == YT ) )
{
#ifdef _DEBUG
Sys_Printf("Warning : degenerate best vectors axis base in CCamWnd::ShiftTexture_BrushPrimit\n");
#endif
// forget it
Select_ShiftTexture_BrushPrimit( f, x, y );
return;
}
// compute best fitted translation in face axis base
outS = XS*x + YS*y;
outT = XT*x + YT*y;
// call actual texture shifting code
Select_ShiftTexture_BrushPrimit( f, outS, outT );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -