smashthewindow Posted March 26, 2012 Share Posted March 26, 2012 GWEN is a GUI system written by Garry Newman, creator of Garry's Mod. I was in the process of writing a GWEN Leadwerks Renderer using only native commands (unlike all the other libraries out there), but is leaving at it's current progress. The main reason is the inability to crop textures only using native Leadwerks commands. (Using OpenGL is a solution though.) Even though not all the features are converted to Leadwerks, below library is more than enough to write a beautiful imageless GUI in Leadwerks. (Which is basically what I want ) I'm posting it here in hopes of someone benefiting out of this in some way. The Header. #ifndef GWEN_RENDERERS_LEADWERKS_H #define GWEN_RENDERERS_LEADWERKS_H #include "Gwen/Gwen.h" #include "Gwen/BaseRender.h" namespace Gwen { namespace Renderer { class Leadwerks : public Gwen::Renderer::Base { public: Leadwerks(); ~Leadwerks(); virtual void Begin(); virtual void End(); virtual void SetDrawColor( Color color ); virtual void DrawFilledRect( Gwen::Rect rect ); virtual void LoadTexture( Gwen::Texture* pTexture ); virtual void FreeTexture( Gwen::Texture* pTexture ); virtual void DrawTexturedRect( Gwen::Texture* pTexture, Gwen::Rect pTargetRect, float u1=0.0f, float v1=0.0f, float u2=1.0f, float v2=1.0f ); virtual void LoadFont( Gwen::Font* pFont ); virtual void FreeFont( Gwen::Font* pFont ); virtual void RenderText( Gwen::Font* pFont, Gwen::Point pos, const Gwen::UnicodeString& text ); virtual Gwen::Point MeasureText( Gwen::Font* pFont, const Gwen::UnicodeString& text ); virtual void DrawPixel( int x, int y ); virtual Gwen::Point MeasureText( Gwen::Font* pFont, const Gwen::String& text ); virtual void RenderText( Gwen::Font* pFont, Gwen::Point pos, const Gwen::String& text ); }; } } #endif And the cpp file. Make sure to read comments . #include <GwenRenderersLeadwerks.h> #include <GwenUtility.h> #include <GwenTexture.h> #include <engine.h> namespace Gwen { namespace Renderer { Leadwerks::Leadwerks() { } Leadwerks::~Leadwerks() { } void Leadwerks::Begin() { LE::SetBlend(1); } void Leadwerks::End() { LE::SetBlend(0); } void Leadwerks::SetDrawColor( Color color ) { LE::TVec4 c; c.X = color.r/255; c.Y = color.g/255; c.Z = color.b/255; c.W = color.a/255; LE::SetColor( c ); } void Leadwerks::DrawFilledRect( Gwen::Rect rect ) { Translate( rect ); if( rect.w == 1 ) { LE::DrawLine( rect.x, rect.y, rect.x, rect.y + rect.h ); return; } if( rect.h == 1 ) { LE::DrawLine( rect.x, rect.y, rect.x + rect.w, rect.y ); return; } LE::DrawRect( rect.x, rect.y, rect.w, rect.h ); } void Leadwerks::LoadTexture( Gwen::Texture* pTexture ) { BP tex = LE::LoadTexture( pTexture->name.Get().c_str() ); pTexture->data = tex; pTexture->failed = (tex == nullptr); pTexture->width = LE::TextureWidth( tex ); pTexture->height = LE::TextureHeight( tex ); } void Leadwerks::FreeTexture( Gwen::Texture* pTexture ) { LE::FreeTexture( (BP)pTexture->data ); } void Leadwerks::DrawTexturedRect( Gwen::Texture* pTexture, Gwen::Rect pTargetRect, float u1, float v1, float u2, float v2 ) { //Ignore this function. Right now you can't crop textures in Leadwerks. /* Translate( pTargetRect ); LE::DrawImage( (BP)pTexture->data, pTargetRect.x, pTargetRect.y, pTargetRect.w, pTargetRect.h ); */ } void Leadwerks::LoadFont( Gwen::Font* pFont ) { //Uncomment the lines below if you're going to use Leadwerks fonts. //I personally prefer the default font better... /* TFont font = LE::LoadFont( Gwen::Utility::UnicodeToString(pFont->facename).c_str() ); LE::SetFont(font); pFont->data = font; */ pFont->realsize = LE::FontHeight(); } void Leadwerks::FreeFont( Gwen::Font* pFont ) { if( pFont->data ) LE::FreeFont( (BP)pFont->data ); } void Leadwerks::RenderText( Gwen::Font* pFont, Gwen::Point pos, const Gwen::UnicodeString& text ) { RenderText( pFont, pos, Gwen::Utility::UnicodeToString(text) ); } Gwen::Point Leadwerks::MeasureText( Gwen::Font* pFont, const Gwen::UnicodeString& text ) { return MeasureText( pFont, Gwen::Utility::UnicodeToString(text) ); } void Leadwerks::DrawPixel( int x, int y ) { Translate( x, y ); LE::Plot( x, y ); } Gwen::Point Leadwerks::MeasureText( Gwen::Font* pFont, const Gwen::String& text ) { if( pFont->data ) LoadFont( pFont ); return Gwen::Point( LE::TextWidth( text.c_str()), LE::FontHeight() ); } void Leadwerks::RenderText( Gwen::Font* pFont, Gwen::Point pos, const Gwen::String& text ) { Translate( pos.x, pos.y ); if( pFont->data ) LoadFont( pFont ); LE::DrawTextA( pos.x, pos.y, text.c_str() ); } } } 1 Quote Blog & Portfolio Current project: moon.chase.star Link to comment Share on other sites More sharing options...
Pixel Perfect Posted March 26, 2012 Share Posted March 26, 2012 Thanks for the code. I'll have a play with this when I get a bit of spare time. Quote Intel Core i5 2.66 GHz, Asus P7P55D, 8Gb DDR3 RAM, GTX460 1Gb DDR5, Windows 7 (x64), LE Editor, GMax, 3DWS, UU3D Pro, Texture Maker Pro, Shader Map Pro. Development language: C/C++ Link to comment Share on other sites More sharing options...
LEFans Posted March 27, 2012 Share Posted March 27, 2012 Thank you.Can share a simple and complete example? Quote AMD3600+/2GB DDR3 SDRAM / GeForce 8600 GTS I3 530/2GB DDR3/GF GT240 DDR5 Link to comment Share on other sites More sharing options...
smashthewindow Posted April 29, 2012 Author Share Posted April 29, 2012 I took a break from coding due to heavy workload on school life, but I finally got to work. I went to finishing the renderer was like the first thing I done when I got back, so here it is. I had to rely on a few OpenGL functions but it's not that heavy. #ifndef GWEN_RENDERERS_LEADWERKS_H #define GWEN_RENDERERS_LEADWERKS_H #include <Gwen/Gwen.h> #include <Gwen/BaseRender.h> #include <engine.h> #include <glGL.h> #include <glGLU.h> namespace Gwen { namespace Renderer { class Leadwerks : public Gwen::Renderer::Base { public: Leadwerks(); ~Leadwerks(); virtual void Begin(); virtual void End(); virtual void SetDrawColor( Color color ); virtual void DrawFilledRect( Gwen::Rect rect ); virtual void LoadTexture( Gwen::Texture* pTexture ); virtual void FreeTexture( Gwen::Texture* pTexture ); virtual void DrawTexturedRect( Gwen::Texture* pTexture, Gwen::Rect pTargetRect, float u1=0.0f, float v1=0.0f, float u2=1.0f, float v2=1.0f ); virtual void LoadFont( Gwen::Font* pFont ); virtual void FreeFont( Gwen::Font* pFont ); virtual void RenderText( Gwen::Font* pFont, Gwen::Point pos, const Gwen::UnicodeString& text ); virtual Gwen::Point MeasureText( Gwen::Font* pFont, const Gwen::UnicodeString& text ); virtual void DrawPixel( int x, int y ); virtual void DrawLinedRect( Gwen::Rect rect ); virtual Gwen::Point MeasureText( Gwen::Font* pFont, const Gwen::String& text ); virtual void RenderText( Gwen::Font* pFont, Gwen::Point pos, const Gwen::String& text ); private: enum CullMode { CULL_NONE, CULL_DRAW_CCW, CULL_DRAW_CW }; void leglBegin (TCamera camera = NULL, float zoom = 1.0f, CullMode cm = CULL_DRAW_CCW); void leglEnd (bool was3D = false); void leglBindTexture(TTexture texture); }; } } #endif #include "Renderer.h" #include <GwenUtility.h> #include <GwenTexture.h> #include <engine.h> namespace Gwen { namespace Renderer { Leadwerks::Leadwerks() { } Leadwerks::~Leadwerks() { } void Leadwerks::Begin() { LE::SetBlend(1); } void Leadwerks::End() { LE::SetBlend(0); } void Leadwerks::SetDrawColor( Color color ) { LE::TVec4 c; c.X = color.r/255; c.Y = color.g/255; c.Z = color.b/255; c.W = color.a/255; LE::SetColor( c ); } void Leadwerks::DrawFilledRect( Gwen::Rect rect ) { Translate( rect ); if( rect.w == 1 && rect.h == 1 ) { LE::Plot( rect.x, rect.y ); return; } if( rect.w == 1 ) { LE::DrawLine( rect.x, rect.y, rect.x, rect.y + rect.h ); return; } if( rect.h == 1 ) { LE::DrawLine( rect.x, rect.y, rect.x + rect.w, rect.y ); return; } LE::DrawRect( rect.x, rect.y, rect.w, rect.h ); } void Leadwerks::LoadTexture( Gwen::Texture* pTexture ) { BP tex = LE::LoadTexture( pTexture->name.Get().c_str() ); pTexture->data = tex; pTexture->failed = (tex == nullptr); if( tex != nullptr ) { pTexture->width = LE::TextureWidth( tex ); pTexture->height = LE::TextureHeight( tex ); } } void Leadwerks::FreeTexture( Gwen::Texture* pTexture ) { LE::FreeTexture( (BP)pTexture->data ); } void Leadwerks::DrawTexturedRect( Gwen::Texture* pTexture, Gwen::Rect pTargetRect, float u1, float v1, float u2, float v2 ) { Translate( pTargetRect ); leglBegin(); leglBindTexture( (BP)pTexture->data ); glBegin( GL_QUADS ); glTexCoord2f(u2, v2); glVertex2i(pTargetRect.x + pTargetRect.w, pTargetRect.y + pTargetRect.h); glTexCoord2f(u2, v1); glVertex2i(pTargetRect.x + pTargetRect.w, pTargetRect.y); glTexCoord2f(u1, v1); glVertex2i(pTargetRect.x, pTargetRect.y ); glTexCoord2f(u1, v2); glVertex2i(pTargetRect.x, pTargetRect.y + pTargetRect.h ); glEnd(); leglBindTexture(NULL); leglEnd(); } void Leadwerks::LoadFont( Gwen::Font* pFont ) { if( Gwen::Utility::UnicodeToString(pFont->facename) != "Default" ) { TFont font = LE::LoadFont( Gwen::Utility::UnicodeToString(pFont->facename).c_str() ); LE::SetFont(font); pFont->data = font; } pFont->size = LE::FontHeight(); } void Leadwerks::FreeFont( Gwen::Font* pFont ) { if( pFont->data ) LE::FreeFont( (BP)pFont->data ); } void Leadwerks::RenderText( Gwen::Font* pFont, Gwen::Point pos, const Gwen::UnicodeString& text ) { RenderText( pFont, pos, Gwen::Utility::UnicodeToString(text) ); } Gwen::Point Leadwerks::MeasureText( Gwen::Font* pFont, const Gwen::UnicodeString& text ) { return MeasureText( pFont, Gwen::Utility::UnicodeToString(text) ); } void Leadwerks::DrawLinedRect( Gwen::Rect rect ) { Translate( rect ); LE::DrawLine( rect.x + 1, rect.y, rect.x + rect.w - 1, rect.y ); LE::DrawLine( rect.x + rect.w, rect.y, rect.x + rect.w, rect.y + rect.h ); LE::DrawLine( rect.x + rect.w - 1, rect.y + rect.h, rect.x + 1, rect.y + rect.h ); LE::DrawLine( rect.x, rect.y + rect.h, rect.x, rect.y ); } void Leadwerks::DrawPixel( int x, int y ) { Translate( x, y ); LE::Plot( x, y ); } Gwen::Point Leadwerks::MeasureText( Gwen::Font* pFont, const Gwen::String& text ) { if( pFont->data ) LoadFont( pFont ); return Gwen::Point( LE::TextWidth( text.c_str()), LE::FontHeight() ); } void Leadwerks::RenderText( Gwen::Font* pFont, Gwen::Point pos, const Gwen::String& text ) { Translate( pos.x, pos.y ); if( pFont->data ) LoadFont( pFont ); LE::DrawTextA( pos.x, pos.y, text.c_str() ); } void Leadwerks::leglBegin(TCamera camera, float zoom, CullMode cm) { // Setup projetion according to argument if (NULL != camera) { // Save current projection matrix. Then reset glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); // Calculate the view frustum float nearRange, farRange; GetCameraRange(camera, nearRange, farRange); float theta = 1.0f / zoom; // tan(45°) = 1.0f float aspect = float(BufferWidth(CurrentBuffer()))/BufferHeight(CurrentBuffer()); glFrustum (-nearRange*theta, nearRange*theta, -nearRange/aspect*theta, nearRange/aspect*theta, nearRange,farRange); // Reset transformation glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); // LE uses a differently handed coordinate system than ogl does glScalef(1.0f, 1.0f, -1.0f); // Calculate the LookAt vectors (camera direction and up vector)... TVec3 from = EntityPosition(camera, true); TVec3 to = {0,0,-1}; to = TFormVector(to, camera, NULL); to += from; TVec3 up = {0,1,0}; up = TFormVector(up, camera, NULL); // Set LookAt gluLookAt(from.X, from.Y, from.Z, to.X, to.Y , to.Z, up.X, up.Y, up.Z); } else { glPushMatrix(); // Set orthographic projection (used for 2D drawing) // Get the current viewport/buffer size. int vPort[4]; glGetIntegerv(GL_VIEWPORT, vPort); // Set the projection gluOrtho2D(0, vPort[2], vPort[3], 0); // like glOrtho(0, vPort[2], vPort[3], 0, -1, 1); // Reset transformation glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); } // Setup default drawing settings. // Alpha blending. glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Backface culling. if (CULL_NONE != cm)glEnable(GL_CULL_FACE); if (NULL != camera)glCullFace((CULL_DRAW_CCW == cm) ? GL_BACK : GL_FRONT); else glCullFace((CULL_DRAW_CCW == cm) ? GL_FRONT : GL_BACK); // Depth test for 3D projection if (NULL != camera)glEnable(GL_DEPTH_TEST); // Drawing color. glColor4f(1.0f, 1.0f, 1.0f, 1.0f); } // Use NULL (0) for the texture to reset (bind no texture) void Leadwerks::leglBindTexture(TTexture texture) { if(NULL != texture) { glEnable(GL_TEXTURE_2D); BindTexture(texture, 0); // LE command. } else { glBindTexture(GL_TEXTURE_2D, NULL); glDisable(GL_TEXTURE_2D); } } // End drawing. Set "was3D" to true if you specified a camera at leglBegin (= used 3D projection). void Leadwerks::leglEnd(bool was3D) { // Undo changes only made in 3D mode (camera != NULL) if (was3D) { glMatrixMode(GL_PROJECTION); glPopMatrix(); glDisable(GL_DEPTH_TEST); } else glPopMatrix(); // Reset transformation. glMatrixMode(GL_MODELVIEW); glPopMatrix(); // Undo changed settings. glDisable(GL_BLEND); glCullFace(GL_BACK); glDisable(GL_CULL_FACE); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); leglBindTexture(NULL); } } } /* GWEN Copyright (c) 2011 Facepunch Studios See license in Gwen.h */ #ifndef GWEN_INPUT_LEADWERKS_H #define GWEN_INPUT_LEADWERKS_H #include "Gwen/InputHandler.h" #include "Gwen/Gwen.h" #include "Gwen/Controls/Canvas.h" #include <engine.h> namespace Gwen { namespace Input { class Leadwerks { public: Leadwerks() { m_Canvas = NULL; m_MouseX = 0; m_MouseY = 0; m_MouseZ = 0; m_LMouseDown = false; m_RMouseDown = false; m_MMouseDown = false; } void Initialize( Gwen::Controls::Canvas* c ) { m_Canvas = c; } bool ProcessMessage( void ) { if ( !m_Canvas ) return false; if( m_MouseX != LE::MouseX() || m_MouseY != LE::MouseY() ) { int dx = LE::MouseX() - m_MouseX; int dy = LE::MouseY() - m_MouseY; m_MouseX = LE::MouseX(); m_MouseY = LE::MouseY(); return m_Canvas->InputMouseMoved( LE::MouseX(), LE::MouseY(), dx, dy ); } //TODO:: Charatcer input if( m_MouseZ != LE::MouseZ() ) { int dz = LE::MouseZ() - m_MouseZ; return m_Canvas->InputMouseWheel( dz ); } if( m_LMouseDown != LE::MouseDown( LE::MOUSE_LEFT ) ) { m_LMouseDown = LE::MouseDown( LE::MOUSE_LEFT ); return m_Canvas->InputMouseButton( 0, m_LMouseDown ); } if( m_RMouseDown != LE::MouseDown( LE::MOUSE_RIGHT ) ) { m_RMouseDown = LE::MouseDown( LE::MOUSE_RIGHT ); return m_Canvas->InputMouseButton( 1, m_RMouseDown ); } if( m_MMouseDown != LE::MouseDown( LE::MOUSE_MIDDLE ) ) { m_MMouseDown = LE::MouseDown( LE::MOUSE_MIDDLE ); return m_Canvas->InputMouseButton( 2, m_MMouseDown ); } //KEY INPUT if( LE::KeyHit( LE::KEY_RSHIFT ) || LE::KeyHit( LE::KEY_LSHIFT ) ) { bool down = LE::KeyDown( LE::KEY_RSHIFT ) || LE::KeyDown( LE::KEY_LSHIFT ); return m_Canvas->InputKey( Gwen::Key::Shift, down ); } if( LE::KeyHit( LE::KEY_ENTER ) ) { bool down = LE::KeyDown( LE::KEY_ENTER ); return m_Canvas->InputKey( Gwen::Key::Return, down ); } if( LE::KeyHit( LE::KEY_BACKSPACE ) ) { bool down = LE::KeyDown( LE::KEY_BACKSPACE ); return m_Canvas->InputKey( Gwen::Key::Backspace, down ); } if( LE::KeyHit( LE::KEY_DELETE ) ) { bool down = LE::KeyDown( LE::KEY_DELETE ); return m_Canvas->InputKey( Gwen::Key::Delete, down ); } if( LE::KeyHit( LE::KEY_LEFT ) ) { bool down = LE::KeyDown( LE::KEY_LEFT ); return m_Canvas->InputKey( Gwen::Key::Left, down ); } if( LE::KeyHit( LE::KEY_RIGHT ) ) { bool down = LE::KeyDown( LE::KEY_RIGHT ); return m_Canvas->InputKey( Gwen::Key::Right, down ); } if( LE::KeyHit( LE::KEY_TAB ) ) { bool down = LE::KeyDown( LE::KEY_TAB ); return m_Canvas->InputKey( Gwen::Key::Tab, down ); } if( LE::KeyHit( LE::KEY_SPACE ) ) { bool down = LE::KeyDown( LE::KEY_SPACE ); return m_Canvas->InputKey( Gwen::Key::Space, down ); } if( LE::KeyHit( LE::KEY_HOME ) ) { bool down = LE::KeyDown( LE::KEY_HOME ); return m_Canvas->InputKey( Gwen::Key::Home, down ); } if( LE::KeyHit( LE::KEY_END ) ) { bool down = LE::KeyDown( LE::KEY_END ); return m_Canvas->InputKey( Gwen::Key::End, down ); } if( LE::KeyHit( LE::KEY_RCONTROL ) || LE::KeyHit( LE::KEY_LCONTROL ) ) { bool down = LE::KeyDown( LE::KEY_RCONTROL ) || LE::KeyDown( LE::KEY_LCONTROL ); return m_Canvas->InputKey( Gwen::Key::Control, down ); } if( LE::KeyHit( LE::KEY_UP ) ) { bool down = LE::KeyDown( LE::KEY_UP ); return m_Canvas->InputKey( Gwen::Key::Up, down ); } if( LE::KeyHit( LE::KEY_DOWN ) ) { bool down = LE::KeyDown( LE::KEY_DOWN ); return m_Canvas->InputKey( Gwen::Key::Down, down ); } return false; } protected: Gwen::Controls::Canvas* m_Canvas; int m_MouseX; int m_MouseY; int m_MouseZ; bool m_LMouseDown; bool m_RMouseDown; bool m_MMouseDown; }; } } #endif Big thanks to Masterxilo who wrote the OpenGL tutorial over here. Quote Blog & Portfolio Current project: moon.chase.star Link to comment Share on other sites More sharing options...
DigitalHax Posted April 29, 2012 Share Posted April 29, 2012 Thanks for this! I'll have a go with it. By the way, what do you need to name the 3 different bits of code you provided? Like *.cpp or *.h Quote Win7 64bit, Leadwerks SDK 2.5, Visual Studio 2012, 3DWS, 3ds Max, Photoshop CS5. Life is too short to remove USB safely. Link to comment Share on other sites More sharing options...
Josh Posted April 29, 2012 Share Posted April 29, 2012 I like this, it's a GUI library that isn't complete garbage. Garry is a good coder. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Rick Posted April 30, 2012 Share Posted April 30, 2012 I like this because he uses the same event styles I use. This is a very nice and clean way to do events. No polling! Button* pQuitButton= new Button( this ); pQuitButton->onPress.Add( this, &MyDerivedControl::OnQuit ); @Smash, could you package this up in a zip file and attach it to the post if possible? Just a little cleaner than scrapping the site. Big thanks for doing this! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.