diff --git a/rainbow/WinGl/Ctrl.h b/rainbow/WinGl/Ctrl.h index c9aecf0cf..ab97cf745 100644 --- a/rainbow/WinGl/Ctrl.h +++ b/rainbow/WinGl/Ctrl.h @@ -56,6 +56,8 @@ public: static Ctrl *GetDesktop() { return desktop; } static void SetWindowSize(Size sz); static Size GetScreenSize() { return screenRect.GetSize(); } + static dword GetCaretTm() { return glCaretTm; } + static void ResetCaretTm() { glCaretTm = GetTickCount(); } static void DrawScreen(); @@ -64,6 +66,7 @@ public: virtual void ApplyTransform(TransformState state) {} + virtual void PostPaint(Draw& w) {} void DragRectDraw(const Rect& rect1, const Rect& rect2, const Rect& clip, int n, Color color, int type, int animation); diff --git a/rainbow/WinGl/Draw.cpp b/rainbow/WinGl/Draw.cpp index 22d7c566c..6cf69d509 100644 --- a/rainbow/WinGl/Draw.cpp +++ b/rainbow/WinGl/Draw.cpp @@ -47,16 +47,19 @@ void SystemDraw::InitClip(const Rect& clip) void SystemDraw::Reset() { systemDraw = this; - cloff.SetCount(30); + cloff.SetCount(32); + mstack.SetCount(32); ci = 0; cn = 0; cd = 0; + mi = 0; drawing_offset = Point(0, 0); alpha = 255; r = g = b = a = 255; angle = 0; scale = 1; image_coloring = true; + projection_mode = 0; } SystemDraw::SystemDraw() { @@ -115,15 +118,29 @@ void SystemDraw::Clear(bool ontransforms) #endif } -void SystemDraw::FlatView(int width, int height) +void SystemDraw::ViewPort(int width, int height) { glViewport(0, 0, (GLsizei) width < 0 ? drawing_size.cx : width, (GLsizei) height < 0 ? drawing_size.cy : height); - float aspect = drawing_size.cx / (float) drawing_size.cy; +} + +void SystemDraw::OrthogonalView(bool clear_modelview) +{ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, drawing_size.cx, drawing_size.cy, 0, -100, 100); glMatrixMode(GL_MODELVIEW); + if(clear_modelview) + glLoadIdentity(); +} + +void SystemDraw::PerspectiveView(bool clear_modelview) +{ + glMatrixMode(GL_PROJECTION); glLoadIdentity(); + gluPerspective(45.0f, GetAspect(), 1.f, 100.0f); + glMatrixMode(GL_MODELVIEW); + if(clear_modelview) + glLoadIdentity(); } void SystemDraw::ApplyTransforms() @@ -138,19 +155,20 @@ void SystemDraw::ApplyTransforms() void SystemDraw::PushContext() { - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glMatrixMode(GL_MODELVIEW); + MatrixStack& m = mstack[mi++]; + glGetDoublev(GL_PROJECTION_MATRIX, m.projection_matrix); + glGetDoublev(GL_MODELVIEW_MATRIX, m.modelview_matrix); + m.projection_mode = projection_mode; } void SystemDraw::PopContext() { + MatrixStack& m = mstack[--mi]; glMatrixMode(GL_PROJECTION); - glPopMatrix(); + glLoadMatrixd(m.projection_matrix); glMatrixMode(GL_MODELVIEW); - glPopMatrix(); + glLoadMatrixd(m.modelview_matrix); + projection_mode = m.projection_mode; } SystemDraw::~SystemDraw() { diff --git a/rainbow/WinGl/DrawOp.cpp b/rainbow/WinGl/DrawOp.cpp index cfdd8fc6c..67590ed04 100644 --- a/rainbow/WinGl/DrawOp.cpp +++ b/rainbow/WinGl/DrawOp.cpp @@ -84,14 +84,10 @@ void SystemDraw::SetVec(float* v, int sx, int sy, int dx, int dy) void SystemDraw::StencilClip(const Rect& r, int mode, bool exclude) { - float vtx[] = { - (float) r.left, (float) r.bottom, - (float) r.left, (float) r.top, - (float) r.right, (float) r.bottom, - (float) r.right, (float) r.top - }; + float vtx[12]; + SetVtx(vtx, (float) r.left, (float) r.top, (float) r.right, (float) r.bottom); - glVertexPointer(2, GL_FLOAT, 0, vtx); + glVertexPointer(projection_mode ? 3 : 2, GL_FLOAT, 0, vtx); int prev_cn = cn; @@ -263,14 +259,16 @@ void SystemDraw::DrawRectOp(int x, int y, int cx, int cy, Color color) glColor4ub(color.GetR(), color.GetG(), color.GetB(), (int) alpha); - float vtx[] = { +/* float vtx[] = { sx, dy, sx, sy, dx, dy, dx, sy - }; + };*/ + float vtx[12]; + SetVtx(vtx, sx, sy, dx, dy); - glVertexPointer(2, GL_FLOAT, 0, vtx); + glVertexPointer(projection_mode ? 3 : 2, GL_FLOAT, 0, vtx); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glColor4ub(255, 255, 255, (int) alpha); @@ -354,14 +352,8 @@ void SystemDraw::DrawImageOp(int x, int y, int cx, int cy, const Image& img, con glColor4ub(color.GetR(), color.GetG(), color.GetB(), (int) alpha); } - glEnable(GL_TEXTURE_2D); - - float vtx[] = { - sx, dy, - sx, sy, - dx, dy, - dx, sy - }; + float vtx[12]; + SetVtx(vtx, sx, sy, dx, dy); float crd[] = { tl, tb, @@ -370,9 +362,10 @@ void SystemDraw::DrawImageOp(int x, int y, int cx, int cy, const Image& img, con tr, tt }; + glEnable(GL_TEXTURE_2D); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, 0, crd); - glVertexPointer(2, GL_FLOAT, 0, vtx); + glVertexPointer(projection_mode ? 3 : 2, GL_FLOAT, 0, vtx); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_TEXTURE_2D); @@ -400,14 +393,9 @@ void SystemDraw::DrawTextureOp(const RectF& r, int textureId, int width, int hei tt = (tt + TEXEL_OFFSET) * th; tb = (tb - TEXEL_OFFSET) * th; - glEnable(GL_TEXTURE_2D); - - float vtx[] = { - sx, dy, - sx, sy, - dx, dy, - dx, sy - }; + float vtx[12]; + + SetVtx(vtx, sx, sy, dx, dy); float crd[] = { tl, tt, @@ -416,9 +404,11 @@ void SystemDraw::DrawTextureOp(const RectF& r, int textureId, int width, int hei tr, tb }; + glEnable(GL_TEXTURE_2D); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, 0, crd); - glVertexPointer(2, GL_FLOAT, 0, vtx); + glVertexPointer(projection_mode ? 3 : 2, GL_FLOAT, 0, vtx); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisableClientState(GL_TEXTURE_COORD_ARRAY); @@ -514,6 +504,117 @@ void SystemDraw::RestoreLastColor() glColor4f(current_color[0], current_color[1], current_color[2], current_color[3]); } +RectF SystemDraw::UnProject(const RectF& r, float& depth) +{ + double projMat[16]; + double modelMat[16]; + int viewPort[4]; + + glGetDoublev(GL_PROJECTION_MATRIX, projMat); + glGetDoublev(GL_MODELVIEW_MATRIX, modelMat); + glGetIntegerv(GL_VIEWPORT, viewPort); + + RectF fr; + double x, y, z; + gluUnProject(r.left, r.top, 0.99f, modelMat, projMat, viewPort, &x, &y, &z); + depth = (float) z; + fr.left = (float) x; + fr.top = (float) y; + gluUnProject(r.right, r.bottom, 0.99f, modelMat, projMat, viewPort, &x, &y, &z); + fr.right = (float) x; + fr.bottom = (float) y; + return fr; +} + +void SystemDraw::UnProject(float* vtx, float sx, float sy, float dx, float dy) +{ + double projMat[16]; + double modelMat[16] = { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + + int viewPort[4]; + + glGetDoublev(GL_PROJECTION_MATRIX, projMat); + //glGetDoublev(GL_MODELVIEW_MATRIX, modelMat); + glGetIntegerv(GL_VIEWPORT, viewPort); + + double xs, ys, xd, yd, z; + + gluUnProject(sx, drawing_size.cy - sy, 0.99, modelMat, projMat, viewPort, &xs, &ys, &z); + gluUnProject(dx, drawing_size.cy - dy, 0.99, modelMat, projMat, viewPort, &xd, &yd, &z); + + vtx[0] = (float) xs; + vtx[1] = (float) yd; + vtx[2] = (float) z; + vtx[3] = (float) xs; + vtx[4] = (float) ys; + vtx[5] = (float) z; + vtx[6] = (float) xd; + vtx[7] = (float) yd; + vtx[8] = (float) z; + vtx[9] = (float) xd; + vtx[10] = (float) ys; + vtx[11] = (float) z; +} + +void SystemDraw::UnProject(float& x, float& y, float &z) +{ + double projMat[16]; + double modelMat[16] = { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + + int viewPort[4]; + + glGetDoublev(GL_PROJECTION_MATRIX, projMat); + glGetIntegerv(GL_VIEWPORT, viewPort); + + double xd, yd, zd; + + gluUnProject(x, drawing_size.cy - y, 0.99, modelMat, projMat, viewPort, &xd, &yd, &zd); + x = (float) xd; + y = (float) yd; + z = (float) zd; +} + +void SystemDraw::SetVtx(float* vtx, float sx, float sy, float dx, float dy) +{ + if(projection_mode == 1) + { + UnProject(vtx, sx, sy, dx, dy); + } + else + { + vtx[0] = sx; + vtx[1] = dy; + vtx[2] = sx; + vtx[3] = sy; + vtx[4] = dx; + vtx[5] = dy; + vtx[6] = dx; + vtx[7] = sy; + } +} + +void SystemDraw::SetProjectionMode(int mode) +{ + if(mode != projection_mode) + { + projection_mode = mode; + if(projection_mode) + PerspectiveView(false); + else + OrthogonalView(false); + } +} + END_UPP_NAMESPACE #endif \ No newline at end of file diff --git a/rainbow/WinGl/DrawText.cpp b/rainbow/WinGl/DrawText.cpp index e39b0a7c3..830cd1e86 100644 --- a/rainbow/WinGl/DrawText.cpp +++ b/rainbow/WinGl/DrawText.cpp @@ -235,17 +235,19 @@ void SystemDraw::Text(int x, int y, int angle, const wchar *text, Font font, Col } #endif - tl = (tl + 0.5f) * tw; - tr = (tr - 0.5f) * tw; - tt = (tt + 0.5f) * th; - tb = (tb - 0.5f) * th; - + tl = (tl + TEXEL_OFFSET) * tw; + tr = (tr - TEXEL_OFFSET) * tw; + tt = (tt + TEXEL_OFFSET) * th; + tb = (tb - TEXEL_OFFSET) * th; + /* float vtx[] = { sx, dy, sx, sy, dx, dy, dx, sy - }; + };*/ + float vtx[12]; + SetVtx(vtx, sx, sy, dx, dy); float crd[] = { tl, tb, @@ -255,7 +257,7 @@ void SystemDraw::Text(int x, int y, int angle, const wchar *text, Font font, Col }; glTexCoordPointer(2, GL_FLOAT, 0, crd); - glVertexPointer(2, GL_FLOAT, 0, vtx); + glVertexPointer(projection_mode ? 3: 2, GL_FLOAT, 0, vtx); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } diff --git a/rainbow/WinGl/Event.cpp b/rainbow/WinGl/Event.cpp index 7cded9424..736e48ac8 100644 --- a/rainbow/WinGl/Event.cpp +++ b/rainbow/WinGl/Event.cpp @@ -77,8 +77,9 @@ void Ctrl::DoMouseGl(int event, Point p, int zdelta) if(!processed) { for(int i = topctrl.GetCount() - 1; i >= 0; i--) { - if(topctrl[i] != (Ctrl*) &infoPanel && topctrl[i] != (Ctrl*) &console && - DoMouseGl(topctrl[i], event, p, zdelta)) + Ptr t = topctrl[i]; + if(t != (Ctrl*) &infoPanel && t != (Ctrl*) &console && t->GetRect().Contains(p) && + DoMouseGl(t, event, p, zdelta)) return; } Ctrl *desktop = GetDesktop(); diff --git a/rainbow/WinGl/Win.cpp b/rainbow/WinGl/Win.cpp index db4327c75..9831ecf18 100644 --- a/rainbow/WinGl/Win.cpp +++ b/rainbow/WinGl/Win.cpp @@ -222,6 +222,12 @@ int CreateGlContext() return 1; } +void SerializeGl(Stream& s) +{ + s % controlPanelActive; + s % consoleActive; +} + Vector& coreCmdLine__(); Vector SplitCmdLine__(const char *cmd); diff --git a/rainbow/WinGl/WinGl.h b/rainbow/WinGl/WinGl.h index 6702e3346..2ae78d7ff 100644 --- a/rainbow/WinGl/WinGl.h +++ b/rainbow/WinGl/WinGl.h @@ -63,11 +63,13 @@ extern int glDrawMode; #define DRAW_ON_TIMER 0 #define DRAW_ON_IDLE 1 +#define DRAW_ON_EVENT 2 int CreateGlWindow(HINSTANCE hInstance); int CreateGlContext(); void ActivateGlContext(); void DestroyGl(); +void SerializeGl(Stream& s); LRESULT CALLBACK glWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); int64 GetHighTickCount(); @@ -165,7 +167,14 @@ public: void ImageColoring(bool b = true) { image_coloring = b; } - + RectF UnProject(const RectF& r, float& depth); + void UnProject(float* vtx, float sx, float sy, float dx, float dy); + void UnProject(float& x, float& y, float &z); + void SetVtx(float* vtx, float sx, float sy, float dx, float dy); + void SetProjectionMode(int mode); + bool IsPerspectiveProjection() { return projection_mode == 1; } + bool IsOrthogonalProjection() { return projection_mode == 0; } + private: static SystemDraw* systemDraw; friend class FontInfo; @@ -180,9 +189,17 @@ private: Rect drawing_clip; }; + struct MatrixStack : Moveable + { + double projection_matrix[16]; + double modelview_matrix[16]; + int projection_mode; + }; + float current_color[4]; float vtx[8]; float crd[8]; + double projection_matrix[16]; void SetVec(float* v, float sx, float sy, float dx, float dy); void SetVec(float* v, int sx, int sy, int dx, int dy); @@ -203,10 +220,13 @@ public: private: Array cloff; + Array mstack; int ci; int cn; int cd; + int mi; bool image_coloring; + int projection_mode; void Reset(); @@ -222,7 +242,9 @@ public: Point GetOffset() const { return drawing_offset; } SystemDraw(Size sz); virtual ~SystemDraw(); - void FlatView(int width = -1, int height = -1); + void ViewPort(int width = -1, int height = -1); + void OrthogonalView(bool clear_modelview = true); + void PerspectiveView(bool clear_modelview = true); void ApplyTransforms(); void Clear(bool ontransforms = false); void PushContext(); diff --git a/rainbow/WinGl/Wnd.cpp b/rainbow/WinGl/Wnd.cpp index 2b4350aac..bab4addff 100644 --- a/rainbow/WinGl/Wnd.cpp +++ b/rainbow/WinGl/Wnd.cpp @@ -208,7 +208,11 @@ bool Ctrl::ProcessEvent(bool *quit) return true; } else if(glDrawMode == DRAW_ON_IDLE) + { + TimerProc(GetTickCount()); + SweepMkImageCache(); DrawScreen(); + } return false; } @@ -233,14 +237,15 @@ void Ctrl::DrawScreen() draw.alpha = infoPanel.GetAlpha(); draw.angle = infoPanel.GetAngle(); draw.scale = infoPanel.GetScale(); - draw.FlatView(); + draw.ViewPort(); + draw.OrthogonalView(); draw.Clear(true); screenFbo0.Bind(); screenFbo0.Clear(); desktop->ApplyTransform(TS_BEFORE_PAINT); desktop->CtrlPaint(draw, clip); screenFbo0.Unbind(); - + draw.OrthogonalView(); glDisable(GL_BLEND); RectF drawRect(0.f, 0.f, (float) screenRect.GetWidth(), (float) screenRect.GetHeight()); float blur = SystemDraw::blurStrength; @@ -290,6 +295,7 @@ void Ctrl::DrawScreen() draw.End(); tq->ApplyTransform(TS_AFTER_PAINT); } + CursorSync(draw); desktop->ApplyTransform(TS_AFTER_PAINT); @@ -337,10 +343,12 @@ bool Ctrl::ProcessEvents(bool *quit) if(!ProcessEvent(quit)) return false; while(ProcessEvent(quit) && (!LoopCtrl || LoopCtrl->InLoop())); - TimerProc(GetTickCount()); - SweepMkImageCache(); if(glDrawMode == DRAW_ON_TIMER) + { + TimerProc(GetTickCount()); + SweepMkImageCache(); DrawScreen(); + } return true; }