From d3a6feee5aa1ce968e26765683b4d250d68ab043 Mon Sep 17 00:00:00 2001 From: unodgs Date: Tue, 22 Nov 2011 20:33:47 +0000 Subject: [PATCH] WinGL: Added automatic atlas textures, fixed some bugs git-svn-id: svn://ultimatepp.org/upp/trunk@4188 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- rainbow/WinGl/AlphaMag.frag | 4 +- rainbow/WinGl/Blur.frag | 42 ++++ rainbow/WinGl/Blur.vert | 5 + rainbow/WinGl/Console.cpp | 35 +++- rainbow/WinGl/Console.h | 4 +- rainbow/WinGl/ControlPanel.cpp | 43 ++++- rainbow/WinGl/ControlPanel.h | 14 ++ rainbow/WinGl/Ctrl.cpp | 1 + rainbow/WinGl/Ctrl.h | 8 +- rainbow/WinGl/Draw.cpp | 127 +----------- rainbow/WinGl/DrawOp.cpp | 78 +++++--- rainbow/WinGl/DrawText.cpp | 37 ++-- rainbow/WinGl/FontGl.h | 8 +- rainbow/WinGl/ResGl.h | 94 +++++++-- rainbow/WinGl/Resources.cpp | 339 +++++++++++++++++++++++++++++++++ rainbow/WinGl/Scrollbar.cpp | 79 +++++--- rainbow/WinGl/Scrollbar.h | 7 +- rainbow/WinGl/TopFrame.cpp | 67 +------ rainbow/WinGl/TopFrame.h | 4 +- rainbow/WinGl/Util.cpp | 10 - rainbow/WinGl/Win.cpp | 17 +- rainbow/WinGl/WinGl.h | 38 ++-- rainbow/WinGl/WinGl.upp | 3 + rainbow/WinGl/Wnd.cpp | 54 +++--- uppsrc/CtrlCore/CtrlDraw.cpp | 18 +- uppsrc/CtrlCore/CtrlMouse.cpp | 5 + uppsrc/CtrlCore/CtrlPos.cpp | 59 +++++- uppsrc/CtrlLib/Static.cpp | 3 + uppsrc/Draw/DrawText.cpp | 2 +- uppsrc/Draw/FontWin32.cpp | 2 +- 30 files changed, 842 insertions(+), 365 deletions(-) create mode 100644 rainbow/WinGl/Blur.frag create mode 100644 rainbow/WinGl/Blur.vert create mode 100644 rainbow/WinGl/Resources.cpp diff --git a/rainbow/WinGl/AlphaMag.frag b/rainbow/WinGl/AlphaMag.frag index 83196876a..4e8b0b870 100644 --- a/rainbow/WinGl/AlphaMag.frag +++ b/rainbow/WinGl/AlphaMag.frag @@ -8,7 +8,7 @@ uniform bool Glow; uniform bool Shadow; const float AlphaCenter = 0.5; -const float DistanceScale = 20.0; +const float DistanceScale = 25.0; uniform float OutlineCenter; uniform float GlowCenter; @@ -23,7 +23,7 @@ void main() float ma = smoothstep(AlphaCenter - width, AlphaCenter + width, alpha); finalColor.a = ma; - + if(Outline) { float mo = smoothstep(OutlineCenter - width, OutlineCenter + width, alpha); diff --git a/rainbow/WinGl/Blur.frag b/rainbow/WinGl/Blur.frag new file mode 100644 index 000000000..83196876a --- /dev/null +++ b/rainbow/WinGl/Blur.frag @@ -0,0 +1,42 @@ +uniform sampler2D Texture; +uniform vec4 GlyphColor; +uniform vec4 GlowColor; +uniform vec4 OutlineColor; + +uniform bool Outline; +uniform bool Glow; +uniform bool Shadow; + +const float AlphaCenter = 0.5; +const float DistanceScale = 20.0; + +uniform float OutlineCenter; +uniform float GlowCenter; + +void main() +{ + vec4 color = texture2D(Texture, gl_TexCoord[0].xy); + float alpha = color.a; + float width = min(length(fwidth(gl_TexCoord[0])), 1.0) * DistanceScale; + + vec4 finalColor = GlyphColor; + + float ma = smoothstep(AlphaCenter - width, AlphaCenter + width, alpha); + finalColor.a = ma; + + if(Outline) + { + float mo = smoothstep(OutlineCenter - width, OutlineCenter + width, alpha); + finalColor = mix(OutlineColor, finalColor, ma); + finalColor.a = mo; + } + + if(Glow && alpha >= finalColor.a - 0.5) + { + float mg = smoothstep(AlphaCenter, GlowCenter, sqrt(alpha)); + finalColor = mix(GlowColor, finalColor, ma); + finalColor.a = mg; + } + + gl_FragColor = finalColor * GlyphColor.a; +} diff --git a/rainbow/WinGl/Blur.vert b/rainbow/WinGl/Blur.vert new file mode 100644 index 000000000..034ba0b09 --- /dev/null +++ b/rainbow/WinGl/Blur.vert @@ -0,0 +1,5 @@ +void main() +{ + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_Position = ftransform(); +} diff --git a/rainbow/WinGl/Console.cpp b/rainbow/WinGl/Console.cpp index 7f596b7b0..cd78f9464 100644 --- a/rainbow/WinGl/Console.cpp +++ b/rainbow/WinGl/Console.cpp @@ -13,8 +13,9 @@ void Console::Paint(Draw& w) w.DrawRect(0, 1, 1, sz.cy, Yellow); w.DrawRect(1, sz.cy - 1, sz.cx - 2, 1, Yellow); //DrawFrame(w, sz, Yellow); - w.DrawImage(sz.cx - 10, sz.cy - 10, WinGlImg::ResizeMarker()); - w.Clip(5, 5, sz.cx - 10, sz.cy - 10); + //w.DrawImage(sz.cx - 18, sz.cy - 21, WinGlImg::ResizeMarker()); + w.DrawRect(1, sz.cy - 22, sz.cx - 2, 1, Yellow); + w.Clip(5, 5, sz.cx - 10, sz.cy - 5 - 21); sw.alpha = 255.f; int y = 5; int ty = Draw::GetStdFontCy() + 2; @@ -32,9 +33,9 @@ void Console::Paint(Draw& w) sw.alpha = 255.f; } - int lines = (sz.cy - y - 5) / ty; - int n = sb.GetPos() / ty; - int maxn = min(n + lines, maxLine); + int lines = (sz.cy - y - 22) / ty; + int n = fceil(sb.GetPos() / double(ty)); + int maxn = min(n + lines, currLine); while(n < maxn) { @@ -58,7 +59,7 @@ void Console::Log(const char* text, Color ink) { bool isend = sb.IsEnd(); - if(++currLine > maxLine) + if(++currLine >= maxLine) { currLine = maxLine; for(int i = 0; i < maxLine - 1; i++) @@ -66,7 +67,10 @@ void Console::Log(const char* text, Color ink) } int ty = Draw::GetStdFontCy() + 2; - sb.SetTotal(currLine * ty); + int total = currLine * ty; + int fcnt = fixedText.GetCount(); + sb.SetTotal(total + 5 + 22); + if(isend) sb.GoEnd(); @@ -82,7 +86,7 @@ void Console::LeftDown(Point p, dword keys) rs = GetSize(); tl = GetScreenRect().TopLeft(); Size sz = GetSize(); - resize = p.x > sz.cx - 10 && p.y > sz.cy - 10; + resize = p.x > sz.cx - 18 && p.y > sz.cy - 18; } void Console::LeftUp(Point p, dword keys) @@ -153,10 +157,21 @@ void Console::Show(bool b) } } +void Console::Clear() +{ + currLine = 0; + sb.Clear(); +} + Console::Console() : init(true), resize(false) { - Add(sb.RightPos(2, 7).VSizePos(2, 10)); - SetLines(1000); + Add(sb.RightPos(2, 7).VSizePos(2, 22)); + Add(clear.LeftPos(2, 50).BottomPos(2, 18)); + clear.SetLabel("Clear"); + //clear.bg = Yellow; + //clear.alpha = 150.f; + clear <<= THISBACK(Clear); + SetLines(3000); currLine = 0; scrollLine = 0; } diff --git a/rainbow/WinGl/Console.h b/rainbow/WinGl/Console.h index 35a647412..ae86b9d1e 100644 --- a/rainbow/WinGl/Console.h +++ b/rainbow/WinGl/Console.h @@ -1,7 +1,7 @@ #ifndef _WinGl_Console_h_ #define _WinGl_Console_h_ -#include +#include "ControlPanel.h" #include "Scrollbar.h" NAMESPACE_UPP @@ -10,6 +10,7 @@ struct Console : Ctrl { Ctrl* parent; SlimScrollBar sb; + SlimButton clear; struct LineInfo : Moveable { Color ink; @@ -39,6 +40,7 @@ struct Console : Ctrl void SetLines(int lines); void Show(bool b = true); + void Clear(); typedef Console CLASSNAME; Console(); diff --git a/rainbow/WinGl/ControlPanel.cpp b/rainbow/WinGl/ControlPanel.cpp index 2ef275c88..571fcc962 100644 --- a/rainbow/WinGl/ControlPanel.cpp +++ b/rainbow/WinGl/ControlPanel.cpp @@ -84,6 +84,47 @@ float ValueSlider::GetPos() return pos; } +void SlimButton::Paint(Draw &w) +{ + SystemDraw& sw = (SystemDraw&) w; + float a = sw.alpha; + sw.alpha = alpha; + Size sz = GetSize(); + if(HasMouseIn(sz)) + w.DrawRect(sz, bg); + sw.alpha = a; + + Size tsz = GetTextSize(label, StdFont()); + w.DrawText((sz.cx - tsz.cx) / 2, (sz.cy - tsz.cy) / 2, label, StdFont(), fg); +} + +void SlimButton::LeftDown(Point p, dword keyflags) +{ + SetCapture(); +} + +void SlimButton::LeftUp(Point p, dword keyflags) +{ + ReleaseCapture(); + Action(); +} + +void SlimButton::MouseMove(Point p, dword keyflags) +{ +} + +void SlimButton::SetLabel(const char* s) +{ + label = s; +} + +SlimButton::SlimButton() +{ + fg = White; + bg = Black; + alpha = 255.f; +} + InfoPanel::InfoPanel() : init(true), parent(NULL) { Add(alphaSlider.RightPos(199, 100).VSizePos(1, 0)); @@ -116,7 +157,7 @@ void InfoPanel::Paint(Draw& w) w.DrawRect(0, 0, 1, sz.cy, frameColor); w.DrawRect(0, 0, sz.cx, 1, frameColor); w.DrawRect(sz.cx - 1, 0, 1, sz.cy, frameColor); - String info = Format("FPS: %.2f, Textures: %d, Size: %d, %d", GetFps(), Resources::textures.GetCount(), wsz.cx, wsz.cy); + String info = Format("FPS: %.2f, Textures: %d (%d), Size: %d, %d", GetFps(), resources.textures.GetCount(), resources.bindedTextures, wsz.cx, wsz.cy); w.DrawText(5, sz.cy - 18, info, StdFont(), White); } diff --git a/rainbow/WinGl/ControlPanel.h b/rainbow/WinGl/ControlPanel.h index 2a60334da..9c4bbcafd 100644 --- a/rainbow/WinGl/ControlPanel.h +++ b/rainbow/WinGl/ControlPanel.h @@ -32,6 +32,20 @@ struct ValueSlider : Ctrl Callback WhenLeftUp; }; +struct SlimButton : Ctrl +{ + Color fg; + Color bg; + float alpha; + String label; + virtual void Paint(Draw &w); + virtual void LeftDown(Point p, dword keyflags); + virtual void LeftUp(Point p, dword keyflags); + virtual void MouseMove(Point p, dword keyflags); + void SetLabel(const char* s); + SlimButton(); +}; + struct InfoPanel : Ctrl { bool init; diff --git a/rainbow/WinGl/Ctrl.cpp b/rainbow/WinGl/Ctrl.cpp index 5a7f907e0..e1c5f11cc 100644 --- a/rainbow/WinGl/Ctrl.cpp +++ b/rainbow/WinGl/Ctrl.cpp @@ -8,6 +8,7 @@ NAMESPACE_UPP void Ctrl::GuiPlatformConstruct() { + cliptobounds = true; } void Ctrl::GuiPlatformRemove() diff --git a/rainbow/WinGl/Ctrl.h b/rainbow/WinGl/Ctrl.h index 0afd3aff3..069ad75d6 100644 --- a/rainbow/WinGl/Ctrl.h +++ b/rainbow/WinGl/Ctrl.h @@ -14,6 +14,8 @@ static int64 glEventLoop; static int64 glEndSessionLoop; + + bool cliptobounds:1; int FindTopCtrl() const; static void SyncTopWindows(); @@ -55,6 +57,10 @@ public: static void SetWindowSize(Size sz); static void DrawScreen(); + + Ctrl& ClipToBounds(bool b = true) { cliptobounds = b; return *this; } + bool IsClipToBounds() const { return cliptobounds; } + virtual void ApplyTransform(TransformState state) {} void DragRectDraw(const Rect& rect1, const Rect& rect2, const Rect& clip, int n, @@ -62,8 +68,6 @@ public: static Ctrl *FindMouseTopCtrl(); - static bool FullWindowDrag; - enum { DRAWDRAGRECT_SCREEN = 0x8000 }; //$ }; diff --git a/rainbow/WinGl/Draw.cpp b/rainbow/WinGl/Draw.cpp index 0341e15b1..c597ed964 100644 --- a/rainbow/WinGl/Draw.cpp +++ b/rainbow/WinGl/Draw.cpp @@ -1,5 +1,4 @@ #include -//#include #ifdef GUI_WINGL @@ -8,131 +7,8 @@ NAMESPACE_UPP #define LLOG(x) // LOG(x) #define LTIMING(x) // RTIMING(x) -int64 Resources::currentSerialId = -1; -ArrayMap Resources::textures; -VectorMap Resources::fonts; -Vector SystemDraw::dragRect; FrameInfo frameInfo; - -float GetFps() -{ - static float fps = 0.0f; - static dword updateInterval = 1000; - static dword timeSinceLastUpdate = 0; - static dword frameCount = 0; - static dword currentTick; - static dword lastTick; - static bool isFirst = true; - - if(isFirst) - { - currentTick = GetTickCount(); - lastTick = currentTick; - isFirst = false; - } - - frameCount++; - currentTick = GetTickCount(); - - dword elapsed = currentTick - lastTick; - - lastTick = currentTick; - timeSinceLastUpdate += elapsed; - - if (timeSinceLastUpdate > updateInterval) - { - if (timeSinceLastUpdate) - { - fps = (frameCount / float(timeSinceLastUpdate)) * 1000.f; - frameCount = 0; - timeSinceLastUpdate -= updateInterval; - } - } - - return fps; -} - -void Texture::AddPart(int64 serialId, const Image& img) -{ -} - -int64 Resources::Bind(const Image& img, bool linear) -{ - int64 serialId = img.GetSerialId(); - - if(!Bind(serialId)) - return serialId; - - int textureNumber = textures.Find(serialId); - - if(textureNumber < 0) - { - textures.Add(serialId); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.GetWidth(), img.GetHeight(), 0, GL_BGRA, GL_UNSIGNED_BYTE, img); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, linear ? GL_LINEAR : GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linear ? GL_LINEAR : GL_NEAREST); - } - - return serialId; -} - -bool Resources::Bind(int64 serialId, bool force) -{ - if(!force && serialId == currentSerialId) - return false; - - currentSerialId = serialId; - glBindTexture(GL_TEXTURE_2D, (GLuint) serialId); - return true; -} - -OpenGLFont& Resources::GetFont(const char* fontName, int fontHeight) -{ - int n = fonts.Find(fontName); - OpenGLFont* fgl = NULL; - if(n >= 0) - fgl = &fonts[n]; - else - { - fgl = &fonts.Add(fontName); - fgl->Load(fontName); - } - - fgl->scale = (fontHeight * 96.f / 72.f) / 72.f; - return *fgl; -} - -OpenGLFont& Resources::GetFontBrc(const char* fontName, const byte* fontDef, const byte** imagesData, const int* imagesSize, int imagesCount, int fontHeight) -{ - int n = fonts.Find(fontName); - OpenGLFont* fgl = NULL; - if(n >= 0) - fgl = &fonts[n]; - else - { - fgl = &fonts.Add(fontName); - fgl->LoadBrc(fontDef, imagesData, imagesSize, imagesCount); - } - - fgl->scale = (fontHeight * 96.f / 72.f) / 72.f; - return *fgl; -} - -OpenGLFont& Resources::GetFont(const Font& font) -{ - if(font.IsBold()) - return GetFontBrc("TahomaB", tahomaBFontDef, (const byte**) tahomaBFontImg, tahomaBFontImg_length, tahomaBFontImg_count, font.GetHeight()); - else - return GetFontBrc("TahomaN", tahomaNFontDef, (const byte**) tahomaNFontImg, tahomaNFontImg_length, tahomaNFontImg_count, font.GetHeight()); - - //return GetFont(bold ? "tahoma14b.fnt" : "tahoma14.fnt"); - /*return GetFontBrc( - bold ? "tahoma14b.fnt" : "tahoma14.fnt", - bold ? resTahoma14Fnt : resTahoma14BoldFnt, - bold ? resTahoma14Img : resTahoma14BoldImg);*/ -} +SystemDraw* SystemDraw::systemDraw = NULL; dword SystemDraw::GetInfo() const { @@ -168,6 +44,7 @@ void SystemDraw::InitClip(const Rect& clip) } void SystemDraw::Reset() { + systemDraw = this; cloff.SetCount(20); ci = 0; cn = 0; diff --git a/rainbow/WinGl/DrawOp.cpp b/rainbow/WinGl/DrawOp.cpp index 1598196d9..7c2e1ad90 100644 --- a/rainbow/WinGl/DrawOp.cpp +++ b/rainbow/WinGl/DrawOp.cpp @@ -34,7 +34,8 @@ void SystemDraw::SetClipRect(const Rect& r) clip = r; #if CLIP_MODE != 2 for(int i = 0; i < ci; i++) - clip &= cloff[i].drawing_clip; + if(!cloff[i].exclude) + clip &= cloff[i].drawing_clip; #endif } @@ -81,7 +82,7 @@ void SystemDraw::SetVec(float* v, int sx, int sy, int dx, int dy) v[6] = (float) dx; v[7] = (float) sy; } -void SystemDraw::StencilClip(const Rect& r, int mode) +void SystemDraw::StencilClip(const Rect& r, int mode, bool exclude) { float vtx[] = { (float) r.left, (float) r.bottom, @@ -90,24 +91,49 @@ void SystemDraw::StencilClip(const Rect& r, int mode) (float) r.right, (float) r.top }; - //SetVec(vtx, r.left, r.top, r.right, r.bottom); glVertexPointer(2, GL_FLOAT, 0, vtx); + int prev_cn = cn; + glColorMask(0, 0, 0, 0); + if(mode == 0) { - ++cn; - glStencilOp(GL_KEEP, GL_INCR, GL_INCR); - glStencilFunc(GL_GEQUAL, cn, ~0); + if(exclude) + { + glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); + glStencilFunc(GL_ALWAYS, 255, ~0); + } + else + { + ++cn; + glStencilOp(GL_KEEP, GL_INCR, GL_INCR); + glStencilFunc(GL_GEQUAL, cn, ~0); + } } else { - --cn; - glStencilOp(GL_KEEP, GL_DECR, GL_DECR); - glStencilFunc(GL_ALWAYS, cn, ~0); + if(exclude) + { + glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); + glStencilFunc(GL_ALWAYS, cn, ~0); + } + else + { + --cn; + glStencilOp(GL_KEEP, GL_DECR, GL_DECR); + glStencilFunc(GL_ALWAYS, cn, ~0); + } } + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glStencilFunc(GL_LEQUAL, cn, ~0); + + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + if(exclude) + glStencilFunc(GL_GREATER, 255, ~0); + else + glStencilFunc(GL_EQUAL, cn, ~0); + glColorMask(1, 1, 1, 1); /* @@ -125,11 +151,11 @@ void SystemDraw::StencilClip(const Rect& r, int mode) { glStencilFunc(GL_LEQUAL, --cn, ~0); } - */ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + */ } -void SystemDraw::SetClip(const Rect& r, int mode) +void SystemDraw::SetClip(const Rect& r, int mode, bool exclude) { //glColor4ub(255, 0, 0, 10); //glRecti(r.left, r.top, r.right, r.bottom); @@ -140,7 +166,7 @@ void SystemDraw::SetClip(const Rect& r, int mode) #elif CLIP_MODE == 1 PlaneClip(clip); #elif CLIP_MODE == 2 - StencilClip(clip, mode); + StencilClip(clip, mode, exclude); #endif } @@ -148,8 +174,9 @@ void SystemDraw::BeginOp() { Cloff& w = cloff[ci++]; w.clipping = false; + w.exclude = false; w.org = drawing_offset; - w.drawing_clip = drawing_clip; + w.drawing_clip = drawing_clip; } void SystemDraw::EndOp() @@ -157,14 +184,14 @@ void SystemDraw::EndOp() ASSERT(ci); #if CLIP_MODE == 2 if(cloff[ci - 1].clipping) - SetClip(drawing_clip, 1); + SetClip(drawing_clip, 1, cloff[ci - 1].exclude); #endif Cloff& w = cloff[--ci]; drawing_offset = w.org; drawing_clip = w.drawing_clip; #if CLIP_MODE != 2 if(cloff[ci].clipping) - SetClip(drawing_clip, 1); + SetClip(drawing_clip); #endif } @@ -195,6 +222,11 @@ bool SystemDraw::ClipoffOp(const Rect& r) bool SystemDraw::ExcludeClipOp(const Rect& r) { + ASSERT(ci > 0); + cloff[ci - 1].clipping = true; + cloff[ci - 1].exclude = true; + drawing_clip = r + drawing_offset; + SetClip(drawing_clip, 0, true); return true; } @@ -328,15 +360,15 @@ void SystemDraw::DrawImageOp(int x, int y, int cx, int cy, const Image& img, con } #endif - Resources::Bind(img); + const Texture& t = resources.Bind(img, false, true); - float tw = 1.f / (float) img.GetWidth(); - float th = 1.f / (float) img.GetHeight(); + float tw = 1.f / (float) t.realWidth; + float th = 1.f / (float) t.realHeight; - tl *= tw; - tr *= tw; - tt *= th; - tb *= th; + tl = (tl + t.x) * tw; + tr = (tr + t.x) * tw; + tt = (tt + t.y) * th; + tb = (tb + t.y) * th; if(image_coloring) { diff --git a/rainbow/WinGl/DrawText.cpp b/rainbow/WinGl/DrawText.cpp index 8684c45d9..0c3ff9963 100644 --- a/rainbow/WinGl/DrawText.cpp +++ b/rainbow/WinGl/DrawText.cpp @@ -9,13 +9,15 @@ void OpenGLFont::LoadBrc(const byte* xml, const byte** imagesData, const int* im Parse((const char*) xml, false); for(int i = 0; i < imagesCount; i++) { - BrcImage& bi = brcImages.Add(); - bi.data = imagesData[i]; - bi.length = imagesSize[i]; + MemStream ms((void*) imagesData[i], imagesSize[i]); + Image img = StreamRaster::LoadAny(ms); + images.Add(img); + if(preload) + resources.Add(img, true); } } -void OpenGLFont::Load(const String& fileName) +void OpenGLFont::Load(const String& fileName, bool preload) { String filePath = GetDataFile(fileName); String xml = LoadFile(filePath); @@ -51,7 +53,10 @@ void OpenGLFont::Parse(const char* xml, bool parsePages) if(parsePages) { String fileName = p["file"]; - images.Add(fileName); + Image img = StreamRaster::LoadFileAny(GetDataFile(fileName)); + images.Add(img); + if(preload) + resources.Add(img, true); } pages.Add(StrInt(p["id"])); } @@ -105,26 +110,17 @@ void OpenGLFont::Parse(const char* xml, bool parsePages) } } -void OpenGLFont::UpdateTextures() + void OpenGLFont::UpdateTextures() { if(texturesUpdated) return; for(int i = 0; i < images.GetCount(); i++) { - Image img = StreamRaster::LoadFileAny(GetDataFile(images[i])); - int64 serialId = Resources::Bind(img, true); - pages[i] = serialId; + const Texture& t = resources.Bind(images[i], true); + pages[i] = t.serialId; } - for(int i = 0; i < brcImages.GetCount(); i++) - { - MemStream ms((void*) brcImages[i].data, brcImages[i].length); - Image img = StreamRaster::LoadAny(ms); - int64 serialId = Resources::Bind(img, true); - pages[i] = serialId; - } - texturesUpdated = true; } @@ -138,8 +134,8 @@ void SystemDraw::Text(int x, int y, int angle, const wchar *text, Font font, Col if(!text) return; - const wchar* s = text; - OpenGLFont& fi = Resources::GetFont(font); + const wchar* s = text; + OpenGLFont& fi = resources.GetFont(font); glEnable(GL_TEXTURE_2D); @@ -151,6 +147,7 @@ void SystemDraw::Text(int x, int y, int angle, const wchar *text, Font font, Col #endif fi.UpdateTextures(); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); alphaMagProg.Start(); @@ -187,7 +184,7 @@ void SystemDraw::Text(int x, int y, int angle, const wchar *text, Font font, Col if(ci.page != page) { - Resources::Bind(fi.pages[ci.page], true); + resources.Bind(fi.pages[ci.page], true); glActiveTexture(GL_TEXTURE0); alphaMagProg.Set("Texture", 0); page = ci.page; diff --git a/rainbow/WinGl/FontGl.h b/rainbow/WinGl/FontGl.h index fb468ebd3..e50265f4e 100644 --- a/rainbow/WinGl/FontGl.h +++ b/rainbow/WinGl/FontGl.h @@ -35,18 +35,18 @@ struct OpenGLFont : Moveable Vector chars; VectorMap > kerns; - Vector images; - Vector brcImages; + Vector images; Vector pages; + bool preload; - OpenGLFont() : texturesUpdated(false), scale(1.0f) + OpenGLFont() : texturesUpdated(false), preload(false), scale(1.0f) {} ~OpenGLFont() {} void LoadBrc(const byte* xml, const byte** imagesData, const int* imagesSize, int imagesCount); - void Load(const String& fileName); + void Load(const String& fileName, bool preload = false); void Parse(const char* xml, bool parsePages); void UpdateTextures(); void BuildVertices(); diff --git a/rainbow/WinGl/ResGl.h b/rainbow/WinGl/ResGl.h index 46efa09eb..f4e92c751 100644 --- a/rainbow/WinGl/ResGl.h +++ b/rainbow/WinGl/ResGl.h @@ -3,22 +3,92 @@ struct Texture : Moveable { - Size sz; - Point curpos; - VectorMap parts; - void AddPart(int64 serialId, const Image& img); + int64 serialId; + int64 atlasSerialId; + int realWidth; + int realHeight; + int width; + int height; + int x; + int y; + + Texture(int w = 0, int h = 0) + { + serialId = -1; + atlasSerialId = -1; + realWidth = w; + realHeight = h; + width = w; + height = h; + x = 0; + y = 0; + } + + String ToString() const + { + return Format("x: %d, y: %d, w: %d, h:%d (%d, %d) - %ld", x, y, width, height, realWidth, realHeight, serialId); + } +}; + +struct Atlas : Moveable +{ + int width; + int height; + bool linear; + Vector parts; + Image Make(ArrayMap& textures); +}; + +struct ImageResource : Moveable +{ + int type; + bool linear; + + //direct image + Image img; + //brc image + const byte* data; + int length; + //disk image + String fileName; }; struct Resources { - static int64 currentSerialId; - static ArrayMap textures; - static VectorMap fonts; - static int64 Bind(const Image& img, bool linear = false); - static bool Bind(int64 serialId, bool force = false); - static OpenGLFont& GetFont(const char* fontName, int fontHeight); - static OpenGLFont& GetFontBrc(const char* fontName, const byte* fontDef, const byte** imagesData, const int* imagesSize, int imagesCount, int fontHeight); - static OpenGLFont& GetFont(const Font& font); + Vector staticImages; + VectorMap staticAtlases; + Vector staticFonts; + + Texture autoAtlas; + ImageBuffer autoAtlasBuffer; + Image autoAtlasImage; + int px, py, maxh; + + int bindedTextures; + + int64 currentSerialId; + ArrayMap textures; + ArrayMap fonts; + + const Texture& CreateTexture(const Image& img, bool linear = false, int width = -1, int height = -1); + void CreateSubTexture(const Texture& t, const Image& img, int x, int y); + + const Texture& Bind(const Image& img, bool linear = false, bool autoatlas = false); + bool Bind(int64 serialId, bool force = false); + void Add(const Image& img, bool linear = false); + void Add(Iml* images, bool linear = false); + void Add(const Font& fnt); + void AddAtlas(const char* atlasName, const Image& img); + void AddAtlas(const char* atlasName, Iml* images); + OpenGLFont& GetFont(const char* fontName, int fontHeight, bool preload = false, const byte* fontDef = NULL, const byte** imagesData = NULL, const int* imagesSize = NULL, int imagesCount = 0); + OpenGLFont& GetFont(const Font& font, bool preload = false); + + void BindStatic(); + + Resources(); }; +extern Resources resources; + + #endif diff --git a/rainbow/WinGl/Resources.cpp b/rainbow/WinGl/Resources.cpp new file mode 100644 index 000000000..0daafb509 --- /dev/null +++ b/rainbow/WinGl/Resources.cpp @@ -0,0 +1,339 @@ +#include "WinGl.h" +#include +#ifdef GUI_WINGL + +NAMESPACE_UPP + +Resources resources; + +Resources::Resources() : autoAtlas(1024, 1024) +{ + px = 0; + py = 0; + maxh = 0; + currentSerialId = -1; + bindedTextures = 0; +} + +const Texture& Resources::CreateTexture(const Image& img, bool linear, int width, int height) +{ + int64 serialId = img.GetSerialId(); + Texture& t = textures.Add(serialId); + t.serialId = serialId; + t.atlasSerialId = -1; + t.width = width > 0 ? width : img.GetWidth(); + t.height = height > 0 ? height : img.GetHeight(); + t.realWidth = t.width; + t.realHeight = t.height; + t.x = 0; + t.y = 0; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, t.width, t.height, 0, GL_BGRA, GL_UNSIGNED_BYTE, img); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, linear ? GL_LINEAR : GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linear ? GL_LINEAR : GL_NEAREST); + ++bindedTextures; + return t; +} + +void Resources::CreateSubTexture(const Texture& t, const Image& img, int x, int y) +{ + Bind(autoAtlas.serialId); + glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, img.GetWidth(), img.GetHeight(), GL_BGRA, GL_UNSIGNED_BYTE, img); +} + +const Texture& Resources::Bind(const Image& img, bool linear, bool autoatlas) +{ + int64 serialId = img.GetSerialId(); + + const Texture* texture = textures.FindPtr(serialId); + if(texture) + { + if(texture->atlasSerialId >= 0) + serialId = texture->atlasSerialId; + } + else if(autoatlas) + { + int w = img.GetWidth(); + int h = img.GetHeight(); + + if(w <= autoAtlas.width && h <= autoAtlas.height && w <= 64 && h <= 64) + { + bool add = px + w <= autoAtlas.width && py + h <= autoAtlas.height; + + if(!add) + { + if(py + maxh + h > autoAtlas.height) + { + add = false; + } + else + { + px = 0; + py += maxh; + maxh = 0; + add = true; + } + } + + if(add) + { + if(h > maxh) + maxh = h; + + Texture& t = textures.Add(img.GetSerialId()); + t.atlasSerialId = autoAtlas.serialId; + t.width = w; + t.height = h; + t.realWidth = autoAtlas.width; + t.realHeight = autoAtlas.height; + t.x = px; + t.y = py; + + CreateSubTexture(autoAtlas, img, px, py); + Copy(autoAtlasImage, Point(px, py), img, img.GetSize()); + + px += w; + + texture = &t; + serialId = autoAtlas.serialId; + } + } + } + + if(!Bind(serialId)) + return *texture; + + if(!texture) + { + texture = &CreateTexture(img, linear); + } + + return *texture; +} + +bool Resources::Bind(int64 serialId, bool force) +{ + if(!force && serialId == currentSerialId) + return false; + + currentSerialId = serialId; + glBindTexture(GL_TEXTURE_2D, (GLuint) serialId); + return true; +} + +void Resources::BindStatic() +{ + if(autoAtlas.serialId < 0) + { + autoAtlasBuffer.Create(autoAtlas.width, autoAtlas.height); + Fill(autoAtlasBuffer, RGBAZero(), autoAtlasBuffer.GetLength()); + autoAtlasImage = autoAtlasBuffer; + Bind(autoAtlasImage.GetSerialId(), true); + autoAtlas = CreateTexture(autoAtlasImage, false); + } + + if(!staticImages.IsEmpty()) + { + for(int i = 0; i < staticImages.GetCount(); i++) + Bind(staticImages[i].img, staticImages[i].linear); + staticImages.Clear(); + } + + if(!staticAtlases.IsEmpty()) + { + for(int i = 0; i < staticAtlases.GetCount(); i++) + Bind(staticAtlases[i].Make(textures), staticAtlases[i].linear); + staticAtlases.Clear(); + } + + if(!staticFonts.IsEmpty()) + { + for(int i = 0; i < staticFonts.GetCount(); i++) + GetFont(staticFonts[i], true); + staticFonts.Clear(); + } +} + +void Resources::Add(const Image& img, bool linear) +{ + ImageResource& ir = staticImages.Add(); + ir.img = img; + ir.linear = linear; +} + +void Resources::Add(const Font& fnt) +{ + Font& f = staticFonts.Add(fnt); +} + +void Resources::Add(Iml* images, bool linear) +{ + for(int i = 0; i < images->GetCount(); i++) + Add(images->Get(i), linear); +} + +void Resources::AddAtlas(const char* atlasName, const Image& img) +{ + Atlas& atlas = staticAtlases.GetAdd(atlasName); + atlas.linear = false; + atlas.parts.Add(img); +} + +void Resources::AddAtlas(const char* atlasName, Iml* images) +{ + Atlas& atlas = staticAtlases.GetAdd(atlasName); + atlas.linear = false; + for(int i = 0; i < images->GetCount(); i++) + atlas.parts.Add(images->Get(i)); +} + +Image Atlas::Make(ArrayMap& textures) +{ + width = 512; + height = 512; + + ImageBuffer ib(width, height); + Fill(ib, RGBAZero(), ib.GetLength()); + + Point p(0, 0); + int maxh = 0; + + int tidx = textures.GetCount(); + + for(int i = 0; i < parts.GetCount(); i++) + { + Image& img = parts[i]; + + int w = img.GetWidth(); + int h = img.GetHeight(); + + if(w > width || h > height) + continue; + + if(p.x + w > width) + { + if(p.y + maxh + h > height) + continue; + + p.x = 0; + p.y += maxh; + maxh = 0; + } + + if(h > maxh) + maxh = h; + + Texture& t = textures.Add(img.GetSerialId()); + t.width = w; + t.height = h; + t.realWidth = width; + t.realHeight = height; + t.x = p.x; + t.y = p.y; + + Copy(ib, p, img, img.GetSize()); + + p.x += w; + } + + Image finalImg(ib); + int64 finalSerialId = finalImg.GetSerialId(); + + for(int i = tidx; i < textures.GetCount(); i++) + textures[i].atlasSerialId = finalSerialId; + + return finalImg; +} + +OpenGLFont& Resources::GetFont(const char* fontName, int fontHeight, bool preload, const byte* fontDef, const byte** imagesData, const int* imagesSize, int imagesCount) +{ + int n = fonts.Find(fontName); + OpenGLFont* fgl = NULL; + if(n >= 0) + fgl = &fonts[n]; + else + { + fgl = &fonts.Add(fontName); + fgl->preload = preload; + + if(fontDef) + fgl->LoadBrc(fontDef, imagesData, imagesSize, imagesCount); + else + fgl->Load(fontName); + } + + fgl->scale = (fontHeight * 96.f / 72.f) / 72.f; + return *fgl; +} + +OpenGLFont& Resources::GetFont(const Font& font, bool preload) +{ + if(font.IsBold()) + return GetFont("TahomaB", font.GetHeight(), preload, + tahomaBFontDef, (const byte**) tahomaBFontImg, tahomaBFontImg_length, tahomaBFontImg_count); + else + return GetFont("TahomaN", font.GetHeight(), preload, + tahomaNFontDef, (const byte**) tahomaNFontImg, tahomaNFontImg_length, tahomaNFontImg_count); +} + +int64 GetHighTickCount() +{ + static int64 counterFreq = 0; + if(counterFreq == 0) + { + if(!QueryPerformanceFrequency((LARGE_INTEGER*) &counterFreq)) + counterFreq = 0; + } + if(counterFreq > 0) + { + int64 counter; + QueryPerformanceCounter((LARGE_INTEGER*) &counter); + return counter * 1000 / counterFreq; + } + else + { + return GetTickCount(); + } +} + +float GetFps() +{ + static float fps = 0.0f; + static int64 updateInterval = 1000; + static int64 timeSinceLastUpdate = 0; + static int64 frameCount = 0; + static int64 currentTick; + static int64 lastTick; + static bool isFirst = true; + + if(isFirst) + { + currentTick = frameInfo.curr_tick_count; + lastTick = currentTick; + isFirst = false; + } + + frameCount++; + currentTick = frameInfo.curr_tick_count; + + int64 elapsed = currentTick - lastTick; + + lastTick = currentTick; + timeSinceLastUpdate += elapsed; + + if (timeSinceLastUpdate > updateInterval) + { + if (timeSinceLastUpdate) + { + fps = (frameCount / float(timeSinceLastUpdate)) * 1000.f; + frameCount = 0; + timeSinceLastUpdate -= updateInterval; + } + } + + return fps; +} + +#endif +END_UPP_NAMESPACE \ No newline at end of file diff --git a/rainbow/WinGl/Scrollbar.cpp b/rainbow/WinGl/Scrollbar.cpp index afa9ab039..cf3725e15 100644 --- a/rainbow/WinGl/Scrollbar.cpp +++ b/rainbow/WinGl/Scrollbar.cpp @@ -95,6 +95,7 @@ SlimScrollBar::SlimScrollBar() void SlimScrollBar::Clear() { total = 0; + t = 0; pos = 0; prev_ps = 0; ps = 0; @@ -109,21 +110,26 @@ void SlimScrollBar::Clear() void SlimScrollBar::UpdatePos(bool update, bool whenscroll) { - sz = GetSize(); + sz = GetSize(); Fix(sz); + if(total <= 0 || sz.cx <= 0) + { cs = ics = 0; + } else { - cs = sz.cx / ((double) total + 0.5); - ics = total / ((double) sz.cx); + cs = sz.cx / double(t + 0.5); + ics = t / double(sz.cx); } - size = sz.cx * cs; + + size = max(0.0, sz.cx * cs); + if(update) pos = new_pos - start_pos; - isbegin = total < sz.cx; - isend = total < sz.cx; + isbegin = t < sz.cx; + isend = t < sz.cx; if(pos <= 0) { @@ -136,8 +142,7 @@ void SlimScrollBar::UpdatePos(bool update, bool whenscroll) isend = true; } - ps = total > sz.cx ? pos * ics : 0; - + ps = t > sz.cx ? pos * ics : 0; if(whenscroll && int(ps) != int(prev_ps)) WhenScroll(); @@ -153,11 +158,16 @@ void SlimScrollBar::Paint(Draw &w) ready = true; } + Ctrl* q = GetParent(); + if(!q) + return; + Size sz = GetSize(); - - if(IsHorz() && total > sz.cx || IsVert() && total > sz.cy) { + Size psz = q->GetSize(); + + if(IsHorz() && total > psz.cx || IsVert() && total > psz.cy) { Point p(int(pos), 0); - Size rsz(fceil(size), IsVert() ? sz.cx : sz.cy); + Size rsz(int(size), IsVert() ? sz.cx : sz.cy); Fix(p); Fix(rsz); SystemDraw& sw = (SystemDraw&) w; @@ -169,7 +179,13 @@ void SlimScrollBar::Paint(Draw &w) void SlimScrollBar::Layout() { - UpdatePos(false); + Size csz = GetSize(); + Fix(csz); + if(ready && csz != sz) + { + sz = csz; + UpdatePos(false); + } } void SlimScrollBar::LeftDown(Point p, dword keyflags) @@ -216,14 +232,14 @@ int SlimScrollBar::GetPos() const void SlimScrollBar::SetPos(int p, bool dontscale, bool whenscroll) { - pos = total > 0 ? dontscale ? p : iscale(p, sz.cx, total) : 0; + pos = total > 0 ? dontscale ? p : iscale(p, sz.cx, t) : 0; UpdatePos(false, whenscroll); Refresh(); } void SlimScrollBar::AddPos(int p, bool dontscale, bool whenscroll) { - pos += total > 0 ? dontscale ? p : iscale(p, sz.cx, total) : 0; + pos += total > 0 ? dontscale ? p : iscale(p, sz.cx, t) : 0; UpdatePos(false, whenscroll); Refresh(); } @@ -233,10 +249,22 @@ int SlimScrollBar::GetTotal() const return total; } -void SlimScrollBar::SetTotal(int t) +void SlimScrollBar::SetTotal(int total, bool whenscroll) { - total = t; - UpdatePos(false); + Ctrl* q = GetParent(); + + Size sz = GetSize(); + Size psz = q ? q->GetSize() : Size(0, 0); + + Fix(sz); + Fix(psz); + + this->total = total; + this->t = total; + if(q) + this->t -= psz.cx - sz.cx; + + UpdatePos(false, whenscroll); Refresh(); } @@ -248,26 +276,25 @@ void SlimScrollBar::AddTotal(int t) if(total <= 0 || sz.cx <= 0) cs = ics = 0; else - cs = sz.cx / ((double) total + 0.5); - size = sz.cx * cs; - ps = min(ps, (double)(total - sz.cx)); + cs = sz.cx / ((double) t + 0.5); + size = int(sz.cx * cs); + ps = min(ps, (double)(t - sz.cx)); pos = (int)(ps * cs); old_pos = new_pos = (int)(pos - start_pos); - Refresh(); } -void SlimScrollBar::GoEnd() +void SlimScrollBar::GoEnd(bool whenscroll) { pos = total; - UpdatePos(false); + UpdatePos(false, whenscroll); Refresh(); } -void SlimScrollBar::GoBegin() +void SlimScrollBar::GoBegin(bool whenscroll) { pos = 0; - UpdatePos(false); + UpdatePos(false, whenscroll); Refresh(); } @@ -291,7 +318,7 @@ void SlimScrollBar::Set(const SlimScrollBar& t) bool SlimScrollBar::IsScrollable() const { - return total > sz.cx && sz.cx > 0; + return t > sz.cx && sz.cx > 0; } END_UPP_NAMESPACE \ No newline at end of file diff --git a/rainbow/WinGl/Scrollbar.h b/rainbow/WinGl/Scrollbar.h index 8e38adbe8..fedec579c 100644 --- a/rainbow/WinGl/Scrollbar.h +++ b/rainbow/WinGl/Scrollbar.h @@ -56,6 +56,7 @@ class SlimScrollBar : public AlignedFrame { private: int total; + int t; bool isend; bool isbegin; double pos, prev_ps, ps; @@ -83,9 +84,9 @@ class SlimScrollBar : public AlignedFrame void AddPos(int p, bool dontscale = false, bool whenscroll = true); int GetTotal() const; void AddTotal(int t); - void SetTotal(int t); - void GoEnd(); - void GoBegin(); + void SetTotal(int t, bool whenscroll = true); + void GoEnd(bool whenscroll = true); + void GoBegin(bool whenscroll = true); bool IsEnd(); bool IsBegin(); void Clear(); diff --git a/rainbow/WinGl/TopFrame.cpp b/rainbow/WinGl/TopFrame.cpp index cab845f9b..a9cd234f2 100644 --- a/rainbow/WinGl/TopFrame.cpp +++ b/rainbow/WinGl/TopFrame.cpp @@ -138,26 +138,9 @@ void TopWindowFrame::StartDrag() return; if(!sizeable && (dir.x || dir.y)) return; - if(FullWindowDrag) { - SetCapture(); - startrect = GetRect(); - startpos = GetMousePos(); - } - else { - Rect r = GetScreenRect(); - RectTracker tr(*this); - tr.SetCursorImage(GetDragImage(dir)) - .MaxRect(screenRect.GetSize()) - .MinSize(ComputeClient(minsize).GetSize()) - .Pattern(DRAWDRAGRECT_DASHED | DRAWDRAGRECT_SCREEN) - .Animation(); - PaintLock++; - r = tr.Track(r, dir.x < 0 ? ALIGN_LEFT : dir.x > 0 ? ALIGN_RIGHT : ALIGN_CENTER, - dir.y < 0 ? ALIGN_TOP : dir.y > 0 ? ALIGN_BOTTOM : ALIGN_CENTER); - PaintLock--; - SetRect(r); - } - LLOG("START DRAG ---------------"); + SetCapture(); + startrect = GetRect(); + startpos = GetMousePos(); } void TopWindowFrame::GripResize() @@ -169,42 +152,7 @@ void TopWindowFrame::GripResize() void TopWindowFrame::LeftDown(Point p, dword keyflags) { dir = GetDragMode(p); - if(dir.x || dir.y || FullWindowDrag) - StartDrag(); - else { - SetCapture(); - holding = true; - hold.Set(GetKbdDelay() / 3, THISBACK(Hold)); - } -} - -void TopWindowFrame::CancelMode() -{ - holding = false; -} - -void TopWindowFrame::LeftUp(Point p, dword keyflags) -{ - holding = false; -} - -void TopWindowFrame::Hold() -{ - if(HasCapture()) { - if(HasMouse() && GetMouseLeft() && holding) - StartDrag(); - ReleaseCapture(); - holding = false; - } -} - -void TopWindowFrame::LeftHold(Point p, dword keyflags) -{ - if(HasCapture() || FullWindowDrag) - return; - dir = GetDragMode(p); - if(!dir.x && !dir.y) - StartDrag(); + StartDrag(); } void TopWindowFrame::LeftDouble(Point p, dword keyflags) @@ -213,9 +161,14 @@ void TopWindowFrame::LeftDouble(Point p, dword keyflags) IgnoreMouseUp(); } +void TopWindowFrame::LeftUp(Point p, dword keyflags) +{ + ReleaseCapture(); +} + void TopWindowFrame::MouseMove(Point, dword) { - if(!HasCapture() || holding) + if(!HasCapture()) return; Size msz = ComputeClient(minsize).GetSize(); Point p = GetMousePos() - startpos; diff --git a/rainbow/WinGl/TopFrame.h b/rainbow/WinGl/TopFrame.h index 6ea6f40a2..ba1117c7d 100644 --- a/rainbow/WinGl/TopFrame.h +++ b/rainbow/WinGl/TopFrame.h @@ -11,11 +11,9 @@ public: virtual void Paint(Draw& w); virtual Image CursorImage(Point p, dword keyflags); virtual void LeftDown(Point p, dword keyflags); - virtual void LeftHold(Point p, dword keyflags); virtual void LeftDouble(Point p, dword keyflags); - virtual void MouseMove(Point p, dword keyflags); - virtual void CancelMode(); virtual void LeftUp(Point p, dword keyflags); + virtual void MouseMove(Point p, dword keyflags); private: Point dir; diff --git a/rainbow/WinGl/Util.cpp b/rainbow/WinGl/Util.cpp index bfc9a2c81..7845e5871 100644 --- a/rainbow/WinGl/Util.cpp +++ b/rainbow/WinGl/Util.cpp @@ -81,16 +81,6 @@ void DrawDragRect(SystemDraw& w, const Rect& rect1, const Rect& rect2, const Rec void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& clip, int n, Color color, int type, int animation) { - DragRect r; - r.rect1 = rect1; - r.rect2 = rect2; - r.clip = clip; - r.n = n; - r.color = color; - r.type = type; - r.animation = animation; - SystemDraw::dragRect.Add(r); - //q.DragRectDraw(rect1, rect2, clip, n, color, type, animation); } END_UPP_NAMESPACE diff --git a/rainbow/WinGl/Win.cpp b/rainbow/WinGl/Win.cpp index 3d9e4f7fb..729373735 100644 --- a/rainbow/WinGl/Win.cpp +++ b/rainbow/WinGl/Win.cpp @@ -11,6 +11,7 @@ HWND glHwnd = NULL; HDC hDC = NULL; HGLRC hRC = NULL; Shader alphaMagProg; +Shader blurProg; String error; #ifdef flagDEBUG @@ -22,12 +23,20 @@ bool consoleActive = false; #endif bool glEndSession = false; +bool glReady = false; + +int glDrawMode = DRAW_ON_IDLE; bool GlEndSession() { return glEndSession; } +bool GlReady() +{ + return glReady; +} + void GlQuitSession() { ::PostQuitMessage(0); @@ -171,10 +180,12 @@ int CreateGlContext() RLOG("OpenGL: CompileProgram ok.."); - wglSwapIntervalEXT(0); - - SetTimer(glHwnd, 1, 10, NULL); + wglSwapIntervalEXT(1); + + if(glDrawMode == DRAW_ON_TIMER) + SetTimer(glHwnd, 1, 10, NULL); RLOG("OpenGL: SetTimer ok.."); + glReady = true; return 1; } diff --git a/rainbow/WinGl/WinGl.h b/rainbow/WinGl/WinGl.h index 4c4127906..7b9170cd4 100644 --- a/rainbow/WinGl/WinGl.h +++ b/rainbow/WinGl/WinGl.h @@ -28,21 +28,27 @@ extern HWND glHwnd; extern HDC hDC; extern HGLRC hRC; extern Shader alphaMagProg; - +extern bool glReady; extern String error; +extern int glDrawMode; + +#define DRAW_ON_TIMER 0 +#define DRAW_ON_IDLE 1 int CreateGlWindow(HINSTANCE hInstance); int CreateGlContext(); void ActivateGlContext(); void DestroyGl(); LRESULT CALLBACK glWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); +int64 GetHighTickCount(); struct FrameInfo { + int64 curr_tick_count; float fps; float frame_factor; float frame_skip; - dword frame_time; - FrameInfo() : fps(0.f), frame_factor(1.f), frame_skip(60.f), frame_time(0) + int64 frame_time; + FrameInfo() : fps(0.f), frame_factor(1.f), frame_skip(60.f), frame_time(0), curr_tick_count(0) {} }; @@ -67,16 +73,8 @@ enum TransformState { TS_BEFORE_CTRL_PAINT, TS_AFTER_CTRL_PAINT, TS_BEFORE_PAINT, - TS_AFTER_PAINT -}; - -struct DragRect : Moveable { - Rect rect1, rect2; - Rect clip; - int n; - Color color; - int type; - int animation; + TS_AFTER_PAINT, + TS_SYNC_LAYOUT }; class SystemDraw : public Draw { @@ -89,8 +87,8 @@ public: void SetClipRect(const Rect& r); void ScissorClip(const Rect& r); void PlaneClip(const Rect& r); - void StencilClip(const Rect& r, int mode = 0); - void SetClip(const Rect& r, int mode = 0); + void StencilClip(const Rect& r, int mode = 0, bool exlude = false); + void SetClip(const Rect& r, int mode = 0, bool exclude = false); virtual void BeginOp(); virtual void EndOp(); @@ -135,7 +133,7 @@ public: private: - + static SystemDraw* systemDraw; friend class FontInfo; friend class Font; @@ -143,6 +141,7 @@ private: struct Cloff : Moveable { bool clipping; + bool exclude; Point org; Rect drawing_clip; }; @@ -164,9 +163,7 @@ public: float alpha; float angle; float scale; - - static Vector dragRect; - + private: Array cloff; int ci; @@ -183,7 +180,7 @@ protected: void Init(); public: - + static SystemDraw& Get() { return *systemDraw; } static void Flush() { /*glFlush();*/ } Point GetOffset() const { return drawing_offset; } SystemDraw(Size sz); @@ -250,6 +247,7 @@ void DrawDragRect(SystemDraw& w, const Rect& rect1, const Rect& rect2, const Rec bool GlIsWaitingEvent(); bool GlProcessEvent(bool *quit); void GlSleep(int ms); +bool GlReady(); bool GlEndSession(); void GlQuitSession(); diff --git a/rainbow/WinGl/WinGl.upp b/rainbow/WinGl/WinGl.upp index 7f339c63f..9002ce458 100644 --- a/rainbow/WinGl/WinGl.upp +++ b/rainbow/WinGl/WinGl.upp @@ -13,6 +13,7 @@ file ResGl.h, FontGl.h, Keys.h, + Resources.cpp, ControlPanel.h, ControlPanel.cpp, Scrollbar.h, @@ -47,6 +48,8 @@ file Resources.brc, Shaders.h, Shaders.cpp, + Blur.frag, + Blur.vert, AlphaMag.frag, AlphaMag.vert, WinGl.iml; diff --git a/rainbow/WinGl/Wnd.cpp b/rainbow/WinGl/Wnd.cpp index 5589d37ea..3e00cfff6 100644 --- a/rainbow/WinGl/Wnd.cpp +++ b/rainbow/WinGl/Wnd.cpp @@ -24,7 +24,6 @@ Rect Ctrl::glCaretRect; int Ctrl::glCaretTm; int64 Ctrl::glEventLoop = 0; int64 Ctrl::glEndSessionLoop = 0; -bool Ctrl::FullWindowDrag = false; int Ctrl::PaintLock; void GlLog(int line, const char* text, Color ink) @@ -61,7 +60,6 @@ void Ctrl::SetDesktop(Ctrl& q) { q.SetRect(screenRect.GetSize()); q.SetOpen(true); - q.SyncLayout(2); q.StateH(OPEN); q.NewTop(); desktop = &q; @@ -72,7 +70,6 @@ void Ctrl::SetWindowSize(Size sz) screenRect = sz; if(desktop) desktop->SetRect(screenRect); - SyncTopWindows(); } void Ctrl::InitGl() @@ -210,24 +207,32 @@ bool Ctrl::ProcessEvent(bool *quit) SyncCaret(); return true; } + else if(glDrawMode == DRAW_ON_IDLE) + DrawScreen(); + return false; } void Ctrl::DrawScreen() { - if(desktop && !painting) { - int t0 = GetTickCount(); + if(hRC && desktop && !painting) { + resources.BindStatic(); + int64 t0 = GetHighTickCount(); + frameInfo.curr_tick_count = t0; painting = true; - desktop->SyncLayout(2); + desktop->ApplyTransform(TS_SYNC_LAYOUT); + desktop->SyncLayout(); + for(int i = 0; i < topctrl.GetCount(); i++) { + Ctrl* tq = topctrl[i]; + tq->ApplyTransform(TS_SYNC_LAYOUT); + tq->SyncLayout(); + } Rect clip = desktop->GetRect(); SystemDraw draw(clip.GetSize()); infoPanel.Init(*desktop); infoPanel.Show(controlPanelActive); console.Init(*desktop); console.Show(consoleActive); - for(int i = 0; i < topctrl.GetCount(); i++) { - topctrl[i]->SyncLayout(2); - } draw.alpha = infoPanel.GetAlpha(); draw.angle = infoPanel.GetAngle(); draw.scale = infoPanel.GetScale(); @@ -236,23 +241,21 @@ void Ctrl::DrawScreen() desktop->ApplyTransform(TS_BEFORE_PAINT); desktop->CtrlPaint(draw, clip); for(int i = 0; i < topctrl.GetCount(); i++) { - if(topctrl[i] == &infoPanel || topctrl[i] == &console) + Ctrl* tq = topctrl[i]; + if(tq == &infoPanel || tq == &console) continue; - Rect r = topctrl[i]->GetRect(); - draw.Clipoff(r); - topctrl[i]->CtrlPaint(draw, clip); + Rect r = tq->GetRect(); + tq->ApplyTransform(TS_BEFORE_PAINT); + if(tq->cliptobounds) + draw.Clipoff(r); + else + draw.Offset(r.left, r.top); + tq->CtrlPaint(draw, clip); draw.End(); + tq->ApplyTransform(TS_AFTER_PAINT); } CursorSync(draw); - for(int i = 0; i < SystemDraw::dragRect.GetCount(); i++) - { - const DragRect& r = SystemDraw::dragRect[i]; - DrawDragRect(draw, r.rect1, r.rect2, r.clip, r.n, r.color, r.type, r.animation); - } - - SystemDraw::dragRect.Clear(); - desktop->ApplyTransform(TS_AFTER_PAINT); glLoadIdentity(); #if CLIP_MODE == 2 @@ -278,7 +281,7 @@ void Ctrl::DrawScreen() MouseSync(draw); SwapBuffers(hDC); painting = false; - int t1 = GetTickCount(); + int64 t1 = GetHighTickCount(); frameInfo.frame_time = t1 - t0; frameInfo.frame_factor = frameInfo.frame_time * frameInfo.frame_skip / 1000.f; frameInfo.fps = frameInfo.frame_time > 0.f ? 1000.f / (float)frameInfo.frame_time : 0.f; @@ -298,7 +301,7 @@ bool Ctrl::ProcessEvents(bool *quit) while(ProcessEvent(quit) && (!LoopCtrl || LoopCtrl->InLoop())); TimerProc(GetTickCount()); SweepMkImageCache(); - if(hRC) + if(glDrawMode == DRAW_ON_TIMER) DrawScreen(); return true; } @@ -322,7 +325,8 @@ void Ctrl::EventLoop0(Ctrl *ctrl) while(loopno > EndSessionLoopNo && !quit && (ctrl ? ctrl->IsOpen() && ctrl->InLoop() : GetTopCtrls().GetCount())) { SyncCaret(); - GuiSleep(20); + if(glDrawMode == DRAW_ON_TIMER) + GuiSleep(20); ProcessEvents(&quit); } @@ -558,8 +562,6 @@ void Ctrl::PopUp(Ctrl *owner, bool savebits, bool activate, bool dropshadow, boo } topctrl.Add(this); popup = isopen = true; - RefreshLayoutDeep(); - SyncLayout(2); StateH(OPEN); if(activate) SetFocusWnd(); } diff --git a/uppsrc/CtrlCore/CtrlDraw.cpp b/uppsrc/CtrlCore/CtrlDraw.cpp index aab1f6ee2..860a533e3 100644 --- a/uppsrc/CtrlCore/CtrlDraw.cpp +++ b/uppsrc/CtrlCore/CtrlDraw.cpp @@ -287,27 +287,29 @@ void Ctrl::CtrlPaint(SystemDraw& w, const Rect& clip, int depth) { if(viewexcluded) w.End(); - DOLEVELCHECK; + //DOLEVELCHECK; if(!oview.IsEmpty() && oview.Intersects(clip)) { glPushMatrix(); LEVELCHECK(w, this); if(overpaint) { - //if(cliptobounds) + if(cliptobounds) w.Clip(oview); w.Offset(view.left, view.top); Paint(w); PaintCaret(w); w.End(); - //if(cliptobounds) + if(cliptobounds) w.End(); } else { - //if(cliptobounds) - w.Clipoff(view); + if(cliptobounds) + w.Clip(view); + w.Offset(view.left, view.top); Paint(w); PaintCaret(w); - //if(cliptobounds) + w.End(); + if(cliptobounds) w.End(); } glPopMatrix(); @@ -319,7 +321,7 @@ void Ctrl::CtrlPaint(SystemDraw& w, const Rect& clip, int depth) { if(q->IsShown() && q->InView()) { Rect rr(q->popup ? clip : cl); LEVELCHECK(w, q); - //if(q->cliptobounds) + if(q->cliptobounds) w.Clip(rr); Rect qr = q->GetRect(); Point off = qr.TopLeft() + view.TopLeft(); @@ -329,7 +331,7 @@ void Ctrl::CtrlPaint(SystemDraw& w, const Rect& clip, int depth) { q->CtrlPaint(w, rr - off, depth + 1); w.End(); } - //if(q->cliptobounds) + if(q->cliptobounds) w.End(); } } diff --git a/uppsrc/CtrlCore/CtrlMouse.cpp b/uppsrc/CtrlCore/CtrlMouse.cpp index 96d94f332..f5a7e32f1 100644 --- a/uppsrc/CtrlCore/CtrlMouse.cpp +++ b/uppsrc/CtrlCore/CtrlMouse.cpp @@ -539,8 +539,13 @@ Image Ctrl::DispatchMouse(int e, Point p, int zd) { Image Ctrl::DispatchMouseEvent(int e, Point p, int zd) { GuiLock __; +#ifdef flagWINGL + if(!IsEnabled() && this != (Ctrl*) &infoPanel) + return Image::Arrow(); +#else if(!IsEnabled()) return Image::Arrow(); +#endif if(captureCtrl && captureCtrl != this && captureCtrl->IsMouseActive()) return captureCtrl->MEvent0(e, p + GetScreenRect().TopLeft() - captureCtrl->GetScreenRect().TopLeft(), zd); diff --git a/uppsrc/CtrlCore/CtrlPos.cpp b/uppsrc/CtrlCore/CtrlPos.cpp index 3ea580059..716631f2e 100644 --- a/uppsrc/CtrlCore/CtrlPos.cpp +++ b/uppsrc/CtrlCore/CtrlPos.cpp @@ -136,6 +136,32 @@ Size Ctrl::GetMaxSize() const return GetVirtualWorkArea().Size(); } +#ifdef flagWINGL +void Ctrl::SyncLayout(int force) +{ + GuiLock __; + Rect view = GetRect().Size(); + overpaint = OverPaint(); + + for(int i = 0; i < frame.GetCount(); i++) { + Frame& f = frame[i]; + f.frame->FrameLayout(view); + if(view != f.view) { + f.view = view; + } + int q = f.frame->OverPaint(); + if(q > overpaint) overpaint = q; + } + + for(Ctrl *q = GetFirstChild(); q; q = q->next) { + q->rect = q->CalcRect(rect, view); + q->SyncLayout(); + } + + State(LAYOUTPOS); + Layout(); +} +#else void Ctrl::SyncLayout(int force) { GuiLock __; @@ -162,17 +188,14 @@ void Ctrl::SyncLayout(int force) } Refresh(); } - #ifdef flagWINGL - if(oview != view) { - #else if(oview != view || force) { - #endif State(LAYOUTPOS); Layout(); } if(refresh) RefreshFrame(); } +#endif int Ctrl::FindMoveCtrl(const VectorMap& m, Ctrl *x) { @@ -186,6 +209,7 @@ Ctrl::MoveCtrl *Ctrl::FindMoveCtrlPtr(VectorMap& m, Ctrl *x) return q >= 0 ? &m[q] : NULL; } +#ifdef flagWINGL void Ctrl::SetPos0(LogPos p, bool _inframe) { GuiLock __; @@ -198,11 +222,31 @@ void Ctrl::SetPos0(LogPos p, bool _inframe) pos = p; inframe = _inframe; Rect to = GetRect().Size(); - #ifdef flagWINGL UpdateRect0(false); - #else + StateH(POSITION); + return; + } + RefreshFrame(); + } + pos = p; + inframe = _inframe; + UpdateRect0(true); + StateH(POSITION); +} +#else +void Ctrl::SetPos0(LogPos p, bool _inframe) +{ + GuiLock __; + if(p == pos && inframe == _inframe) return; + if(parent) { + Rect from = GetRect().Size(); + Top *top = GetTopRect(from, true)->top; + if(top) { + LTIMING("SetPos0 MoveCtrl"); + pos = p; + inframe = _inframe; + Rect to = GetRect().Size(); UpdateRect0(); - #endif GetTopRect(to, true); MoveCtrl *s = FindMoveCtrlPtr(top->scroll_move, this); if(s && s->from == from && s->to == to) { @@ -226,6 +270,7 @@ void Ctrl::SetPos0(LogPos p, bool _inframe) UpdateRect(); StateH(POSITION); } +#endif void Ctrl::UpdateRect0(bool sync) { diff --git a/uppsrc/CtrlLib/Static.cpp b/uppsrc/CtrlLib/Static.cpp index 8a6d74ef3..00d3cb37a 100644 --- a/uppsrc/CtrlLib/Static.cpp +++ b/uppsrc/CtrlLib/Static.cpp @@ -87,6 +87,9 @@ LabelBox::LabelBox() { LabelBase::SetInk(LabelBoxTextColor, LabelBoxDisabledTextColor); SetVAlign(ALIGN_TOP); + #ifdef flagWINGL + ClipToBounds(false); + #endif } void LabelBox::AssignAccessKeys(dword used) diff --git a/uppsrc/Draw/DrawText.cpp b/uppsrc/Draw/DrawText.cpp index cf0439f9e..dc54a3e8e 100644 --- a/uppsrc/Draw/DrawText.cpp +++ b/uppsrc/Draw/DrawText.cpp @@ -180,7 +180,7 @@ void Draw::DrawText(int x, int y, const String& text, Font font, Color ink, cons Size GetTextSize(const wchar *text, Font font, int n) { #ifdef flagWINGL - return GetTextSize(text, Resources::GetFont(font), n); + return GetTextSize(text, resources.GetFont(font), n); #else FontInfo fi = font.Info(); if(n < 0) diff --git a/uppsrc/Draw/FontWin32.cpp b/uppsrc/Draw/FontWin32.cpp index ca3131aad..adabe44e6 100644 --- a/uppsrc/Draw/FontWin32.cpp +++ b/uppsrc/Draw/FontWin32.cpp @@ -245,7 +245,7 @@ Vector GetAllFacesSys() GlyphInfo GetGlyphInfoSys(Font font, int chr) { static GlyphInfo gi; - const OpenGLFont& fi = Resources::GetFont(font); + const OpenGLFont& fi = resources.GetFont(font); gi.width = chr < fi.chars.GetCount() ? int(fi.chars[chr].xadvance * fi.scale + 0.5f) : 0;