dhewm3/neo/tools/radiant/GLWidget.cpp
Daniel Gibson 5c1e1d7708 Fix ParticleEditor's Materialpicker screwing up ViewPort
In short, it uses a idGLDrawableMaterial widget that calls
renderSystem->BeginFrame(w, h); (with w and h being small for the texture
preview window) and BeginFrame() sets glConfig.vidWidth and vidHeight to
w/h and that never got reset to the original value (window width/height).
This breaks everything because for some reason
renderSystem->GetSCreenWidth()/Height() return glConfig.vidWidth/Height
so it will just continue to render everything at that resolution (in a
small rectangle on the lower left corner of the window).
This bug has already existed in Doom3 1.3.1 (but was less noticable because
apparently  when switching away from Doom3 and back to the window it reset
vidWidth/Height to the window resolution)
I only implemented a workaround (restore glConfig.vid* after rendering the
texture preview), it's possible that the same issue exists in other
(probably editor-) code - but a "proper fix" might also break code (and I'm
not super-familiar with the editor code or even just using them)
2019-03-10 05:23:06 +01:00

953 lines
22 KiB
C++

/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "tools/edit_gui_common.h"
#include "qe3.h"
#include "Radiant.h"
#include "GLWidget.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// idGLWidget
class idMiniDrawVert {
public:
idVec3 xyz;
idVec2 st;
idMiniDrawVert(float x, float y, float z, float s, float t) : xyz(x,y,z), st(s, t) {
};
};
static idMiniDrawVert cubeData[] = {
idMiniDrawVert(-1.0, -1.0, +1.0, 0.0, 0.0),
idMiniDrawVert(+1.0, -1.0, +1.0, 1.0, 0.0),
idMiniDrawVert(+1.0, +1.0, +1.0, 1.0, 1.0),
idMiniDrawVert(-1.0, +1.0, +1.0, 0.0, 1.0),
idMiniDrawVert(-1.0, -1.0, -1.0, 1.0, 0.0),
idMiniDrawVert(-1.0, +1.0, +1.0, 1.0, 1.0),
idMiniDrawVert(+1.0, +1.0, -1.0, 0.0, 1.0),
idMiniDrawVert(+1.0, -1.0, -1.0, 0.0, 0.0),
idMiniDrawVert(-1.0, +1.0, -1.0, 0.0, 1.0),
idMiniDrawVert(-1.0, +1.0, +1.0, 0.0, 0.0),
idMiniDrawVert(+1.0, +1.0, +1.0, 1.0, 0.0),
idMiniDrawVert(+1.0, +1.0, -1.0, 1.0, 1.0),
idMiniDrawVert(-1.0, -1.0, -1.0, 1.0, 1.0),
idMiniDrawVert(+1.0, -1.0, -1.0, 0.0, 1.0),
idMiniDrawVert(+1.0, -1.0, +1.0, 0.0, 0.0),
idMiniDrawVert(-1.0, -1.0, +1.0, 1.0, 0.0),
idMiniDrawVert(+1.0, -1.0, -1.0, 1.0, 0.0),
idMiniDrawVert(+1.0, +1.0, -1.0, 1.0, 1.0),
idMiniDrawVert(+1.0, +1.0, +1.0, 0.0, 1.0),
idMiniDrawVert(+1.0, -1.0, +1.0, 0.0, 0.0),
idMiniDrawVert(-1.0, -1.0, -1.0, 0.0, 0.0),
idMiniDrawVert(-1.0, -1.0, +1.0, 1.0, 0.0),
idMiniDrawVert(-1.0, +1.0, +1.0, 1.0, 1.0),
idMiniDrawVert(-1.0, +1.0, -1.0, 0.0, 1.0)
};
static int cubeSides = sizeof(cubeData) / sizeof(idMiniDrawVert);
static int numQuads = cubeSides / 4;
void glTexturedBox(idVec3 &point, float size, const idMaterial *mat) {
qglTranslatef(point.x, point.y, point.z);
for (int i = 0; i < numQuads; i++) {
qglBegin(GL_QUADS);
for (int j = 0; j < 4; j++) {
idVec3 v = cubeData[i * 4 + j].xyz;
v *= size;
qglTexCoord2fv(cubeData[i * 4 + j].st.ToFloatPtr());
qglVertex3fv(v.ToFloatPtr());
}
qglEnd();
}
}
idGLWidget::idGLWidget()
{
initialized = false;
drawable = NULL;
}
idGLWidget::~idGLWidget()
{
}
BEGIN_MESSAGE_MAP(idGLWidget, CWnd)
//{{AFX_MSG_MAP(idGLWidget)
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MBUTTONDOWN()
ON_WM_MBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_MOUSEWHEEL()
ON_WM_RBUTTONDOWN()
ON_WM_RBUTTONUP()
ON_WM_TIMER()
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// idGLWidget message handlers
BOOL idGLWidget::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Add your specialized code here and/or call the base class
return CWnd::PreCreateWindow(cs);
}
BOOL idGLWidget::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
{
if (CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext) == -1) {
return FALSE;
}
CDC *dc = GetDC();
QEW_SetupPixelFormat(dc->m_hDC, false);
ReleaseDC(dc);
return TRUE;
}
void idGLWidget::OnPaint()
{
if (!initialized) {
CDC *dc = GetDC();
QEW_SetupPixelFormat(dc->m_hDC, false);
ReleaseDC(dc);
initialized = true;
}
CPaintDC dc(this); // device context for painting
CRect rect;
GetClientRect(rect);
if (!qwglMakeCurrent(dc.m_hDC, win32.hGLRC)) {
}
qglViewport(0, 0, rect.Width(), rect.Height());
qglScissor(0, 0, rect.Width(), rect.Height());
qglMatrixMode(GL_PROJECTION);
qglLoadIdentity();
qglClearColor (0.4f, 0.4f, 0.4f, 0.7f);
qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
qglDisable(GL_DEPTH_TEST);
qglDisable(GL_BLEND);
qglOrtho(0, rect.Width(), 0, rect.Height(), -256, 256);
if (drawable) {
drawable->draw(1, 1, rect.Width()-1, rect.Height()-1);
} else {
qglViewport(0, 0, rect.Width(), rect.Height());
qglScissor(0, 0, rect.Width(), rect.Height());
qglMatrixMode(GL_PROJECTION);
qglLoadIdentity();
qglClearColor (0.4f, 0.4f, 0.4f, 0.7f);
qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
qwglSwapBuffers(dc);
qglFlush();
qwglMakeCurrent(win32.hDC, win32.hGLRC);
}
extern bool Sys_KeyDown(int key);
void idGLDrawable::buttonDown(int _button, float x, float y) {
pressX = x;
pressY = y;
button = _button;
if (button == MK_RBUTTON) {
handleMove = true;
}
}
void idGLDrawable::buttonUp(int button, float x, float y) {
handleMove = false;
}
extern float fDiff(float f1, float f2);
void idGLDrawable::mouseMove(float x, float y) {
if (handleMove) {
Update();
if (Sys_KeyDown(VK_MENU)) {
// scale
float *px = &x;
float *px2 = &pressX;
if (fDiff(y, pressY) > fDiff(x, pressX)) {
px = &y;
px2 = &pressY;
}
if (*px > *px2) {
// zoom in
scale += 0.1f;
if ( scale > 10.0f ) {
scale = 10.0f;
}
} else if (*px < *px2) {
// zoom out
scale -= 0.1f;
if ( scale <= 0.001f ) {
scale = 0.001f;
}
}
*px2 = *px;
::SetCursorPos(pressX, pressY);
} else if (Sys_KeyDown(VK_SHIFT)) {
// rotate
} else {
// origin
if (x != pressX) {
xOffset += (x - pressX);
pressX = x;
}
if (y != pressY) {
yOffset -= (y - pressY);
pressY = y;
}
//::SetCursorPos(pressX, pressY);
}
}
}
void idGLDrawable::draw(int x, int y, int w, int h) {
GL_State( GLS_DEFAULT );
qglViewport(x, y, w, h);
qglScissor(x, y, w, h);
qglMatrixMode(GL_PROJECTION);
qglClearColor( 0.1f, 0.1f, 0.1f, 0.0f );
qglClear(GL_COLOR_BUFFER_BIT);
qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
qglLineWidth(0.5);
qglColor3f(1, 1, 1);
globalImages->BindNull();
qglBegin(GL_LINE_LOOP);
qglColor3f(1, 0, 0);
qglVertex2f(x + 3, y + 3);
qglColor3f(0, 1, 0);
qglVertex2f(x + 3, h - 3);
qglColor3f(0, 0, 1);
qglVertex2f(w - 3, h - 3);
qglColor3f(1, 1, 1);
qglVertex2f(w - 3, y + 3);
qglEnd();
}
static int viewAngle = -98;
void idGLDrawableMaterial::buttonDown(int button, float x, float y) {
idGLDrawable::buttonDown(button, x, y);
//viewAngle += (button == MK_LBUTTON) ? 15 : -15;
}
void idGLDrawableMaterial::mouseMove(float x, float y) {
if (handleMove) {
Update();
bool doScale = Sys_KeyDown(VK_MENU);
bool doLight = Sys_KeyDown(VK_SHIFT);
if (doScale || doLight) {
// scale
float *px = &x;
float *px2 = &pressX;
if (fDiff(y, pressY) > fDiff(x, pressX)) {
px = &y;
px2 = &pressY;
}
if (*px > *px2) {
// zoom in
if (doScale) {
scale += 0.1f;
if ( scale > 10.0f ) {
scale = 10.0f;
}
} else {
light += 0.05f;
if ( light > 2.0f ) {
light = 2.0f;
}
}
} else if (*px < *px2) {
// zoom out
if (doScale) {
scale -= 0.1f;
if ( scale <= 0.001f ) {
scale = 0.001f;
}
} else {
light -= 0.05f;
if ( light < 0.0f ) {
light = 0.0f;
}
}
}
*px2 = *px;
::SetCursorPos(pressX, pressY);
} else {
// origin
if (x != pressX) {
xOffset += (x - pressX);
pressX = x;
}
if (y != pressY) {
yOffset -= (y - pressY);
pressY = y;
}
//::SetCursorPos(pressX, pressY);
}
}
}
void idGLDrawableMaterial::draw(int x, int y, int w, int h) {
const idMaterial *mat = material;
if (mat) {
qglViewport(x, y, w, h);
qglScissor(x, y, w, h);
qglMatrixMode(GL_PROJECTION);
qglClearColor( 0.1f, 0.1f, 0.1f, 0.0f );
qglClear(GL_COLOR_BUFFER_BIT);
if (worldDirty) {
InitWorld();
renderLight_t parms;
idDict spawnArgs;
spawnArgs.Set("classname", "light");
spawnArgs.Set("name", "light_1");
spawnArgs.Set("origin", "0 0 0");
idStr str;
sprintf(str, "%f %f %f", light, light, light);
spawnArgs.Set("_color", str);
gameEdit->ParseSpawnArgsToRenderLight( &spawnArgs, &parms );
lightDef = world->AddLightDef( &parms );
idImage *img = (mat->GetNumStages() > 0) ? mat->GetStage(0)->texture.image : mat->GetEditorImage();
if (img == NULL) {
common->Warning("Unable to load image for preview for %s", mat->GetName());
return;
}
int width = img->uploadWidth;
int height = img->uploadHeight;
width *= scale;
height *= scale;
srfTriangles_t *tris = worldModel->AllocSurfaceTriangles( 4, 6 );
tris->numVerts = 4;
tris->numIndexes = 6;
tris->indexes[0] = 0;
tris->indexes[1] = 1;
tris->indexes[2] = 2;
tris->indexes[3] = 3;
tris->indexes[4] = 1;
tris->indexes[5] = 0;
tris->verts[0].xyz.x = 64;
tris->verts[0].xyz.y = -xOffset + 0 - width / 2;
tris->verts[0].xyz.z = yOffset + 0 - height / 2;
tris->verts[0].st.x = 1;
tris->verts[0].st.y = 1;
tris->verts[1].xyz.x = 64;
tris->verts[1].xyz.y = -xOffset + width / 2;
tris->verts[1].xyz.z = yOffset + height / 2;
tris->verts[1].st.x = 0;
tris->verts[1].st.y = 0;
tris->verts[2].xyz.x = 64;
tris->verts[2].xyz.y = -xOffset + 0 - width / 2;
tris->verts[2].xyz.z = yOffset + height / 2;
tris->verts[2].st.x = 1;
tris->verts[2].st.y = 0;
tris->verts[3].xyz.x = 64;
tris->verts[3].xyz.y = -xOffset + width / 2;
tris->verts[3].xyz.z = yOffset + 0 - height / 2;
tris->verts[3].st.x = 0;
tris->verts[3].st.y = 1;
tris->verts[0].normal = tris->verts[1].xyz.Cross(tris->verts[3].xyz);
tris->verts[1].normal = tris->verts[2].normal = tris->verts[3].normal = tris->verts[0].normal;
AddTris(tris, mat);
worldModel->FinishSurfaces();
renderEntity_t worldEntity;
memset( &worldEntity, 0, sizeof( worldEntity ) );
if ( mat->HasGui() ) {
worldEntity.gui[ 0 ] = mat->GlobalGui();
}
worldEntity.hModel = worldModel;
worldEntity.axis = mat3_default;
worldEntity.shaderParms[0] = 1;
worldEntity.shaderParms[1] = 1;
worldEntity.shaderParms[2] = 1;
worldEntity.shaderParms[3] = 1;
modelDef = world->AddEntityDef( &worldEntity );
worldDirty = false;
}
renderView_t refdef;
// DG: renderSystem->BeginFrame() changes glConfig.vidWidth and vidHeight to w and h
// that is never reset automatically and for some reason glConfig.vidWith/height is even
// used for renderSystem->GetScreenWidth()/Height() so idSessionLocal::UpdateScreen()
// which calls renderSystem->BeginFrame( renderSystem->GetScreenWidth(), renderSystem->GetScreenHeight() );
// won't reset those values to something sane either, causing the game to be rendered in a tiny rectangle
// at the lower left corner of the screen once we're done picking a material here..
// I don't dare to fix this in renderSystem, as other code might rely on this behavior..
// (OTOH I wouldn't be surprised if other callers of renderSystem->BeginFrame() cause the same issue)
// Anyway, my workaround is to remember glConfig.vidWith/Height and set them to the original
// values once we're done rendering here..
int oldWidth = glConfig.vidWidth;
int oldHeight = glConfig.vidHeight;
// render it
renderSystem->BeginFrame(w, h);
memset( &refdef, 0, sizeof( refdef ) );
refdef.vieworg.Set(viewAngle, 0, 0);
refdef.viewaxis = idAngles(0,0,0).ToMat3();
refdef.shaderParms[0] = 1;
refdef.shaderParms[1] = 1;
refdef.shaderParms[2] = 1;
refdef.shaderParms[3] = 1;
refdef.width = SCREEN_WIDTH;
refdef.height = SCREEN_HEIGHT;
refdef.fov_x = 90;
refdef.fov_y = 2 * atan((float)h / w) * idMath::M_RAD2DEG;
refdef.time = eventLoop->Milliseconds();
world->RenderScene( &refdef );
int frontEnd, backEnd;
renderSystem->EndFrame( &frontEnd, &backEnd );
qglMatrixMode( GL_MODELVIEW );
qglLoadIdentity();
// DG: reset glConfig.vidWidth/Height
glConfig.vidWidth = oldWidth;
glConfig.vidHeight = oldHeight;
}
}
void idGLDrawableMaterial::setMedia(const char *name) {
idImage *img = NULL;
if (name && *name) {
material = declManager->FindMaterial(name);
if (material) {
const shaderStage_t *stage = (material->GetNumStages() > 0) ? material->GetStage(0) : NULL;
if (stage) {
img = stage->texture.image;
} else {
img = material->GetEditorImage();
}
}
} else {
material = NULL;
}
// set scale to get a good fit
if (material && img) {
float size = (img->uploadWidth > img->uploadHeight) ? img->uploadWidth : img->uploadHeight;
// use 128 as base scale of 1.0
scale = 128.0 / size;
} else {
scale = 1.0;
}
xOffset = 0.0;
yOffset = 0.0;
worldDirty = true;
}
idGLDrawableModel::idGLDrawableModel(const char *name) {
worldModel = renderModelManager->FindModel( name );
light = 1.0;
worldDirty = true;
}
idGLDrawableModel::idGLDrawableModel() {
worldModel = renderModelManager->DefaultModel();
light = 1.0;
}
void idGLDrawableModel::setMedia(const char *name) {
worldModel = renderModelManager->FindModel(name);
worldDirty = true;
xOffset = 0.0;
yOffset = 0.0;
zOffset = -128;
rotation.Set( 0.0f, 0.0f, 0.0f, 1.0f );
radius = 2.6f;
lastPress.Zero();
}
void idGLDrawableModel::SetSkin( const char *skin ) {
skinStr = skin;
}
void idGLDrawableModel::buttonDown(int _button, float x, float y) {
pressX = x;
pressY = y;
lastPress.y = -( float )( 2 * x - rect.z ) / rect.z;
lastPress.x = -( float )( 2 * y - rect.w ) / rect.w;
lastPress.z = 0.0f;
button = _button;
if (button == MK_RBUTTON || button == MK_LBUTTON) {
handleMove = true;
}
}
void idGLDrawableModel::mouseMove(float x, float y) {
if (handleMove) {
Update();
if (button == MK_LBUTTON) {
float cury = ( float )( 2 * x - rect.z ) / rect.z;
float curx = ( float )( 2 * y - rect.w ) / rect.w;
idVec3 to( -curx, -cury, 0.0f );
to.ProjectSelfOntoSphere( radius );
lastPress.ProjectSelfOntoSphere( radius );
idVec3 axis;
axis.Cross( to, lastPress );
float len = ( lastPress - to ).Length() / ( 2.0f * radius );
len = idMath::ClampFloat( -1.0f, 1.0f, len );
float phi = 2.0f * asin ( len ) ;
axis.Normalize();
axis *= sin( phi / 2.0f );
idQuat rot( axis.z, axis.y, axis.x, cos( phi / 2.0f ) );
rot.Normalize();
rotation *= rot;
rotation.Normalize();
lastPress = to;
lastPress.z = 0.0f;
} else {
bool doScale = Sys_KeyDown(VK_MENU);
bool doLight = Sys_KeyDown(VK_SHIFT);
if (doLight) {
// scale
float *px = &x;
float *px2 = &pressX;
if (fDiff(y, pressY) > fDiff(x, pressX)) {
px = &y;
px2 = &pressY;
}
if (*px > *px2) {
light += 0.05f;
if ( light > 2.0f ) {
light = 2.0f;
}
} else if (*px < *px2) {
light -= 0.05f;
if ( light < 0.0f ) {
light = 0.0f;
}
}
*px2 = *px;
::SetCursorPos(pressX, pressY);
} else {
// origin
if (x != pressX) {
if (doScale) {
zOffset += (x - pressX);
} else {
xOffset += (x - pressX);
}
pressX = x;
}
if (y != pressY) {
if (doScale) {
zOffset -= (y - pressY);
} else {
yOffset -= (y - pressY);
}
pressY = y;
}
//::SetCursorPos(pressX, pressY);
}
}
}
}
void idGLDrawableModel::draw(int x, int y, int w, int h) {
if ( !worldModel ) {
return;
}
if ( worldModel->IsDynamicModel() != DM_STATIC ) {
//return;
}
rect.Set( x, y, w, h );
qglViewport(x, y, w, h);
qglScissor(x, y, w, h);
qglMatrixMode(GL_PROJECTION);
qglClearColor( 0.1f, 0.1f, 0.1f, 0.0f );
qglClear(GL_COLOR_BUFFER_BIT);
if (worldDirty) {
//InitWorld();
world->InitFromMap( NULL );
renderLight_t parms;
idDict spawnArgs;
spawnArgs.Set("classname", "light");
spawnArgs.Set("name", "light_1");
spawnArgs.Set("origin", "-128 0 0");
idStr str;
sprintf(str, "%f %f %f", light, light, light);
spawnArgs.Set("_color", str);
gameEdit->ParseSpawnArgsToRenderLight( &spawnArgs, &parms );
lightDef = world->AddLightDef( &parms );
renderEntity_t worldEntity;
memset( &worldEntity, 0, sizeof( worldEntity ) );
spawnArgs.Clear();
spawnArgs.Set("classname", "func_static");
spawnArgs.Set("name", spawnArgs.GetString("model"));
spawnArgs.Set("origin", "0 0 0");
if ( skinStr.Length() ) {
spawnArgs.Set( "skin", skinStr );
}
gameEdit->ParseSpawnArgsToRenderEntity(&spawnArgs, &worldEntity);
worldEntity.hModel = worldModel;
worldEntity.axis = rotation.ToMat3();
worldEntity.shaderParms[0] = 1;
worldEntity.shaderParms[1] = 1;
worldEntity.shaderParms[2] = 1;
worldEntity.shaderParms[3] = 1;
modelDef = world->AddEntityDef( &worldEntity );
worldDirty = false;
}
renderView_t refdef;
// render it
renderSystem->BeginFrame(w, h);
memset( &refdef, 0, sizeof( refdef ) );
refdef.vieworg.Set(zOffset, xOffset, -yOffset);
refdef.viewaxis = idAngles(0,0,0).ToMat3();
refdef.shaderParms[0] = 1;
refdef.shaderParms[1] = 1;
refdef.shaderParms[2] = 1;
refdef.shaderParms[3] = 1;
refdef.width = SCREEN_WIDTH;
refdef.height = SCREEN_HEIGHT;
refdef.fov_x = 90;
refdef.fov_y = 2 * atan((float)h / w) * idMath::M_RAD2DEG;
refdef.time = eventLoop->Milliseconds();
world->RenderScene( &refdef );
int frontEnd, backEnd;
renderSystem->EndFrame( &frontEnd, &backEnd );
qglMatrixMode( GL_MODELVIEW );
qglLoadIdentity();
}
void idGLWidget::OnLButtonDown(UINT nFlags, CPoint point)
{
SetCapture();
if (drawable) {
if ( drawable->ScreenCoords() ) {
ClientToScreen(&point);
}
drawable->buttonDown(MK_LBUTTON, point.x, point.y);
}
}
void idGLWidget::OnLButtonUp(UINT nFlags, CPoint point)
{
if (drawable) {
if ( drawable->ScreenCoords() ) {
ClientToScreen(&point);
}
drawable->buttonUp(MK_LBUTTON, point.x, point.y);
}
ReleaseCapture();
}
void idGLWidget::OnMButtonDown(UINT nFlags, CPoint point)
{
SetCapture();
if (drawable) {
if ( drawable->ScreenCoords() ) {
ClientToScreen(&point);
}
drawable->buttonDown(MK_MBUTTON, point.x, point.y);
}
}
void idGLWidget::OnMButtonUp(UINT nFlags, CPoint point)
{
if (drawable) {
if ( drawable->ScreenCoords() ) {
ClientToScreen(&point);
}
drawable->buttonUp(MK_MBUTTON, point.x, point.y);
}
ReleaseCapture();
}
void idGLWidget::OnMouseMove(UINT nFlags, CPoint point)
{
if (drawable) {
if ( drawable->ScreenCoords() ) {
ClientToScreen(&point);
}
drawable->mouseMove(point.x, point.y);
RedrawWindow();
}
}
BOOL idGLWidget::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
if (drawable) {
float f = drawable->getScale();
if ( zDelta > 0.0f ) {
f += 0.1f;
} else {
f -= 0.1f;
}
if ( f <= 0.0f ) {
f = 0.1f;
}
if ( f > 5.0f ) {
f = 5.0f;
}
drawable->setScale(f);
}
return TRUE;
}
void idGLWidget::OnRButtonDown(UINT nFlags, CPoint point)
{
SetCapture();
if (drawable) {
if ( drawable->ScreenCoords() ) {
ClientToScreen(&point);
}
drawable->buttonDown(MK_RBUTTON, point.x, point.y);
}
}
void idGLWidget::OnRButtonUp(UINT nFlags, CPoint point)
{
if (drawable) {
if ( drawable->ScreenCoords() ) {
ClientToScreen(&point);
}
drawable->buttonUp(MK_RBUTTON, point.x, point.y);
}
ReleaseCapture();
}
void idGLWidget::setDrawable(idGLDrawable *d) {
drawable = d;
if (d->getRealTime()) {
SetTimer(1, d->getRealTime(), NULL);
}
}
void idGLWidget::OnTimer(UINT nIDEvent) {
if (drawable && drawable->getRealTime()) {
Invalidate(FALSE);
} else {
KillTimer(1);
}
}
idGLDrawable::idGLDrawable() {
scale = 1.0;
xOffset = 0.0;
yOffset = 0.0;
handleMove = false;
realTime = 0;
}
void idGLDrawableConsole::draw(int x, int y, int w, int h) {
qglPushAttrib( GL_ALL_ATTRIB_BITS );
qglClearColor( 0.1f, 0.1f, 0.1f, 0.0f );
qglScissor( 0, 0, w, h );
qglClear( GL_COLOR_BUFFER_BIT );
renderSystem->BeginFrame( w, h );
console->Draw( true );
renderSystem->EndFrame( NULL, NULL );
qglPopAttrib();
}
void idGLConsoleWidget::init() {
setDrawable(&console);
}
void idGLConsoleWidget::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
sysEvent_t ev;
memset( &ev, 0, sizeof( ev ) );
ev.evType = SE_KEY;
ev.evValue2 = 1;
ev.evValue = nChar;
::console->ProcessEvent( &ev, true );
}
BEGIN_MESSAGE_MAP(idGLConsoleWidget, idGLWidget)
//{{AFX_MSG_MAP(idGLConsoleWidget)
ON_WM_PAINT()
ON_WM_KEYDOWN()
ON_WM_KEYUP()
ON_WM_CHAR()
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void idGLConsoleWidget::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
sysEvent_t ev;
memset( &ev, 0, sizeof( ev ) );
ev.evType = SE_KEY;
ev.evValue2 = 0;
ev.evValue = nChar;
::console->ProcessEvent( &ev, true );
}
void idGLConsoleWidget::OnPaint() {
idGLWidget::OnPaint();
}
void idGLConsoleWidget::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
sysEvent_t ev;
memset( &ev, 0, sizeof( ev ) );
ev.evType = SE_CHAR;
ev.evValue = nChar;
::console->ProcessEvent( &ev, true );
}
void idGLConsoleWidget::OnLButtonDown(UINT nFlags, CPoint point) {
SetFocus();
}
BOOL idGLWidget::OnEraseBkgnd(CDC* pDC)
{
return FALSE;
//return CWnd::OnEraseBkgnd(pDC);
}
idGLDrawableWorld::idGLDrawableWorld() {
world = NULL;
worldModel = NULL;
InitWorld();
}
idGLDrawableWorld::~idGLDrawableWorld() {
delete world;
}
void idGLDrawableWorld::AddTris(srfTriangles_t *tris, const idMaterial *mat) {
modelSurface_t surf;
surf.geometry = tris;
surf.shader = mat;
worldModel->AddSurface( surf );
}
void idGLDrawableWorld::draw(int x, int y, int w, int h) {
}
void idGLDrawableWorld::InitWorld() {
if ( world == NULL ) {
world = renderSystem->AllocRenderWorld();
}
if ( worldModel == NULL ) {
worldModel = renderModelManager->AllocModel();
}
world->InitFromMap( NULL );
worldModel->InitEmpty( va( "GLWorldModel_%i", Sys_Milliseconds() ) );
}