]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/tools/radiant/GLWidget.cpp
Various Mac OS X tweaks to get this to build. Probably breaking things.
[icculus/iodoom3.git] / neo / tools / radiant / GLWidget.cpp
1 /*
2 ===========================================================================
3
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. 
6
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).  
8
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code.  If not, see <http://www.gnu.org/licenses/>.
21
22 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.
23
24 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.
25
26 ===========================================================================
27 */
28
29 #include "../../idlib/precompiled.h"
30 #pragma hdrstop
31
32 #include "qe3.h"
33 #include "Radiant.h"
34 #include "GLWidget.h"
35
36 #ifdef _DEBUG
37 #define new DEBUG_NEW
38 #undef THIS_FILE
39 static char THIS_FILE[] = __FILE__;
40 #endif
41
42
43
44 /////////////////////////////////////////////////////////////////////////////
45 // idGLWidget
46 class idMiniDrawVert {
47 public:
48         idVec3 xyz;
49         idVec2 st;
50         idMiniDrawVert(float x, float y, float z, float s, float t) : xyz(x,y,z), st(s, t) {
51         };
52 };
53
54 static idMiniDrawVert cubeData[] = {
55         idMiniDrawVert(-1.0, -1.0, +1.0, 0.0, 0.0),
56         idMiniDrawVert(+1.0, -1.0, +1.0, 1.0, 0.0),
57         idMiniDrawVert(+1.0, +1.0, +1.0, 1.0, 1.0),
58         idMiniDrawVert(-1.0, +1.0, +1.0, 0.0, 1.0),
59
60         idMiniDrawVert(-1.0, -1.0, -1.0, 1.0, 0.0),
61         idMiniDrawVert(-1.0, +1.0, +1.0, 1.0, 1.0),
62         idMiniDrawVert(+1.0, +1.0, -1.0, 0.0, 1.0),
63         idMiniDrawVert(+1.0, -1.0, -1.0, 0.0, 0.0),
64
65         idMiniDrawVert(-1.0, +1.0, -1.0, 0.0, 1.0),
66         idMiniDrawVert(-1.0, +1.0, +1.0, 0.0, 0.0),
67         idMiniDrawVert(+1.0, +1.0, +1.0, 1.0, 0.0),
68         idMiniDrawVert(+1.0, +1.0, -1.0, 1.0, 1.0),
69
70         idMiniDrawVert(-1.0, -1.0, -1.0, 1.0, 1.0),
71         idMiniDrawVert(+1.0, -1.0, -1.0, 0.0, 1.0),
72         idMiniDrawVert(+1.0, -1.0, +1.0, 0.0, 0.0),
73         idMiniDrawVert(-1.0, -1.0, +1.0, 1.0, 0.0),
74
75         idMiniDrawVert(+1.0, -1.0, -1.0, 1.0, 0.0),
76         idMiniDrawVert(+1.0, +1.0, -1.0, 1.0, 1.0),
77         idMiniDrawVert(+1.0, +1.0, +1.0, 0.0, 1.0),
78         idMiniDrawVert(+1.0, -1.0, +1.0, 0.0, 0.0),
79
80         idMiniDrawVert(-1.0, -1.0, -1.0, 0.0, 0.0),
81         idMiniDrawVert(-1.0, -1.0, +1.0, 1.0, 0.0),
82         idMiniDrawVert(-1.0, +1.0, +1.0, 1.0, 1.0),
83         idMiniDrawVert(-1.0, +1.0, -1.0, 0.0, 1.0)
84 };
85
86 static int cubeSides = sizeof(cubeData) / sizeof(idMiniDrawVert);
87 static int numQuads = cubeSides / 4;
88
89 void glTexturedBox(idVec3 &point, float size, const idMaterial *mat) {
90         qglTranslatef(point.x, point.y, point.z);
91         for (int i = 0; i < numQuads; i++) {
92                 qglBegin(GL_QUADS);
93                 for (int j = 0; j < 4; j++) {
94                         idVec3 v = cubeData[i * 4 + j].xyz;
95                         v *= size;
96                         qglTexCoord2fv(cubeData[i * 4 + j].st.ToFloatPtr());
97                         qglVertex3fv(v.ToFloatPtr());
98                 }
99                 qglEnd();
100         }
101 }
102
103 idGLWidget::idGLWidget()
104 {
105         initialized = false;
106         drawable = NULL;
107 }
108
109 idGLWidget::~idGLWidget()
110 {
111 }
112
113
114 BEGIN_MESSAGE_MAP(idGLWidget, CWnd)
115         //{{AFX_MSG_MAP(idGLWidget)
116         ON_WM_PAINT()
117         ON_WM_LBUTTONDOWN()
118         ON_WM_LBUTTONUP()
119         ON_WM_MBUTTONDOWN()
120         ON_WM_MBUTTONUP()
121         ON_WM_MOUSEMOVE()
122         ON_WM_MOUSEWHEEL()
123         ON_WM_RBUTTONDOWN()
124         ON_WM_RBUTTONUP()
125         ON_WM_TIMER()
126         ON_WM_ERASEBKGND()
127         //}}AFX_MSG_MAP
128 END_MESSAGE_MAP()
129
130 /////////////////////////////////////////////////////////////////////////////
131 // idGLWidget message handlers
132
133 BOOL idGLWidget::PreCreateWindow(CREATESTRUCT& cs) 
134 {
135         // TODO: Add your specialized code here and/or call the base class
136         
137         return CWnd::PreCreateWindow(cs);
138 }
139
140 BOOL idGLWidget::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) 
141 {
142         if (CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext) == -1) {
143                 return FALSE;
144         }
145
146         CDC *dc = GetDC();
147         QEW_SetupPixelFormat(dc->m_hDC, false);
148         ReleaseDC(dc);
149
150         return TRUE;
151
152 }
153
154 void idGLWidget::OnPaint() 
155 {
156
157         if (!initialized) {
158                 CDC *dc = GetDC();
159                 QEW_SetupPixelFormat(dc->m_hDC, false);
160                 ReleaseDC(dc);
161                 initialized = true;
162         }
163         CPaintDC dc(this); // device context for painting
164         
165         CRect rect;
166         GetClientRect(rect);
167
168         if (!qwglMakeCurrent(dc.m_hDC, win32.hGLRC)) {
169         }
170
171         qglViewport(0, 0, rect.Width(), rect.Height());
172         qglScissor(0, 0, rect.Width(), rect.Height());
173         qglMatrixMode(GL_PROJECTION);
174         qglLoadIdentity();
175         qglClearColor (0.4f, 0.4f, 0.4f, 0.7f);
176         qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
177
178
179         qglDisable(GL_DEPTH_TEST);
180         qglDisable(GL_BLEND);
181         qglOrtho(0, rect.Width(), 0, rect.Height(), -256, 256);
182
183         if (drawable) {
184                 drawable->draw(1, 1, rect.Width()-1, rect.Height()-1);
185         } else {
186                 qglViewport(0, 0, rect.Width(), rect.Height());
187                 qglScissor(0, 0, rect.Width(), rect.Height());
188                 qglMatrixMode(GL_PROJECTION);
189                 qglLoadIdentity();
190                 qglClearColor (0.4f, 0.4f, 0.4f, 0.7f);
191                 qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
192         }
193
194         qwglSwapBuffers(dc);
195         qglFlush();
196         qwglMakeCurrent(win32.hDC, win32.hGLRC);
197
198 }
199
200 extern bool Sys_KeyDown(int key);
201
202 void idGLDrawable::buttonDown(int _button, float x, float y) {
203         pressX = x;
204         pressY = y;
205         button = _button;
206         if (button == MK_RBUTTON) {
207                 handleMove = true;
208         }
209 }
210
211 void idGLDrawable::buttonUp(int button, float x, float y) {
212         handleMove = false;
213 }
214
215 extern float    fDiff(float f1, float f2);
216 void idGLDrawable::mouseMove(float x, float y) {
217         if (handleMove) {
218                 Update();
219                 if (Sys_KeyDown(VK_MENU)) {
220                         // scale
221                         float *px = &x;
222                         float *px2 = &pressX;
223
224                         if (fDiff(y, pressY) > fDiff(x, pressX)) {
225                                 px = &y;
226                                 px2 = &pressY;
227                         }
228
229                         if (*px > *px2) {
230                                 // zoom in
231                                 scale += 0.1f;
232                                 if ( scale > 10.0f ) {
233                                         scale = 10.0f;
234                                 }
235                         } else if (*px < *px2) {
236                                 // zoom out
237                                 scale -= 0.1f;
238                                 if ( scale <= 0.001f ) {
239                                         scale = 0.001f;
240                                 }
241                         }
242
243                         *px2 = *px;
244                         ::SetCursorPos(pressX, pressY);
245
246                 } else if (Sys_KeyDown(VK_SHIFT)) {
247                         // rotate
248                 } else {
249                         // origin
250                         if (x != pressX) {
251                                 xOffset += (x - pressX);
252                                 pressX = x;
253                         }
254                         if (y != pressY) {
255                                 yOffset -= (y - pressY);
256                                 pressY = y;
257                         }
258                         //::SetCursorPos(pressX, pressY);
259                 }
260         }
261 }
262
263 void idGLDrawable::draw(int x, int y, int w, int h) {
264         GL_State( GLS_DEFAULT );
265         qglViewport(x, y, w, h);
266         qglScissor(x, y, w, h);
267         qglMatrixMode(GL_PROJECTION);
268         qglClearColor( 0.1f, 0.1f, 0.1f, 0.0f );
269         qglClear(GL_COLOR_BUFFER_BIT);
270         qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
271         qglLineWidth(0.5);
272         qglColor3f(1, 1, 1);
273         globalImages->BindNull();
274         qglBegin(GL_LINE_LOOP);
275         qglColor3f(1, 0, 0);
276         qglVertex2f(x + 3, y + 3);
277         qglColor3f(0, 1, 0);
278         qglVertex2f(x + 3, h - 3);
279         qglColor3f(0, 0, 1);
280         qglVertex2f(w - 3, h - 3);
281         qglColor3f(1, 1, 1);
282         qglVertex2f(w - 3, y + 3);
283         qglEnd();
284
285 }
286
287 static int viewAngle = -98;
288 void idGLDrawableMaterial::buttonDown(int button, float x, float y) {
289         idGLDrawable::buttonDown(button, x, y);
290         //viewAngle += (button == MK_LBUTTON) ? 15 : -15;
291 }
292
293
294 void idGLDrawableMaterial::mouseMove(float x, float y) {
295         if (handleMove) {
296                 Update();
297                 bool doScale = Sys_KeyDown(VK_MENU);
298                 bool doLight = Sys_KeyDown(VK_SHIFT);
299                 if (doScale || doLight) {
300                         // scale
301                         float *px = &x;
302                         float *px2 = &pressX;
303
304                         if (fDiff(y, pressY) > fDiff(x, pressX)) {
305                                 px = &y;
306                                 px2 = &pressY;
307                         }
308
309                         if (*px > *px2) {
310                                 // zoom in
311                                 if (doScale) {
312                                         scale += 0.1f;
313                                         if ( scale > 10.0f ) {
314                                                 scale = 10.0f;
315                                         }
316                                 } else {
317                                         light += 0.05f;
318                                         if ( light > 2.0f ) {
319                                                 light = 2.0f;
320                                         }
321                                 }
322                         } else if (*px < *px2) {
323                                 // zoom out
324                                 if (doScale) {
325                                         scale -= 0.1f;
326                                         if ( scale <= 0.001f ) {
327                                                 scale = 0.001f;
328                                         }
329                                 } else {
330                                         light -= 0.05f;
331                                         if ( light < 0.0f ) {
332                                                 light = 0.0f;
333                                         }
334                                 }
335                         }
336                         *px2 = *px;
337                         ::SetCursorPos(pressX, pressY);
338                 } else {
339                         // origin
340                         if (x != pressX) {
341                                 xOffset += (x - pressX);
342                                 pressX = x;
343                         }
344                         if (y != pressY) {
345                                 yOffset -= (y - pressY);
346                                 pressY = y;
347                         }
348                         //::SetCursorPos(pressX, pressY);
349                 }
350         }
351 }
352
353
354 void idGLDrawableMaterial::draw(int x, int y, int w, int h) {
355         const idMaterial *mat = material;
356         if (mat) {
357                 qglViewport(x, y, w, h);
358                 qglScissor(x, y, w, h);
359                 qglMatrixMode(GL_PROJECTION);
360                 qglClearColor( 0.1f, 0.1f, 0.1f, 0.0f );
361                 qglClear(GL_COLOR_BUFFER_BIT);
362
363                 if (worldDirty) {
364                         InitWorld();
365                         renderLight_t   parms;
366                         idDict spawnArgs;
367                         spawnArgs.Set("classname", "light");
368                         spawnArgs.Set("name", "light_1");
369                         spawnArgs.Set("origin", "0 0 0");
370                         idStr str;
371                         sprintf(str, "%f %f %f", light, light, light);
372                         spawnArgs.Set("_color", str);
373                         gameEdit->ParseSpawnArgsToRenderLight( &spawnArgs, &parms );
374                         lightDef = world->AddLightDef( &parms );
375
376                         idImage *img = (mat->GetNumStages() > 0) ? mat->GetStage(0)->texture.image : mat->GetEditorImage();
377
378                         if (img == NULL) {
379                                 common->Warning("Unable to load image for preview for %s", mat->GetName());
380                                 return;
381                         }
382
383                         int width = img->uploadWidth;
384                         int height = img->uploadHeight;
385
386                         width *= scale;
387                         height *= scale;
388
389                         srfTriangles_t *tris = worldModel->AllocSurfaceTriangles( 4, 6 );
390                         tris->numVerts = 4;
391                         tris->numIndexes = 6;
392
393                         tris->indexes[0] = 0;
394                         tris->indexes[1] = 1;
395                         tris->indexes[2] = 2;
396                         tris->indexes[3] = 3;
397                         tris->indexes[4] = 1;
398                         tris->indexes[5] = 0;
399
400                         tris->verts[0].xyz.x = 64;
401                         tris->verts[0].xyz.y = -xOffset + 0 - width / 2;
402                         tris->verts[0].xyz.z = yOffset + 0 - height / 2;
403                         tris->verts[0].st.x = 1;
404                         tris->verts[0].st.y = 1;
405                         
406                         tris->verts[1].xyz.x = 64;
407                         tris->verts[1].xyz.y = -xOffset + width / 2;
408                         tris->verts[1].xyz.z = yOffset + height / 2;
409                         tris->verts[1].st.x = 0;
410                         tris->verts[1].st.y = 0;
411
412                         tris->verts[2].xyz.x = 64;
413                         tris->verts[2].xyz.y = -xOffset + 0 - width / 2;
414                         tris->verts[2].xyz.z = yOffset + height / 2;
415                         tris->verts[2].st.x = 1;
416                         tris->verts[2].st.y = 0;
417
418                         tris->verts[3].xyz.x = 64;
419                         tris->verts[3].xyz.y = -xOffset + width / 2;
420                         tris->verts[3].xyz.z = yOffset + 0 - height / 2;
421                         tris->verts[3].st.x = 0;
422                         tris->verts[3].st.y = 1;
423
424                         tris->verts[0].normal = tris->verts[1].xyz.Cross(tris->verts[3].xyz);
425                         tris->verts[1].normal = tris->verts[2].normal = tris->verts[3].normal = tris->verts[0].normal;
426                         AddTris(tris, mat);
427
428                         worldModel->FinishSurfaces();
429                         
430                         renderEntity_t worldEntity;
431
432                         memset( &worldEntity, 0, sizeof( worldEntity ) );
433                         if ( mat->HasGui() ) {
434                                 worldEntity.gui[ 0 ] = mat->GlobalGui();
435                         }
436                         worldEntity.hModel = worldModel;
437                         worldEntity.axis = mat3_default;
438                         worldEntity.shaderParms[0] = 1;
439                         worldEntity.shaderParms[1] = 1;
440                         worldEntity.shaderParms[2] = 1;
441                         worldEntity.shaderParms[3] = 1;
442                         modelDef = world->AddEntityDef( &worldEntity );
443
444                         worldDirty = false;
445                 }
446                 
447                 renderView_t    refdef;
448                 // render it
449                 renderSystem->BeginFrame(w, h);
450                 memset( &refdef, 0, sizeof( refdef ) );
451                 refdef.vieworg.Set(viewAngle, 0, 0);
452
453                 refdef.viewaxis = idAngles(0,0,0).ToMat3();
454                 refdef.shaderParms[0] = 1;
455                 refdef.shaderParms[1] = 1;
456                 refdef.shaderParms[2] = 1;
457                 refdef.shaderParms[3] = 1;
458
459                 refdef.width = SCREEN_WIDTH;
460                 refdef.height = SCREEN_HEIGHT;
461                 refdef.fov_x = 90;
462                 refdef.fov_y = 2 * atan((float)h / w) * idMath::M_RAD2DEG;
463
464                 refdef.time = eventLoop->Milliseconds();
465
466                 world->RenderScene( &refdef );
467                 int frontEnd, backEnd;
468                 renderSystem->EndFrame( &frontEnd, &backEnd );
469
470                 qglMatrixMode( GL_MODELVIEW );
471                 qglLoadIdentity();
472         }
473
474 }
475
476 void idGLDrawableMaterial::setMedia(const char *name) {
477         idImage *img = NULL;
478         if (name && *name) {
479                 material = declManager->FindMaterial(name);
480                 if (material) {
481                         const shaderStage_t *stage = (material->GetNumStages() > 0) ? material->GetStage(0) : NULL;
482                         if (stage) {
483                                 img = stage->texture.image;
484                         } else {
485                                 img = material->GetEditorImage();
486                         }
487                 }
488         } else {
489                 material = NULL;
490         }
491         // set scale to get a good fit
492
493         if (material && img) {
494
495                 float size = (img->uploadWidth > img->uploadHeight) ? img->uploadWidth : img->uploadHeight;
496                 // use 128 as base scale of 1.0
497                 scale = 128.0 / size;
498         } else {
499                 scale = 1.0;
500         }
501         xOffset = 0.0;
502         yOffset = 0.0;
503         worldDirty = true;
504 }
505
506 idGLDrawableModel::idGLDrawableModel(const char *name) {
507         worldModel = renderModelManager->FindModel( name );
508         light = 1.0;
509         worldDirty = true;
510 }
511
512 idGLDrawableModel::idGLDrawableModel() {
513         worldModel = renderModelManager->DefaultModel();
514         light = 1.0;
515 }
516
517 void idGLDrawableModel::setMedia(const char *name) {
518         worldModel = renderModelManager->FindModel(name);
519         worldDirty = true;
520         xOffset = 0.0;
521         yOffset = 0.0;
522         zOffset = -128;
523         rotation.Set( 0.0f, 0.0f, 0.0f, 1.0f );
524         radius = 2.6f;
525         lastPress.Zero();
526 }
527
528 void idGLDrawableModel::SetSkin( const char *skin ) {
529         skinStr = skin;
530 }
531
532
533 void idGLDrawableModel::buttonDown(int _button, float x, float y) {
534         pressX = x;
535         pressY = y;
536
537         lastPress.y = -( float )( 2 * x - rect.z ) / rect.z;
538         lastPress.x = -( float )( 2 * y - rect.w ) / rect.w;
539         lastPress.z = 0.0f;
540         button = _button;
541         if (button == MK_RBUTTON || button == MK_LBUTTON) {
542                 handleMove = true;
543         }
544 }
545
546 void idGLDrawableModel::mouseMove(float x, float y) {
547         if (handleMove) {
548                 Update();
549                 if (button == MK_LBUTTON) {
550                         float cury = ( float )( 2 * x - rect.z ) / rect.z;
551                         float curx = ( float )( 2 * y - rect.w ) / rect.w;
552                         idVec3 to( -curx, -cury, 0.0f );
553                         to.ProjectSelfOntoSphere( radius );
554                         lastPress.ProjectSelfOntoSphere( radius );
555                         idVec3 axis;
556                         axis.Cross( to, lastPress );
557                         float len = ( lastPress - to ).Length() / ( 2.0f * radius );
558                         len = idMath::ClampFloat( -1.0f, 1.0f, len );
559                         float phi = 2.0f * asin ( len ) ;
560
561                         axis.Normalize();
562                         axis *= sin( phi / 2.0f );
563                         idQuat rot( axis.z, axis.y, axis.x, cos( phi / 2.0f ) );
564                         rot.Normalize();
565
566                         rotation *= rot;
567                         rotation.Normalize();
568
569                         lastPress = to;
570                         lastPress.z = 0.0f;
571                 } else {
572                         bool doScale = Sys_KeyDown(VK_MENU);
573                         bool doLight = Sys_KeyDown(VK_SHIFT);
574                         if (doLight) {
575                                 // scale
576                                 float *px = &x;
577                                 float *px2 = &pressX;
578
579                                 if (fDiff(y, pressY) > fDiff(x, pressX)) {
580                                         px = &y;
581                                         px2 = &pressY;
582                                 }
583
584                                 if (*px > *px2) {
585                                         light += 0.05f;
586                                         if ( light > 2.0f ) {
587                                                 light = 2.0f;
588                                         }
589                                 } else if (*px < *px2) {
590                                         light -= 0.05f;
591                                         if ( light < 0.0f ) {
592                                                 light = 0.0f;
593                                         }
594                                 }
595                                 *px2 = *px;
596                                 ::SetCursorPos(pressX, pressY);
597                         } else {
598                                 // origin
599                                 if (x != pressX) {
600                                         if (doScale) {
601                                                 zOffset += (x - pressX);
602                                         } else {
603                                                 xOffset += (x - pressX);
604                                         }
605                                         pressX = x;
606                                 }
607                                 if (y != pressY) {
608                                         if (doScale) {
609                                                 zOffset -= (y - pressY);
610                                         } else {
611                                                 yOffset -= (y - pressY);
612                                         }
613                                         pressY = y;
614                                 }
615                                 //::SetCursorPos(pressX, pressY);
616                         }
617                 }
618         }
619 }
620
621
622 void idGLDrawableModel::draw(int x, int y, int w, int h) {
623         if ( !worldModel ) {
624                 return;
625         }
626         if ( worldModel->IsDynamicModel() != DM_STATIC ) {
627                 //return;
628         }
629
630         rect.Set( x, y, w, h );
631
632         qglViewport(x, y, w, h);
633         qglScissor(x, y, w, h);
634         qglMatrixMode(GL_PROJECTION);
635         qglClearColor( 0.1f, 0.1f, 0.1f, 0.0f );
636         qglClear(GL_COLOR_BUFFER_BIT);
637
638         if (worldDirty) {
639                 //InitWorld();
640                 world->InitFromMap( NULL );
641                 renderLight_t   parms;
642                 idDict spawnArgs;
643                 spawnArgs.Set("classname", "light");
644                 spawnArgs.Set("name", "light_1");
645                 spawnArgs.Set("origin", "-128 0 0");
646                 idStr str;
647                 sprintf(str, "%f %f %f", light, light, light);
648                 spawnArgs.Set("_color", str);
649                 gameEdit->ParseSpawnArgsToRenderLight( &spawnArgs, &parms );
650                 lightDef = world->AddLightDef( &parms );
651
652                 renderEntity_t worldEntity;
653                 memset( &worldEntity, 0, sizeof( worldEntity ) );
654                 spawnArgs.Clear();
655                 spawnArgs.Set("classname", "func_static");
656                 spawnArgs.Set("name", spawnArgs.GetString("model"));
657                 spawnArgs.Set("origin", "0 0 0");
658                 if ( skinStr.Length() ) {
659                         spawnArgs.Set( "skin", skinStr );
660                 }
661                 gameEdit->ParseSpawnArgsToRenderEntity(&spawnArgs, &worldEntity);
662                 worldEntity.hModel = worldModel;
663
664                 worldEntity.axis = rotation.ToMat3();
665
666                 worldEntity.shaderParms[0] = 1;
667                 worldEntity.shaderParms[1] = 1;
668                 worldEntity.shaderParms[2] = 1;
669                 worldEntity.shaderParms[3] = 1;
670                 modelDef = world->AddEntityDef( &worldEntity );
671
672                 worldDirty = false;
673         }
674                 
675         renderView_t    refdef;
676         // render it
677         renderSystem->BeginFrame(w, h);
678         memset( &refdef, 0, sizeof( refdef ) );
679         refdef.vieworg.Set(zOffset, xOffset, -yOffset);
680
681         refdef.viewaxis = idAngles(0,0,0).ToMat3();
682         refdef.shaderParms[0] = 1;
683         refdef.shaderParms[1] = 1;
684         refdef.shaderParms[2] = 1;
685         refdef.shaderParms[3] = 1;
686
687         refdef.width = SCREEN_WIDTH;
688         refdef.height = SCREEN_HEIGHT;
689         refdef.fov_x = 90;
690         refdef.fov_y = 2 * atan((float)h / w) * idMath::M_RAD2DEG;
691
692         refdef.time = eventLoop->Milliseconds();
693
694         world->RenderScene( &refdef );
695         int frontEnd, backEnd;
696         renderSystem->EndFrame( &frontEnd, &backEnd );
697
698         qglMatrixMode( GL_MODELVIEW );
699         qglLoadIdentity();
700 }
701
702
703
704 void idGLWidget::OnLButtonDown(UINT nFlags, CPoint point) 
705 {
706         SetCapture();
707         if (drawable) {
708                 if ( drawable->ScreenCoords() ) {
709                         ClientToScreen(&point);
710                 }
711                 drawable->buttonDown(MK_LBUTTON, point.x, point.y);
712         }
713 }
714
715 void idGLWidget::OnLButtonUp(UINT nFlags, CPoint point) 
716 {
717         if (drawable) {
718                 if ( drawable->ScreenCoords() ) {
719                         ClientToScreen(&point);
720                 }
721                 drawable->buttonUp(MK_LBUTTON, point.x, point.y);
722         }
723         ReleaseCapture();
724 }
725
726 void idGLWidget::OnMButtonDown(UINT nFlags, CPoint point) 
727 {
728         SetCapture();
729         if (drawable) {
730                 if ( drawable->ScreenCoords() ) {
731                         ClientToScreen(&point);
732                 }
733                 drawable->buttonDown(MK_MBUTTON, point.x, point.y);
734         }
735 }
736
737 void idGLWidget::OnMButtonUp(UINT nFlags, CPoint point) 
738 {
739         if (drawable) {
740                 if ( drawable->ScreenCoords() ) {
741                         ClientToScreen(&point);
742                 }
743                 drawable->buttonUp(MK_MBUTTON, point.x, point.y);
744         }
745         ReleaseCapture();
746 }
747
748 void idGLWidget::OnMouseMove(UINT nFlags, CPoint point) 
749 {
750         if (drawable) {
751                 if ( drawable->ScreenCoords() ) {
752                         ClientToScreen(&point);
753                 }
754                 drawable->mouseMove(point.x, point.y);
755                 RedrawWindow();
756         }
757 }
758
759 BOOL idGLWidget::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) 
760 {
761         if (drawable) {
762                 float f = drawable->getScale();
763                 if ( zDelta > 0.0f ) {
764                         f += 0.1f;
765                 } else {
766                         f -= 0.1f;
767                 }
768                 if ( f <= 0.0f ) {
769                         f = 0.1f;
770                 }
771                 if ( f > 5.0f ) {
772                         f = 5.0f;
773                 }
774                 drawable->setScale(f);
775         }
776         return TRUE;
777 }
778
779 void idGLWidget::OnRButtonDown(UINT nFlags, CPoint point) 
780 {
781         SetCapture();
782         if (drawable) {
783                 if ( drawable->ScreenCoords() ) {
784                         ClientToScreen(&point);
785                 }
786                 drawable->buttonDown(MK_RBUTTON, point.x, point.y);
787         }
788 }
789
790 void idGLWidget::OnRButtonUp(UINT nFlags, CPoint point) 
791 {
792         if (drawable) {
793                 if ( drawable->ScreenCoords() ) {
794                         ClientToScreen(&point);
795                 }
796                 drawable->buttonUp(MK_RBUTTON, point.x, point.y);
797         }
798         ReleaseCapture();
799 }
800
801 void idGLWidget::setDrawable(idGLDrawable *d) {
802         drawable = d;
803         if (d->getRealTime()) {
804                 SetTimer(1, d->getRealTime(), NULL);
805         }
806 }
807
808
809 void idGLWidget::OnTimer(UINT nIDEvent) {
810         if (drawable && drawable->getRealTime()) {
811                 Invalidate(FALSE);
812         } else {
813                 KillTimer(1);
814         }
815 }
816
817
818 idGLDrawable::idGLDrawable() {
819         scale = 1.0;   
820         xOffset = 0.0;
821         yOffset = 0.0;
822         handleMove = false;
823         realTime = 0;
824
825 }
826
827 void idGLDrawableConsole::draw(int x, int y, int w, int h) {
828         qglPushAttrib( GL_ALL_ATTRIB_BITS );
829         qglClearColor( 0.1f, 0.1f, 0.1f, 0.0f );
830         qglScissor( 0, 0, w, h );
831         qglClear( GL_COLOR_BUFFER_BIT );
832         renderSystem->BeginFrame( w, h );
833
834         console->Draw( true );
835
836         renderSystem->EndFrame( NULL, NULL );
837         qglPopAttrib();
838 }
839
840 void idGLConsoleWidget::init() {
841         setDrawable(&console);
842 }
843
844 void idGLConsoleWidget::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
845 {
846         sysEvent_t      ev;
847
848         memset( &ev, 0, sizeof( ev ) );
849         ev.evType = SE_KEY;
850         ev.evValue2 = 1;
851         ev.evValue = nChar;
852
853         ::console->ProcessEvent( &ev, true );
854 }
855
856 BEGIN_MESSAGE_MAP(idGLConsoleWidget, idGLWidget)
857         //{{AFX_MSG_MAP(idGLConsoleWidget)
858         ON_WM_PAINT()
859         ON_WM_KEYDOWN()
860         ON_WM_KEYUP()
861         ON_WM_CHAR()
862         ON_WM_LBUTTONDOWN()
863         //}}AFX_MSG_MAP
864 END_MESSAGE_MAP()
865
866
867
868 void idGLConsoleWidget::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
869 {
870         sysEvent_t      ev;
871
872         memset( &ev, 0, sizeof( ev ) );
873         ev.evType = SE_KEY;
874         ev.evValue2 = 0;
875         ev.evValue = nChar;
876
877         ::console->ProcessEvent( &ev, true );
878 }
879
880 void idGLConsoleWidget::OnPaint() {
881         idGLWidget::OnPaint();
882 }
883
884 void idGLConsoleWidget::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
885 {
886         sysEvent_t      ev;
887
888         memset( &ev, 0, sizeof( ev ) );
889         ev.evType = SE_CHAR;
890         ev.evValue = nChar;
891
892         ::console->ProcessEvent( &ev, true );
893 }
894
895 void idGLConsoleWidget::OnLButtonDown(UINT nFlags, CPoint point) {
896         SetFocus();
897 }
898
899 BOOL idGLWidget::OnEraseBkgnd(CDC* pDC) 
900 {
901         return FALSE;
902         
903         //return CWnd::OnEraseBkgnd(pDC);
904 }
905
906
907 idGLDrawableWorld::idGLDrawableWorld() {
908         world = NULL;
909         worldModel = NULL;
910         InitWorld();
911 }
912
913 idGLDrawableWorld::~idGLDrawableWorld() {
914         delete world;
915 }
916
917 void idGLDrawableWorld::AddTris(srfTriangles_t *tris, const idMaterial *mat) {
918         modelSurface_t  surf;
919         surf.geometry = tris;
920         surf.shader = mat;
921         worldModel->AddSurface( surf );
922 }
923
924 void idGLDrawableWorld::draw(int x, int y, int w, int h) {
925         
926 }
927
928 void idGLDrawableWorld::InitWorld() {
929         if ( world == NULL ) {
930                 world = renderSystem->AllocRenderWorld();
931         }
932         if ( worldModel == NULL ) {
933                 worldModel = renderModelManager->AllocModel();
934         }
935         world->InitFromMap( NULL );
936         worldModel->InitEmpty( va( "GLWorldModel_%i", Sys_Milliseconds() ) );
937 }