Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Di Mai 14, 2024 13:12

Foren-Übersicht » English » English Programming Forum
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 17 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
BeitragVerfasst: Mi Jul 11, 2007 12:09 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 24, 2007 00:44
Beiträge: 144
Has anyone had any experience of displaying the contents of a Delphi TWebBrowser in OpenGL? Of course, the VCL component itself can just be put on top of anything you are rendering in OpenGL I guess, but I don't think that would look very good. I'm sure there will be challenges around scrolling the TWebBrowser and everything else, but I was wondering whether there was a way to render the contents of the TWebBrowser window to OpenGL... as a texture or something. Or are there other ways I haven't even thought of? Any ideas / pointers appreciated.

_________________
Cheers, DpM
http://www.hmusiccentre.org.uk


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jul 11, 2007 19:42 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
You can get an IViewObject with: WebBrowser.ControlInterface as IViewObject
The ViewObject can draw to a Device Context of a Bitmap although it is not very fast.

Code:
  1. var
  2.   View: IViewObject;
  3.   r: TRect;
  4.   bmp: TBitmap;
  5. begin
  6.   view := webbrowser.controlinterface as IViewObject;
  7.   r := rect(x, y, x + width, y + width);
  8.   WebBrowser.Width := width;
  9.   WebBrowser.Height := Height;
  10.   bmp := TBitmap.Create;
  11.   bmp.PixelFormat := pf32bit;
  12.   bmp.Width := width;
  13.   bmp.Height := height;
  14.   view.Draw(DVASPECT_CONTENT, 1, nil, nil, 0, bmp.canvas.Handle, @r, nil, nil, 0);
  15.  
  16.   // Copy bmp into Texture
  17. end;
  18.  


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Nov 21, 2007 20:16 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 24, 2007 00:44
Beiträge: 144
This works fine. Thank you. I have just given it a go - I was wondering, is there any clever way to get (I really mean 'display' in OpenGL) the entirety of a site, i.e. one that the user can scroll down on too - or should I provide some kind of Page Down / Page Up buttons in my OpenGL program that link to some code that then auto-scrolls the browser by a whole page, takes another snapshot image and the reloads that as a texture into OpenGL - thus (rather slowly, as you say) showing the new information in the browser?

_________________
Cheers, DpM
http://www.hmusiccentre.org.uk


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Nov 22, 2007 00:09 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 24, 2007 00:44
Beiträge: 144
Actually... I've made some interesting progress. I can now successfully take a snapshot of a URL from the Browser component and get the totality of the URL saved - not just what's currently on display in the browser window. However, my real purpose for wanting this was to save and display Wikipedia artist biographies in my program... for example - Shakira at http://en.wikipedia.org/wiki/Shakira ...

Previously I had just opened up a Browser in my application, but I'm not that happy with that and sometimes I get some funny z-order fighting going on and people have said it didn't work properly under Vista for some reason. So - saving to an image that I could load as a texture seemed the way to go. However, I've now arrived at a different issue (I think)...

The biography for Shakira actually looks really nice, but it turns out to be a 625 x 10,095 pixel image and is over 2 meg in size. Yes, 10,095... the single JPG looks like this (scaled down to 10%):

Bild

Madness! How am I supposed to go about loading that into my OpenGL program... the next PoT after that is 16,384 and, even if that doesn't cause a problem, how do I go about displaying it?

Code for anyone who is interested...

Code:
  1. procedure TForm1.FormShow ( Sender : TObject
  2.                           );
  3. begin
  4.   wbBrowser.Navigate ('http://en.wikipedia.org/wiki/Shakira');
  5. end;
  6.  
  7.  
  8. procedure TForm1.btnSaveClick ( Sender : TObject
  9.                               );
  10. var
  11.   P : TPoint;
  12.   IDoc1 : IHTMLDocument2;
  13.   Web : IWebBrowser2;
  14. begin
  15.   with wbBrowser do
  16.   begin
  17.     Document.QueryInterface (IHTMLDocument2,iDoc1);
  18.     Web := ControlInterface;
  19.     TControl (wbBrowser).Visible := Boolean (0);
  20.     P := GetDocumentSize (wbBrowser);
  21.     Height := P.Y + 20;
  22.     SaveWikipediaBiographyAsJPG (Web,'C:\Biography.jpg',P.X,P.Y);
  23.   end;
  24. end;
  25.  
  26.  
  27. procedure TForm1.SaveWikipediaBiographyAsJPG ( Browser : iWebBrowser2;
  28.                                                Filename : String;
  29.                                                W, H : Integer
  30.                                             );
  31. const
  32.   WikipediaWidth = 160;
  33.   ScrollbarWidth = 20;
  34.   HeaderHeight = 50;
  35.   FooterHeight = 176;
  36. var
  37.   SourceDrawRect : TRect;
  38.   SourceBitmap : TBitmap;
  39.   JPEG : TJPEGImage;
  40.   ViewObject : IViewObject;
  41. begin
  42.   SourceBitmap := TBitmap.Create;
  43.   JPEG := TJPEGImage.Create;
  44.   try
  45.     SourceDrawRect := Rect (0,0,W,H);
  46.     SourceBitmap.Width := W;
  47.     SourceBitmap.Height := H;
  48.  
  49.     ViewObject := Browser as IViewObject;
  50.     ViewObject.Draw (DVASPECT_CONTENT,1,nil,nil,0,SourceBitmap.Canvas.Handle,@SourceDrawRect,nil,nil,0);
  51.  
  52.     { Crop out the left-hand side Wikipedia banner, header, scrollbar and footer... }
  53.     SourceBitmap.Canvas.CopyRect (Rect (0,0,W - (WikipediaWidth + ScrollbarWidth),H - (HeaderHeight + FooterHeight)),SourceBitmap.Canvas,Rect (WikipediaWidth,HeaderHeight,W - ScrollbarWidth,H - FooterHeight));
  54.     SourceBitmap.Width := W - (WikipediaWidth + ScrollBarWidth);
  55.     SourceBitmap.Height := H - (HeaderHeight + FooterHeight);
  56.  
  57.     JPEG.Assign (SourceBitmap);
  58.     JPEG.SaveToFile (Filename);
  59.   finally
  60.     JPEG.Free;
  61.     SourceBitmap.Free;
  62.   end;
  63. end;

_________________
Cheers, DpM
http://www.hmusiccentre.org.uk


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Nov 22, 2007 01:12 
Offline
Ernährungsberater
Benutzeravatar

Registriert: Sa Jan 01, 2005 17:11
Beiträge: 2067
Programmiersprache: C++
Dynamic loading. You just have the current view and the previous and the next view in memory. If the user starts scrolling you dynamically load and dispose your resources. Should work fine if the user doesn't request a special position without your range. Then it may stock a little but it may be worth a try.
Take a look on tutorials about displaying a map, this is nearly the same, just in one more dimension.

_________________
Steppity,steppity,step,step,step! :twisted:
❆ ❄ ❄ ❄ ❅ ❄ ❆ ❄ ❅ ❄ ❅ ❄ ❅ ❄ ❄
❄ ❄ ❄ ❅ ❄ ❄ ❄ ❅ ❄ ❄ ❆ ❄ ❄


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Nov 22, 2007 20:26 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2621
Wohnort: Berlin
Programmiersprache: Go, C/C++
The easiest way i think is a kind of Virtual Texture.
A fix size of Texture (1024x1024) and an little algo who load the new visible part of the real image in the virtual texture.
If you scroll on a the image you normally move the image some pixels on x or y.
You can move the imagedata in the virtual texture on x or y and load the new needed part of the image on the fly.
A block base format like dds(dxt) would be a good base.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Nov 23, 2007 01:27 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 24, 2007 00:44
Beiträge: 144
I would like to be able to display the image on screen and scroll down using my MCE IR Remote's cursor keys... just up and down, no left or right. I don't even know how to go about starting to load only part of the image in though... up to now I have been using Textures.pas to load in my textures and I just pass that a filename and a GLUInt... then I've got a texture. Easy.

Is the suggestion now that I actually load the whole file into a TJPG but only build the part of the texture I want at any one time, say the 1024x1024 - or maybe (if I can scale the Wikipedia webpage down to 512 pixels wide) 512x512 and then somehow load little bits into texture memory as I scroll down the image?

Or is the suggestion that I somehow only load part of the file on disk into texture memory and repeatedly do this for whichever section I'm displaying?

How do I even start?

_________________
Cheers, DpM
http://www.hmusiccentre.org.uk


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Nov 23, 2007 09:32 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
In my opinion the view of an webpage is only temporary for 1-6 minutes. Right? This could make the handling much easier. So you don't should write the image to the disk. And never with an jpeg (to much cpu load while loading and saving). Hold the whole webpage in the source TBitmap. Thats the easiest and fastest way. And the webpages don't get too large. If it is to large you can't create the image anyway.

You can't (shouldn't) use things like Textures.pas. Because they normally load the the textures from disc and creates it with gluBuildMipMaps. This may resize your texture and create mip map on the CPU. This is really slow. So its better to create all the textures by yourself. But i think you need more than one texture to draw it on the screen.

For an example look at the image below. From left right you are scrolling down. The blue line marks your monitor. The red rect is the texture 1 and the green is the texture 2. Wenn you are scrolling down and the green (2) texture is at the end you should draw the red (1) texture under the green (2) but before you must copy new imagedata into it. To optimze its possible to cut the green texture at the first time. Because in this case only one is visible.

BUT depending on the resolution its possible that you need more than one texture in the horizontal so you should program this very flexible. And also for vertical. Its possible that 2 x 1024 are to small for an technic like this. So it's necessare to use 3 textures in the vertical. But the principle is always the same.

To Create an empty texture and update date you need to do this.
Code:
  1. - create Texture object (glGenTexture)
  2. - setup parameters (filter etc.)
  3. - allocate the texture (glTexImage2D with width and hight BUT with NIL as data pointer. So the texture will be allocated with zero filled data.)


Now you are able to copy some data with glTexSubImage. Depending on size etc. But beware. The TBitmap store his data from the bottom to the top and if you have more than one texture in the horizontal you can't copy the whole block at one. So i think it's better to copy line by line. But this isn't to perfect way. But even faster than gluBuildMipMaps. ;)


Dateianhänge:
screens.png
screens.png [ 1.36 KiB | 8158-mal betrachtet ]
Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Nov 23, 2007 09:37 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 24, 2007 00:44
Beiträge: 144
Wow. This may take me some time, but I will certainly give it a go and report back to the forum. Many thanks.

_________________
Cheers, DpM
http://www.hmusiccentre.org.uk


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Nov 23, 2007 13:40 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 24, 2007 00:44
Beiträge: 144
Well, first things first... rather than have the strange 625 pixel width, I have altered my code so that it sets the Wikipedia saved page width to be 512 pixels. So I am now dealing with (continuing with Shakira as my example) a 512x11,537 image... that's actually a 2.35mb JPG or a 22.5mb 24-bit BMP on disk for information. More to follow...

_________________
Cheers, DpM
http://www.hmusiccentre.org.uk


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Nov 23, 2007 14:40 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2621
Wohnort: Berlin
Programmiersprache: Go, C/C++
Don't scale down only up or equal size or you lose image information.
768(source width) scaled up to 1024 then you can copy the source with same resolution in the destination and change the max Texcoords to 768(source resolution)/1024(destination resolution)=0.xxx=MaxU.

Code:
  1. glTexcoord(0,0);
  2. ...
  3. glTexcoord(MaxU,MaxV);

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Nov 23, 2007 17:12 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 24, 2007 00:44
Beiträge: 144
OK. I've done it and it looks pretty good I think. Although I'm not sure I'm doing it the most efficient way. The stages I go through are as follows:

1) Hit a Wikipedia URL - the attached program goes to the Shakira article.
2) Get the browser page dimensions (the limits that it wants to be).
3) Set the browser width so the Wikipedia page (when I've stripped out the left-hand area) is actually going to be 512 pixels wide.
4) Grab the image as a 24-bit bitmap and crop it - remove left-hand side, header, footer etc..
5) Copy the first TRect (0,0,512,512) to a 512x512 pixel GeneratedBitmap of type TBitmap - when scrolled the Y 0 and 512 would be +YOffset.
6) Assign a Byte array and copy the GeneratedBitmap's RGB values across to it.
7) Use glTexImage2D to blast the Byte array into my texture... BiographyTexture.

Display the image on on the pOGL TPanel and allow the user to scroll up and down with Up and Down arrows and PgUp and PgDn. This is the meat of the conversion procedure that I've come up with...

Code:
  1.  
  2. procedure TfrmMain.CopySubBitmapToTexture;
  3. var
  4.   RowLoop, ColLoop, Index : Integer;
  5.   ScanLine : PRGBArray;
  6. begin
  7.   GeneratedBitmap := TBitmap.Create;
  8.   GeneratedBitmap.PixelFormat := pf24bit;
  9.   GeneratedBitmap.Width := OpenGLTextureSize;
  10.   GeneratedBitmap.Height := OpenGLTextureSize;
  11.  
  12.   { SourceBitmap is our massive 512xLargeNumber bitmap. Copy part of it... }
  13.   GeneratedBitmap.Canvas.CopyRect (Rect (0,0,OpenGLTextureSize,OpenGLTextureSize),SourceBitmap.Canvas,Rect (0,YOffset,OpenGLTextureSize,OpenGLTextureSize + YOffset));
  14.  
  15.   { Copy the TBitmap's pixels to an array of Byte. }
  16.   Index := 0;
  17.   for RowLoop := GeneratedBitmap.Height - 1 downto 0 do
  18.   begin
  19.     ScanLine := GeneratedBitmap.ScanLine[RowLoop];
  20.     for ColLoop := 0 to GeneratedBitmap.Width - 1 do
  21.     begin
  22.       GeneratedByteArray[Index] := ScanLine[ColLoop].rgbtRed;
  23.       GeneratedByteArray[Index + 1] := ScanLine[ColLoop].rgbtGreen;
  24.       GeneratedByteArray[Index + 2] := ScanLine[ColLoop].rgbtBlue;
  25.       Inc (Index,3);
  26.     end;
  27.   end;
  28.  
  29.   { Pass this Byte array to our texture... }
  30.   glTexImage2D (GL_TEXTURE_2D,0,GL_RGB,OpenGLTextureSize,OpenGLTextureSize,0,GL_RGB,GL_UNSIGNED_BYTE,GeneratedByteArray);
  31.   GeneratedBitmap.Free;
  32. end;
  33.  

My question about this is simply... is there a better way to do this? Is there a way that I can avoid the conversion of TBitmap to Byte array to Texture and jump straight from a TBitmap to a Texture?

By the way, performance is fine - looks cool too... have a go with the attached program.


Dateianhänge:
DpM-Example.zip [5.97 KiB]
300-mal heruntergeladen

_________________
Cheers, DpM
http://www.hmusiccentre.org.uk
Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Nov 23, 2007 17:51 
Offline
Ernährungsberater
Benutzeravatar

Registriert: Sa Jan 01, 2005 17:11
Beiträge: 2067
Programmiersprache: C++
Do I read it right that you're updating the image every frame the user scrolls?
Better create a second texture like on Lossy's picture. This is much faster.

_________________
Steppity,steppity,step,step,step! :twisted:
❆ ❄ ❄ ❄ ❅ ❄ ❆ ❄ ❅ ❄ ❅ ❄ ❅ ❄ ❄
❄ ❄ ❄ ❅ ❄ ❄ ❄ ❅ ❄ ❄ ❆ ❄ ❄


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Nov 23, 2007 18:09 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 24, 2007 00:44
Beiträge: 144
Um, yeah - I am... but it works fine though... the user is basically allowed to scroll down (10 pixels at a time) or page down (512 pixels)... so each time I copy the newly cropped part of the image across it gets there pretty quickly. I can be at the top of a Wikipedia article and just press Pg Down and hold it - it looks fine and gets to the bottom pretty quickly - not slow and doesn't flicker or lag or anything... and this is on a crappy laptop. Now, I might like ultra-smooth scrolling... but is it worth the effort? I dunno... what's my advantage to having two textures?

Also... on some very large Wikipedia articles I get an EOutOfResources exception with "There is not enough storage to process this command" which is a shame... but I guess it's simply down to the size of the bitmaps and the amount of RAM I have. Something to be wary of nevertheless... the article that I was trying to load was a 33,989 pixel high article. I will have to catch that and react appropriately of course.

This is partially why I'm mostly curious if there's a way of avoiding creating the Byte array - then I could save some resources.

_________________
Cheers, DpM
http://www.hmusiccentre.org.uk


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Nov 23, 2007 18:18 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 24, 2007 00:44
Beiträge: 144
With just some simple testing... hitting Wikipedia URLs for "Madonna" and "Queen (band)" it seems my system's personal break point is somewhere between image sizes of 18,771 and 21,215 - the former works and the latter excepts.

_________________
Cheers, DpM
http://www.hmusiccentre.org.uk


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 17 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Foren-Übersicht » English » English Programming Forum


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.030s | 19 Queries | GZIP : On ]