Write your own Einstein@home screensaver

Mike Hewson
Mike Hewson
Moderator
Joined: 1 Dec 05
Posts: 6591
Credit: 324552139
RAC: 177192

Slow but steady progress on

Slow but steady progress on the HUD aspect. I've decided to create a relatively small class hierarchy to enact this. If done right it could form a reasonable HUD mini "content management system" that others might use. The idea being you decide on text or image or whatever, and then place those elements within 'containers' and then arrange the containers within the entire HUD, +/- justifications ( ie. distribution of 'clear space' above the minimum required to display the elements ). With the advantage of auto-resizing. But we'll see .... :-0

Also firming up is the concept of a 'Hall of Fame' where E@H discoveries are highlighted when coming into ( the ever-changing ) view, thus triggering an associated story or 'bio' in the HUD. So yes, our contributors who have hit the jackpot with the 'discovery' WU's will get their names in lights!! :-)

My main trouble at present isn't writing the code, but not writing code : meaning restricting my plans so that I will actually emit an executable/publishable product sometime! LOL. But with OOP, and C++ especially, one can 'stub' alot of constructs ( eg. create function calls or a parameterised interface, but have them 'do nothing' pro-tem ). So one can come back later on ...

[ In time I'll learn yet another API :-) BOINC this time to craft an EinsteinGammaAdapter class ..... but much later ]

Cheers, Mike.

I have made this letter longer than usual because I lack the time to make it shorter ...

... and my other CPU is a Ryzen 5950X :-) Blaise Pascal

Oliver Behnke
Oliver Behnke
Moderator
Administrator
Joined: 4 Sep 07
Posts: 987
Credit: 25171438
RAC: 2

RE: [ In time I'll learn

Message 78119 in response to message 78118

Quote:

[ In time I'll learn yet another API :-) BOINC this time to craft an EinsteinGammaAdapter class ..... but much later ]

Just include an instance of BOINCClientAdapter in your class and you're done...

Cheers,
Oliver

Einstein@Home Project

Mike Hewson
Mike Hewson
Moderator
Joined: 1 Dec 05
Posts: 6591
Credit: 324552139
RAC: 177192

Now doing a really boring (

Now doing a really boring ( but necessary ) bit of entering star coordinates, magnitudes etc of the 88 official constellations. Done about 75% of them, up to Orion ..... :-)

Cheers, Mike.

I have made this letter longer than usual because I lack the time to make it shorter ...

... and my other CPU is a Ryzen 5950X :-) Blaise Pascal

Mike Hewson
Mike Hewson
Moderator
Joined: 1 Dec 05
Posts: 6591
Credit: 324552139
RAC: 177192

A couple of mild gotcha's

A couple of mild gotcha's with the OGLFT::TranslucentTexture class and it's 'official' web based documents ( circa 2002 ).

- no mention is made of a four parameter constructor using a memory based font file image ( which is created in the screensaver code via ResourceFactory ). However the header file ( oglft.h ) produced during the OGLFT library construction does and is excellently commented so :
[pre]/*!
* \param data_base the memory location (base pointer) which contains the font face.
* \param data_size the size (in bytes) of the font data found at \ref data_base.
* \param point_size the initial point size of the font to generate. A point
* is essentially 1/72th of an inch. Defaults to 12.
* \param resolution the pixel density of the display in dots per inch (DPI).
* Defaults to 100 DPI.
*/
OGLFT_API TranslucentTexture(const FT_Byte* data_base, const FT_Long data_size,
float point_size = 12, FT_UInt resolution = 100);[/pre]
This is used thus eg. in Starsphere::initialize() :

[pre]// create medium font instances using font resource (base address + size)
m_FontHeader = new OGLFT::TranslucentTexture(&m_FontResource->data()->at(0),
m_FontResource->data()->size(),
13, 78 );[/pre]
- there is no explicit mention of the need to call glEnable(GL_TEXTURE_2D) prior to using the compile/draw/etc functions. The class pastes textures ( ie. bitmap images of the character glyphs derived from a given font/face ) onto OpenGL QUAD's and thus requires the 2D texturing facility of the OpenGL engine available. Of course, one later uses glDisable(GL_TEXTURE_2D) when you're done with this need. Inspection of oglft.cpp finds these lacking.

Neither of these are terrible problems - if you know about them - but required a detour for me to delimit during debugging. :-)

Cheers, Mike.

I have made this letter longer than usual because I lack the time to make it shorter ...

... and my other CPU is a Ryzen 5950X :-) Blaise Pascal

Mike Hewson
Mike Hewson
Moderator
Joined: 1 Dec 05
Posts: 6591
Credit: 324552139
RAC: 177192

Fonts again. I've discovered

Fonts again. I've discovered I'd really like the glyph that indicates 'degrees' ie. a little circle sitting high above the baseline. It's not in the 00h-7Fh range of the usual 7-bit ASCII standard.

Now the current LiberationSans-Regular TrueType font used in Starsphere doesn't have that. This is not a problem however as :

- I found a likely candidate font/face by the name of FreeMono ( as in beer and copyright ) from GNU.

- the byte code for my desired 'degrees' glyph is in the range 80h-FFh. Just note for later it's unsigned char ( ie. 8-bit unsigned byte ) value.

Hence I then .....

- edit the resources.orc file like so :

replacing ( or not as you please, since you can have as many distinctly named resources as you want/need compiled )
[pre]FontSansSerif|LiberationSans-Regular.ttf.res[/pre]
with

[pre]MyChosenFontIdentifier|FreeMono.ttf.res[/pre]
[ .... where the .res ending is simply that, no file format change involved, so if you rename without it then you have the original ttf ]

- change in main.cpp this line so :

replacing ( or not .... )

[pre]const Resource* fontResource = factory.createInstance("FontSansSerif");[/pre]
with

[pre]const Resource* fontResource = factory.createInstance("MyChosenFontIdentifier");[/pre]
- eg. in the AbstractGraphicsEngine object that has the OpenGL callback targets, say Starsphere, look in the initialize() function that is passed said const Resource* pointer in it's parameter list and do what you will with it. In my Solarsystem case I'll be passing that to a Simulation class ( that does all the rendering and view manipulation aka 'flying around and looking' ) which in turn will pass that pointer again to it's sub-components. Especially the GridGlobe class as that's where I want to use the 'degrees' glyph in marking the celestial sphere coordinate grid at the intersections of circles of constant right-ascension with those of constant declination.

- recompile the project etc .....

With much thanks to Oliver in particular for creating this brilliant aspect of the framework, of which I ( think I ) have eventually worked out a/the raison d'etre of !! :-) :0)

[ but also including any other desired 'resource' usage too ie. achieving at runtime an in-memory byte level mapping of any content what-so-ever, but distributed within the executable itself ]

Cheers, Mike.

( edit ) Currently AbstractGraphicsEngine::initialize() only takes one Resource pointer, for font management at present, but other designs might vary. For my Simulation class I allow multiple font/face registrations and use an internal std::map ( in an associative array role ) to cope with variants :

[pre]std::map fonts;[/pre]
accessed via a suitable member function like :

[pre]void setFont(content element, OGLFT::TranslucentTexture* font);[/pre]
where 'content' is an enumeration of sub-components :

[pre]/// Enumerants for the scene elements
enum content {AXES, CONSTELLATIONS, EARTH, GRID, PULSARS, SUPERNOVAE, HUDOVER};[/pre]
.... the idea being to assign, if I want, different variations to different scene elements. Note that in '3D space' font size ( meaning : as specified within the original font file ) per se is not of great importance as I can OpenGL transform ( scale, shear, mirror-image or ... ) the geometry to please. Which is potentially different from a rasterised HUD.

( edit ) "..... per se is not of great importance" : Well, within the limits of anti-aliasing behaviour. So, say, OGLFT::MonochromeTexture will look different close up compared to OGLFT::TranslucentTexture.

I have made this letter longer than usual because I lack the time to make it shorter ...

... and my other CPU is a Ryzen 5950X :-) Blaise Pascal

Mike Hewson
Mike Hewson
Moderator
Joined: 1 Dec 05
Posts: 6591
Credit: 324552139
RAC: 177192

I ought mention : - the

I ought mention :

- the word 'font' is a bit plural in meaning nowadays, and so depends upon who is talking. But I tend to think in terms of a 'font family of faces'. For instance bold & italic would distinguish two faces within a font family, whereas Helvetica and Courier are different font families.

- a given font file may have many faces within it ( but all from the one family ), and thus one can select between these if you know the internal offsets and sizes.

- for a given point size ( a 'point' is 1/72 th of an inch, a traditional measure ) then dots ( or pixels ) = resolution_in_dots_per_inch * ( point_size / 72 ). So for the Starsphere code the constructed font has 13 points at a resolution of 78 DPI which is ~ 14 pixels. This would be the size on the HUD - at the near frustum face - but in '3D space' evidently depends on the distance to it in the scene field.

Cheers, Mike.

I have made this letter longer than usual because I lack the time to make it shorter ...

... and my other CPU is a Ryzen 5950X :-) Blaise Pascal

Mike Hewson
Mike Hewson
Moderator
Joined: 1 Dec 05
Posts: 6591
Credit: 324552139
RAC: 177192

Have a good look and feel now

Have a good look and feel now on the simulation. Constellations are labelled, the celestial sphere grid looks nice with little markers indicating degrees of declination and hours of right ascension at the intersections. Have re-checked all constellation coordinates and seems fine, just finished Taurus and another 10 constellations to go.

BTW: it's way simpler to scale/shrink lowercase 'o' and adjust position - for the degree symbol - than worry about multiple font 'pages'!! Ditto for the little 'h' - for right ascension. :-)

One mild bit of bad news for OGLFT::TranslucentTexture font type rendering - changing the font's foreground or background color invalidates it's internal glyph cache. This is because the colors are 'pasted onto' OpenGL quads when a glyph is first formed, which is what is then placed server side. In practice this means you will lose the underlying server side representation ( ie. texture buffer handle and contents ) and thus your desired appearance. OGLFT manages all of that behind the API, so you can't change this behaviour. So .... this is managed at present by cloning the font to copies and then setting the ( different ) colors once for those copies.

In any case now that I know quite alot more about OGLFT than before, I will move on to the HUD. Once that's done I aim to release a minimalist version for comment/testing etc.

Cheers, Mike.

I have made this letter longer than usual because I lack the time to make it shorter ...

... and my other CPU is a Ryzen 5950X :-) Blaise Pascal

Oliver Behnke
Oliver Behnke
Moderator
Administrator
Joined: 4 Sep 07
Posts: 987
Credit: 25171438
RAC: 2

Sounds good! OGLFT is OSS, so

Message 78125 in response to message 78124

Sounds good! OGLFT is OSS, so you want to think about whether your changes might be worthwhile sending upstream - I did so myself, too ;-)

Oliver

Einstein@Home Project

Mike Hewson
Mike Hewson
Moderator
Joined: 1 Dec 05
Posts: 6591
Credit: 324552139
RAC: 177192

RE: Sounds good! OGLFT is

Message 78126 in response to message 78125

Quote:

Sounds good! OGLFT is OSS, so you want to think about whether your changes might be worthwhile sending upstream - I did so myself, too ;-)

Oliver


Well, I guess that's feasible. At a glance the simplest strategy, I reckon, would require a change in existing base class(es) of a function or five to virtual status ( specifically those that inspect or mutate foreground and background colors ), and then I substitute suitable code while subclassing. That leaves existing semantics untouched. But I think I'd be happier doing that if I analysed (a) more closely their memory management tactics ie. heap vs. texture memory, and (b) what the overall change in the memory footprint would be.

It's the video card RAM which is the precious commodity here, and I doubt if any one would go silly and instantiate a font variant for every possible RGB shade! But you could index a such a scheme along color criteria, maybe use an integral handle ( like OpenGL buffer object, display list identifiers et al ) to pass around. So you don't clone the font (ie. the bit pattern), you multiply the glyph caches instead. So that implies a (further) de-coupling of the "font idea" from the "colored glyph idea" ...... thus you would only lose a glyph cache (i) when you explicitly ask for that to happen, and (ii) when you destroy the entire font instance. Hmmmm, maybe a factory paradigm.

A backburner job :-)

Cheers, Mike.

( edit ) Briefly, for those not familiar with OOP : the virtual function concept allows ( decided generally at compile time, but sometimes at runtime ) substitution of code behaviour by identically signatured functions across a class inheritance hierarchy. Think of, say, three generations of your relatives at the Xmas banquet and asking any/all to 'please get yourself a drink from the refrigerator'. They will all do that task in their own unique ways without you needing to individualise instructions ( at the time of the invitation ).

I have made this letter longer than usual because I lack the time to make it shorter ...

... and my other CPU is a Ryzen 5950X :-) Blaise Pascal

Mike Hewson
Mike Hewson
Moderator
Joined: 1 Dec 05
Posts: 6591
Credit: 324552139
RAC: 177192

Another mild issue, arising

Another mild issue, arising as I approach public release : ( my reading of ) the copyright of some of the images I'm using specifically require or strongly prefer that the image files be embedded within the executable, and not distributed as separate files. Sooooo ....... for this reason ( and simplicity generally ) I'll do that via the framework's Resource/ResourceCompiler mechanism, for all images used.

In detailed coding terms that could also involve, say SDL_CreateRGBSurfaceFrom(), acting on a Resource object to shovel/process the data on the way through to the video memory. This has specific advantages :

- the pixel map isn't copied, only referenced. Efficient.
- thus is unaffected by SDL_FreeSurface ie. truly static.

On the other hand I could bypass SDL completely and just directly present to OpenGL ( eg. during texture object generation ) a pointer to the pixel map. The Resource class can publicly give a const vector* which would do nicely for that purpose ( it's just an address and OpenGL wouldn't care of any C++ class semantics etc ).

Either way, to get it in as a Resource object : I may not need to strip any image file internal header areas, just point to the pixel subset afterwards. But on the other hand I might just write a separate 'little utility' that pulls in an image file onto an SDL_Surface, letting the SDL_Surface cope with all that header rubbish, hence emitting a 'pure' RGBA pixel map as a file that ResourceCompiler will then take up.

Hey!!! Why don't I create a new subclass from ResourceCompiler to do that?? Now there's a thought ...... the worst I would need to do to that base class is to make some stuff protected that is currently private. If done right that won't break current semantics for existing use. As Arnie says, I'll be back!! :-0 :-)

Ultimately thus, data-wise, the distributed executable file will be fully self-contained with the possible exception of the planned update-able "Hall Of Fame" listing ( and any BOINC API derived dynamic information like current WU search details et al ).

Cheers, Mike.

( edit ) Yeah that'll work : if you want the original vanilla ResourceCompiler just use that. If you want, say, ImageResourceCompiler then call that instead .... it could inspect the filename extensions ( in resources.orc ) for SDL_Surface manage-able files and process those, and still have it call the superclass for the rest anyway.

( edit ) Naturally, I'd leave ResourceCompiler private data as such, it's the functions I'd be converting to protected !!!

I have made this letter longer than usual because I lack the time to make it shorter ...

... and my other CPU is a Ryzen 5950X :-) Blaise Pascal

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.