Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ Widgets - General questions or Mixed problems » Taking snapshot of GLCtrl no longer works
Taking snapshot of GLCtrl no longer works [message #52184] Mon, 05 August 2019 12:20 Go to next message
Tom1
Messages: 635
Registered: March 2007
Contributor
Hi,

I have not worked with GLCtrl for a while. Now as I tried to recompile my old program, I found out that my code taking snapshot of the GLCtrl contents no longer works. It just returns a black image:

		Size sz=GetSize();
		ImageBuffer ib(sz);
		glReadPixels(0,0,sz.cx,sz.cy,GL_BGRA_EXT,GL_UNSIGNED_BYTE,(GLvoid*)(RGBA*)ib);


Any suggestions how to proceed?

Best regards,

Tom
Re: Taking snapshot of GLCtrl no longer works [message #52192 is a reply to message #52184] Wed, 07 August 2019 14:50 Go to previous messageGo to next message
Tom1
Messages: 635
Registered: March 2007
Contributor
Hi,

I just cannot get around this issue for some reason. When I call glGetError(), it simply returns GL_INVALID_OPERATION.

I'm not in a middle of a glBegin/glEnd -pair either. The code worked/works on Upp svn 11960, and I have tried many options for format parameter here without any success.

I guess this is somehow related to the changes done to GLCtrl some time ago, but I cannot see the relevant change compared to the previous version.

BTW, I'm working on Windows 10 x64.

Any help will be appreciated!

Best regards,

Tom
Re: Taking snapshot of GLCtrl no longer works [message #52194 is a reply to message #52192] Wed, 07 August 2019 16:45 Go to previous messageGo to next message
Tom1
Messages: 635
Registered: March 2007
Contributor
Hi,

OK, I see that nowadays this only works in GLPaint() routine, but not out side of it anymore. I think there is no longer access to the appropriate context after GLPaint is finished.

Best regards,

Tom
Re: Taking snapshot of GLCtrl no longer works [message #52206 is a reply to message #52194] Fri, 09 August 2019 09:13 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 11991
Registered: November 2005
Ultimate Member
Tom1 wrote on Wed, 07 August 2019 16:45
Hi,

OK, I see that nowadays this only works in GLPaint() routine, but not out side of it anymore. I think there is no longer access to the appropriate context after GLPaint is finished.

Best regards,

Tom


Actually, there is now just single context that is moved to window before GLPaint and disconnected after it.
Re: Taking snapshot of GLCtrl no longer works [message #52207 is a reply to message #52206] Fri, 09 August 2019 09:26 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 11991
Registered: November 2005
Ultimate Member
There is now new ExecuteGL method to resolve this issue - it sets the context, executes any GL code, then finishes. For now only implemented in Win32.

Can you try if that solves your problem please?

Also, I would appreciate a code snippet you are using to capture the Image, I would like to incorporate it to some reference example.
Re: Taking snapshot of GLCtrl no longer works [message #52212 is a reply to message #52207] Fri, 09 August 2019 11:00 Go to previous messageGo to next message
Tom1
Messages: 635
Registered: March 2007
Contributor
Hi Mirek,

Yes, thanks! This ExecuteGL approach works beautifully. Could you add this to Linux and OSX too? (Although, I still don't have any of those Macs.)

Here's how to get the snapshot:

	String exportdir;
	
	virtual void ExportViewAsImage(){
		Size sz=GetSize();
		ImageBuffer ib(sz);

		glReadPixels(0,0,sz.cx,sz.cy,GL_BGRA_EXT,GL_UNSIGNED_BYTE,(GLvoid*)~ib);
		if(!glGetError()){
			// Flip
			Buffer<RGBA> temp(sz.cx);
			for(int i=0;i<sz.cy/2;i++){
				memcpy(temp,ib[i],sz.cx*sizeof(RGBA));
				memcpy(ib[i],ib[sz.cy-1-i],sz.cx*sizeof(RGBA));
				memcpy(ib[sz.cy-1-i],temp,sz.cx*sizeof(RGBA));
			}
			
			// Flatten alpha channel
			for(int i=0;i<sz.cy;i++){
				for(int x=0;x<sz.cx;x++) ib[i][x].a=255;
			}
	
			// Save image
			FileSel fs;
			fs.Type("Portable Network Graphics (*.png)","*.png");
			if(!exportdir.IsEmpty()) fs.PreSelect(exportdir);
			else fs.ActiveDir(::GetDesktopFolder());
			if(fs.ExecuteSaveAs("Save snapshot as...")){
				exportdir=~fs;
				PNGEncoder enc;
				enc.SaveFile(~fs,ib);
			}
		}
	}
	
	void ContextMenu(Bar& bar) {
		bar.Add("Export view as image...", [&](){ ExecuteGL(THISFN(ExportViewAsImage)); });
	}


Thanks and best regards,

Tom
Re: Taking snapshot of GLCtrl no longer works [message #52214 is a reply to message #52212] Fri, 09 August 2019 14:00 Go to previous messageGo to next message
Tom1
Messages: 635
Registered: March 2007
Contributor
Hi,

This new ExecuteGL also helped me in cleanly pre-loading the textures and allowed dropping the source images/rasters right after that. This saves quite a bit of RAM.

Thanks,

Tom
Re: Taking snapshot of GLCtrl no longer works [message #52215 is a reply to message #52214] Fri, 09 August 2019 16:29 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 11991
Registered: November 2005
Ultimate Member
Now works in GTK too.

As for textures, that was actually the primary motivation for changes. It should actually be possible to create textures without ExecuteGL, all that is needed is a call to GLCtrl::CreateContext before it. (It gets called on GLCtrl creation too).

Mirek
Re: Taking snapshot of GLCtrl no longer works [message #52221 is a reply to message #52212] Sun, 11 August 2019 18:45 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 2979
Registered: August 2008
Veteran
Thank you for the changes.

Tom code works well for me, but even though it works, after glReadPixels a GL_INVALID_OPERATION is got.
Is it a problem?


Best regards
Iñaki
Re: Taking snapshot of GLCtrl no longer works [message #52222 is a reply to message #52221] Mon, 12 August 2019 07:42 Go to previous messageGo to next message
Tom1
Messages: 635
Registered: March 2007
Contributor
Hi Koldo,

Have you tried to call 'glGetError()' just before taking the snapshot? This would clear any errors prior to calling 'glReadPixels()'. Since you can get the actual snapshot done, it does not sound logical the 'glReadPixels()' would be the one to fail with GL_INVALID_OPERATION. (Just for reference, I do not get GL_INVALID_OPERATION here. Running on latest Windows 10 x64 with Intel Core i9 integrated graphics.)

Best regards,

Tom
Re: Taking snapshot of GLCtrl no longer works [message #52224 is a reply to message #52215] Mon, 12 August 2019 08:52 Go to previous messageGo to next message
Tom1
Messages: 635
Registered: March 2007
Contributor
Hi Mirek,

Thanks for making it work in Linux too. Test result: OK! (Linux Mint 19.2 on a virtual machine.)

Best regards,

Tom
Re: Taking snapshot of GLCtrl no longer works [message #52228 is a reply to message #52222] Mon, 12 August 2019 16:00 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 2979
Registered: August 2008
Veteran
Hi Tom

Yes, you are right. A failed operation activates glGetError(), but a successful one does not clean it Smile
It works perfectly in W10.

In addition, it also works well in Ubuntu 16.04 LTS.


Best regards
Iñaki

[Updated on: Mon, 12 August 2019 16:00]

Report message to a moderator

Re: Taking snapshot of GLCtrl no longer works [message #52232 is a reply to message #52222] Mon, 12 August 2019 21:50 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 11991
Registered: November 2005
Ultimate Member
Tom1 wrote on Mon, 12 August 2019 07:42
Hi Koldo,

Have you tried to call 'glGetError()' just before taking the snapshot? This would clear any errors prior to calling 'glReadPixels()'. Since you can get the actual snapshot done, it does not sound logical the 'glReadPixels()' would be the one to fail with GL_INVALID_OPERATION. (Just for reference, I do not get GL_INVALID_OPERATION here. Running on latest Windows 10 x64 with Intel Core i9 integrated graphics.)

Best regards,

Tom


I can add glGetError to ExecuteGL. Should I?
Re: Taking snapshot of GLCtrl no longer works [message #52234 is a reply to message #52232] Tue, 13 August 2019 09:07 Go to previous message
Tom1
Messages: 635
Registered: March 2007
Contributor
Hi Mirek,

Maybe that is a good idea, actually before calling GLExecute() and GLPaint() too. However, the GLExecute() and GLPaint() should only be called if glGetError() does not have any errors pending from its own initialization. This way we can always trust in GLExecute() and GLPaint() that the initialization of GL has been successful and any GL errors are due to our own code. This may require something to handle errors inside GLCtrl.

Best regards,

Tom
Previous Topic: Deleting Ctrl from within itself
Next Topic: Add compilable testcases for nontrivial problems!
Goto Forum:
  


Current Time: Tue Aug 20 00:39:43 CEST 2019

Total time taken to generate the page: 0.01010 seconds