Game Development Community

Torque 3D Embedded Browser (WebKit)

by Josh Engebretson · in Torque 3D Professional · 01/15/2010 (8:55 pm) · 305 replies

Hey guys,

Here are some highlights:

1) It uses QtWebKit which is based off Apple's WebKit, the same HTML5/Canvas based web rendering engine from Chrome, Safari, Adobe AIR

2) QtWebKit is *easily* the best designed embeddable web browser I have found in exhaustive travels... (I actually compiled Chrome from source at one point, not recommended). Qt is *extremely* well supported and owned by Nokia who recently paid $153,000,000 for it. So, it is probably going to be around for some time.

3) Flash works :)

4) It is setup as a GuiControl so interacts perfectly with mouse events, control overlap, filters...

There are currently 3 rendering modes:

torque.mythoslabs.com/static/t3d_web_rendertexture.jpg
1) Render to Texture: This mode renders the web view to an offscreen buffer and then uploads it to a GFXTexHandle. It uses the Torque GUI system input for mouse and keyboard. As we're rendering to a texture, compositing and rendering to 3d surfaces is possible. Flash renders as long as it is set to windowless mode in the HTML (not a big deal). Instead of using Flash for anything other than presentation/video playback, I would suggest looking into Canvas/HTML5/CSS animations/effects in this mode.

torque.mythoslabs.com/static/t3d_web_rendernative.jpg
2) Render Native: This mode integrates a native child window with Gui Control, giving the best of both worlds :) There is no need to render to texture as we're using an actual clipped child HWND which uses the Torque GUI system for position/extents and focus :) Transparency does not currently work, however under Vista/Win7 this should be possible. I should be able to get masking working with minimal effort, which would allow for shaped windows and transparent areas.

torque.mythoslabs.com/static/t3d_web_renderpopup.jpg
3) Render Popup: This mode pops up a standalone window, which is owned by the application and consistent in scripting with other modes. This is useful for things like integrated document browsing, tutorial video watching, game doc reading, game forum reading, etc... where you don't want to crowd your game interface with browser. However, you want CLOSE scripted integration with a standard browser (no worries of IE/Mozilla/Chrome), which isn't possible with the current "launch browser" functionality.

These modes work with HTTPS adding a nice way to authenticate to servers, secure purchasing, etc.

It is still pretty early in the development and the idea with the code release will be to get feedback on usability and features... especially WRT integration with Javascript on the page, etc.

EDIT: The first version has been released and is available HERE

Regards,
- Josh Engebretson
Mythos Labs, LLC
#261
05/14/2012 (1:12 pm)
Update: Still slogging through this. I still plan to have a finished product here this Friday but, in the meantime, I want to share some updates.

I've got it up and running with the latest Qt (4.8.1), but I'm having issues linking the webkit textures. Just a temp setback I'm sure. :)

Some hints and gotchas for people trying to follow along:

* This is a great link for getting Qt 4.7 or 4.8 working with Visual Studio 2010: http://www.holoborodko.com/pavel/2011/02/01/how-to-compile-qt-4-7-with-visual-studio-2010/

* Make sure you use 'jom' (see the link above) to bring down the build times!

* You'll need Perl to build Qt 4.8. I'm using "Strawberry Perl" (http://strawberryperl.com/).
#262
05/18/2012 (9:38 am)
Here's how I got QtWebKit to work with T3D 1.2 (on a Windows 7 OS, using Visual Studio 10):

I started with downloading the latest version QT: http://download.qt.nokia.com/qt/source/qt-win-opensource-4.8.1-vs2010.exe

Use the installer with the destination folder: C:\Qt\4.8.1

The installation will require Perl, which you can get from here: http://strawberryperl.com/

Download the latest version of jom ( ftp://ftp.qt.nokia.com/jom/ ) and extract it into C:\Qt\Jom

Start the Visual Studio 2010 Command Prompt (Start->Programs->Microsoft Visual Studio 2010->Visual Studio Tools->Visual Studio Command Prompt) and run the following commands:

cd c:\Qt\4.8.1
configure -debug-and-release -opensource -stl -no-qt3support -platform win32-msvc2010 -no-phonon -no-phonon-backend
..\jom\jom.exe -j 4

The '4' in the last step should be set to the number of physical cores on your machine.

Even with multiple cores, these steps may take hours. Get started now, I'll go over the rest of the steps later.
#263
05/18/2012 (12:10 pm)
(Note: Most of the changes listed below are just a collection of fixes posted previously in this thread.)

Before you close the command window, type in the following command:
bin\qtvars.bat

We also need to add "C:\Qt\4.8.1\bin" to your Windows 'Environment Variables' (so your finished program can find the Qt DLLs).

Now, download a fresh copy of the WebKitDemo and make the following change to the WebKitDemo\buildFiles\config\project.conf:

- $qtdir = "C:/Qt/QtCustom4.6.2";
+ $qtdir = "C:/Qt/4.8.1";

Now you can go ahead and generate projects (double click "generateProjects.bat" in the WebKitDemo folder).

Download my code fixes and use it to replace the following files:
source\web\guiWebCore.cpp
source\web\guiWebCtrl.cpp
source\web\guiWebView.cpp
source\web\guiWebViewMoc.cpp
source\myGameTSCtrl.cpp

Open up buildFiles\VisualStudio 2010\WebKitDemo.sln in Visual Studio.

In the 'Solution Explorer', right click 'zlib' and select 'Properties'.
Select 'C/C++', then 'Preprocessor'. Add "Z_PREFIX" (without quotes) to the list of 'Preprocessor Definitions'.

(more to follow)
#264
05/18/2012 (12:21 pm)

Code Changes to Torque Engine source:


We need to make NamedTexTarget::getTexture virtual in Engine\source\materials\matTextureTarget.h:

- GFXTextureObject* getTexture( U32 index = 0 ) const;
+ virtual GFXTextureObject* getTexture( U32 index = 0 ) const;

Next add the following to InstancingMaterialHook::getInstancingMat in Engine\source\ts\instancingMatHook.cpp:

features.addFeature( MFT_UseInstancing ); 

+     Material::sAllowTextureTargetAssignment = true;
       if ( !instMat->init( features, matInst->getVertexFormat() ) )
          SAFE_DELETE( instMat );
+     Material::sAllowTextureTargetAssignment = false;

      hook->mMatInst = instMat;


Finally, Qt 4.8.1 uses stl so we're going to have to make a minor function name change to avoid conflicts. Change the following line in Engine\source\core\tAlgorithm.h:

- inline void swap( T &left, T &right )
+ inline void torque_swap( T &left, T &right )

Rebuild the project and replace 'swap' that come up as errors with 'torque_swap' in the following files:
Engine\source\forest\forestWindMgr.cpp
Engine\source\math\mathUtils.cpp
Engine\source\math\mIntersector.h
Engine\source\math\mPlaneSet.h
Engine\source\sfx\sfxController.cpp

Build, run, and enjoy the magic! ;)

Let me know if you have any questions...
#265
05/18/2012 (6:35 pm)
@Doug
I must say I am very impressed from how fast you made it work and the way you explained what needs to be done yet although knowing the bits and bytes is important and highly appreciated...
I still have some questions:
Why I still can't download an updated patch to the stock engine source code that includes all the files compiled and source changes...
I think that it will make this project more accessible...
Can I use Qt SDK version 1.2.1?
I would like to know if you think my following resource is useful and can be used instead of qt webkit
Berkelium off-screen Google's Chromium web browser rendering
Check out this video www.youtube.com/watch?v=zUdrflSOe_Q
#266
05/19/2012 (12:51 pm)
Quote:
Why I still can't download an updated patch to the stock engine source code that includes all the files compiled and source changes...

The code is not officially supported code.
#267
05/19/2012 (1:13 pm)
Why I still can't download an updated patch to the stock engine source code that includes all the files compiled and source changes "Unofficially"?...
#268
05/19/2012 (3:52 pm)
Thank you for the time you put into this Doug, I was able to follow your directions well. I have the webkit running, and I can open and use the browser from the home screen successfully.

However, when I try to enter a game, I get a crash in matInstance.cpp, at line 440: "mProcessedMaterial->setTransforms(matrixSet, state, getCurPass());"

Any idea what could be causing this?

#269
05/21/2012 (3:27 pm)
@Jack: Did you make sure to make the change to InstancingMaterialHook::getInstancingMat?

Material::sAllowTextureTargetAssignment = true; // add this line
       if ( !instMat->init( features, matInst->getVertexFormat() ) )
          SAFE_DELETE( instMat );
     Material::sAllowTextureTargetAssignment = false; // and this line
#270
05/21/2012 (3:40 pm)
Possibly related to Jack Stone's issue: I also got a crash when loading a mission -- though the example browser from the menu worked fine -- until I deleted all shaders (in the shaders directory) and copy/pasted from a newer version of the engine than what was included in the WebKitDemo package.
#271
05/21/2012 (5:46 pm)
Michael, Thank you, that fixed my issue! Much appreciated. Resource working well now, thanks Doug!
#272
05/22/2012 (9:48 am)
Hello,

I wish to know if when you using the popup mode or the native mode, the background undergoes some slowdown?

#273
05/24/2012 (6:05 am)
@Doug thank you, I was able to get this running in my dev environment.

@anyone

I was having a look at this link and thinking about overlaying some nice webkit css styled huds/forms...

labs.qt.nokia.com/2009/06/30/transparent-qwebview-or-qwebpage/

I added the above changed, but have not had much luck. All I seem to be able to manage is a black background...

I also attempted this change thinking the background could now in fact be transparent, but the texture was missing an alpha channel or there was background fill going on (or something)

mWebImage = new QImage( mTexSize, mTexSize, QImage::Format_ARGB32);
      mWebImage->fill(qRgba(0, 0, 0, 0));

I'm not sure where to look, but could the issue be with mCurrentTexture?

here:

if (mMode == GuiWebView::RENDER_TEXTURE)
   {
      U32 a = U32(mOpacity * 255.f);
      if (a > 255)
         a = 255;
      GFX->getDrawUtil()->setBitmapModulation(ColorI(255, 255, 255, a));
      RectI rect(offset, getExtent());
      RectI srcRect(Point2I(0,0),getExtent());
      GFX->getDrawUtil()->drawBitmapStretchSR(mCurrentTexture, rect, srcRect);
   }

Any pointers by anyone would be greatly appreciated. Will post back if I stumble on the solution.

Cheers
#274
06/02/2012 (9:28 pm)
OK...an update on this...

The following code creates the desired transparent webpage (albeit a separate application window atm) when the .gui file is loaded. So the update is that the transparent part is working and I've tracked the issue to be when making it a child of the game window...now just to make them work together.

Would still appreciate any advice/thoughts on how to achieve this.

Cheers

J

In GuiWebView::GuiWebView() : QWebView()

QPalette palette = this->palette();
   palette.setBrush(QPalette::Base, Qt::transparent);
   this->page()->setPalette(palette);
   this->setPalette(palette);

   connect(this, SIGNAL(loadStarted()),
      this, SLOT(loadStartedSlot()));

In bool GuiWebView::setMode(RenderMode mode, S32 texSize)

if (mode == RENDER_NATIVE)
   {
      mMode = mode;
      setWindowFlags(Qt::FramelessWindowHint);
      setAttribute(Qt::WA_OpaquePaintEvent, false);
      //setAttribute(Qt::WA_NoSystemBackground);
      setAttribute(Qt::WA_TranslucentBackground);
      //setAutoFillBackground(false);
      //LONG exStyle = GetWindowLong(winId(), GWL_EXSTYLE) | WS_EX_NOACTIVATE | WS_EX_NOPARENTNOTIFY;// | WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOPMOST;
      //SetWindowLong(winId(), GWL_EXSTYLE, exStyle);
      //SetParent(winId(), getWin32WindowHandle());
      show();
   }
#275
06/15/2012 (4:17 am)
Snap...got it (well the proof of concept at least) Running in texture mode...

The intent is to be able to do something like this

The trick from my initial problem was to set the textures to transparent.

In bool GuiWebCtrl::onAdd()

GBitmap bmpA( mTexSize, mTexSize, false, GFXFormatR8G8B8A8 );
         bmpA.fill(ColorI(0,0,0,0));
         mTextureObjectA.set(&bmpA, &GFXDefaultStaticDiffuseProfile, false, avar("%s() -  (line %d)", __FUNCTION__, __LINE__));
         GBitmap bmpB( mTexSize, mTexSize, false, GFXFormatR8G8B8A8 );
         bmpB.fill(ColorI(0,0,0,0));
         mTextureObjectB.set(&bmpB, &GFXDefaultStaticDiffuseProfile, false, avar("%s() -  (line %d)", __FUNCTION__, __LINE__));


In GuiWebView::GuiWebView() : QWebView()

QPalette palette = this->palette();
   palette.setBrush(QPalette::Base, Qt::transparent);
   this->page()->setPalette(palette);
   this->setPalette(palette);

   setAttribute(Qt::WA_OpaquePaintEvent);
   setAttribute(Qt::WA_TranslucentBackground);

And in bool GuiWebView::setMode(RenderMode mode, S32 texSize)

//mWebImage = new QImage( mTexSize, mTexSize, QImage::Format_RGB32);
      mWebImage = new QImage( mTexSize, mTexSize, QImage::Format_ARGB32);
      mWebImage->fill(qRgba(0, 0, 0, 0));
      mWebBits = mWebImage->bits();

And in my test Fn I've simply got:

%ctrl = new GuiWebCtrl(MyWebCtrl) {
         //renderMode = "native";
         renderMode = "texture";
         fps = "24";
         texSize = "1024";
         //url = "https://encrypted.google.com/webhp?hl=en";
         url = "file:///art/test.html";
         horizSizing = "windowRelative";
         vertSizing = "windowRelative";

...

Canvas.add(%ctrl);

EDIT: fixed markup
#276
08/09/2012 (5:14 pm)
Thought I chime in and pass a bit information on to everyone. Eric mentioned this in passing in his latest blog and I talked about it in another thread a bit earlier.

If you're wanting to use this resource with the current version of QtWebkit to play any media you will be disappointed unfortunately. In a project we're working on that was using this we discovered there is an issue in Qt preventing it.

In QtWebkit 4.8 the media functionality was moved to another library called QtMobility, which means you need to add this library to your code as well. The rub comes from the fact that QtMobility 1.2 (the version that has that functionality in it) is incompatible with QtWebkit 4.8. I'll just let that sink in for a second.

.....

So, yeah, wanting to use any media at all in combination with this resource means you have to take one of two routes. Use an older version of QtWebkit like 4.7.x, not a great solution but the only one if you're really intent on using Qt. The other is to use Awesomium instead of QtWebkit. We picked the latter. I can't release the code for it right now as it's tied to a service contract, but ripping out Qt and replacing it with Awesomium is fairly straight forward. If you have the docs up for both API's while doing it you can find the Awesomium equivalents to the Qt calls.
#277
08/09/2012 (7:02 pm)
I will say that I've only heard good things about Awesomium. Berkelium is another open source library of a similar nature, but I've not heard it reviewed.
#278
08/09/2012 (8:25 pm)
Awesomium has better integration with .Net than Berkelium...
"ripping out Qt and replacing it with Awesomium is fairly straight forward" when can we see a plug-in/kit with a simple patch and decent support to Indie Developers wanting to create a Garage Game without the need to be a C++ Game Engine Core developer...
#279
08/10/2012 (9:03 am)
@Tomer
We have no plans to make this into a kit, that's why it released as resource to begin with a couple years ago. Resources released by GG employees, past or present, have to follow the same rules as other resources.
#280
08/10/2012 (7:04 pm)
Ok no kit. There is a free Unity 3D Plugin at http://awesomium.com/download/
How about 1 zip file I can use to patch the stock engine after downloading QtWebkit 4.7.x SDK or Awesomium SDK?
Why anyone should use Torque if there is no end user solution for such basic functionality?