Write your own Einstein@home screensaver

Mike Hewson
Mike Hewson
Moderator
Joined: 1 Dec 05
Posts: 6588
Credit: 317507858
RAC: 374648

Here you go, a screenshot

Here you go, a screenshot :

... look familiar ? That thar would be the original Starsphere in the making, being reborn in the new paradigm ! Here's the invocation within the rendering loop of the pulsars, supernovae and the stars :

[pre] m_view = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -15.0f));

m_rotation = glm::rotate(m_rotation, 0.01f, m_axis);

m_camera = m_projection * m_view * m_rotation;

m_render_task_psr->utilise(GL_POINTS, Npulsars);
m_render_task_snr->utilise(GL_POINTS, NSNRs);
m_render_task_star->utilise(GL_POINTS, m_distinct_stars);[/pre]
Next up : the constellation line markings.

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: 984
Credit: 25171438
RAC: 34

Seems nice and simple!

Message 78353 in response to message 78352

Seems nice and simple!

Einstein@Home Project

Stranger7777
Stranger7777
Joined: 17 Mar 05
Posts: 436
Credit: 429850401
RAC: 77913

It is amazing how easy

It is amazing how easy nowadays computer grahics can be written.
Just one line of code
m_rotation = glm::rotate(m_rotation, 0.01f, m_axis);
and the whole array is rotated and even using a hardware acceleration when it is possible. No need to write own code for rotation matrix. Just one line...
I remember those days when I have to write the whole rotation and rendering proccess
by myself. And it works without any hardware acceleration at all. Though it was a one color transparent fading cube. But the aim was to understand and to make it all myself.
So I'm long for those times. May be I'm getting older... :)

Mike Hewson
Mike Hewson
Moderator
Joined: 1 Dec 05
Posts: 6588
Credit: 317507858
RAC: 374648

The glm library is brilliant.

The glm library is brilliant. You can use it for things other than OpenGL/GLSL. The main boon IMHO is that the syntax/semantics of the data types matches shader code. I was faced with writing my own matrix classes/methods ( groan ) before I found it. It is way better than anything I could have done. It is purely header and thus slips right in to any existing development setup, the only downside of which is possible massive C++ template unwrapping which could be quite a pain without a fast machine and/or a ton of RAM during compilation.

I would also re-iterate the importance of the GLEW and SDL (v2+) libraries, without which an effort of this type would be a hopeless task.

But there is still good old fashioned idiocy ! You may be amused by this commit, which I put in to remind myself* of the dangers of hubris [ "Look on my works, ye Mighty, and despair!" ] !! :-)

Cheers, Mike.

* I've been doing this for so long that I began talking to the repo ..... :-)

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

Stranger7777
Stranger7777
Joined: 17 Mar 05
Posts: 436
Credit: 429850401
RAC: 77913

Yeah, talking to repo is what

Yeah, talking to repo is what I do when I desperate of what I've done and why it is returning me this :)

Mike Hewson
Mike Hewson
Moderator
Joined: 1 Dec 05
Posts: 6588
Credit: 317507858
RAC: 374648

Ok, the constellations

Ok, the constellations :

.... where you may note that I have slightly offset the yellow constellation line markings from the stars.

Next up : coordinate grid ( right ascension and declination ) on the sphere + Cartesian axes through the centre.

{ ... ooh yeah, dum de dum, it's bangin' now ... }

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

Stranger7777
Stranger7777
Joined: 17 Mar 05
Posts: 436
Credit: 429850401
RAC: 77913

Ok. This is customer feedback

Ok. This is customer feedback :)

On this stage you have already to think about making all these things switchable, by hotkeys for example, have you? ;)

P.S. And please add constellation names with very small letters along longest line in each constellation (and also switchable).

Thank you in advance.

Mike Hewson
Mike Hewson
Moderator
Joined: 1 Dec 05
Posts: 6588
Credit: 317507858
RAC: 374648

RE: Ok. This is customer

Message 78359 in response to message 78358

Quote:
Ok. This is customer feedback :)


Cool ! At last I have made something to be feed-backable upon ... :-) :-)

[ I'm going to soon get the win32 build working ( as most don't own a Linux target ), this is a wee bit more problematic however. ]

Quote:
On this stage you have already to think about making all these things switchable, by hotkeys for example, have you? ;)


Yep, I'll be replicating the behaviour of the original Starsphere beast which has that. Hotkeys are sitting in the code as we speak, just REM-ed out at present. With all features active it does look quite visually dense.

Quote:
P.S. And please add constellation names with very small letters along longest line in each constellation (and also switchable).


Good one. To the whiteboard -> on the list ... :-)

Quote:
Thank you in advance.


Thank You ! :-)

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: 6588
Credit: 317507858
RAC: 374648

Heart Beat. Whack !

Heart Beat. Whack ! :-0

Well how non-trivial it is to get text on the HUD - nearly solved ( tracking down one errant pointer as we speak ) and is the only real remaining barrier of significance in this enterprise. Hope springs eternal. Rough heuristic as follows :

- SDL is the library to interface for acquiring a rendering context ( read : instance of an OpenGL conforming state machine ), plus input from devices/files etc.

- SDL_ttf is the library to gain pretty painless access to font representations and extract the crucial glyph patterns.

- obtain an SDL_Surface pointer/reference ( for some given text string ) via a call, say, to TTF_RenderText_Solid().

- using SDL_ConvertSurfaceFormat() get a different SDL_Surface with suitable pixel value representations : RGB @ 8 bits per color.

- load up one of my TextureBuffer objects with said SDL_Surface derived values. Now you have a ( wrapped ) object subject to OpenGL state.

- hence a texture shader may pick out values ( technically sample the pixel map ) to determine fragment color eg.

#version 150

// This is a fragment shader. It samples/interpolates the
// texture object currently bound to GL_TEXTURE0.

// With these texture coordinates ...
in vec2 pass_text_coords;

// ... lookup using this sampler device ...
uniform sampler2D color_map;

// ... to determine the fragment color.
out vec4 out_color;

void main()
{
out_color = texture(color_map, pass_text_coords.st);
}


- however that pixel map interpolation has to occur with respect to texturing coordinates for some geometric primitive.

- there aren't GL_QUAD objects available anymore. So one uses two triangles with a common edge to make up a quadrilateral shape. That common edge becomes a diagonal across that shape.

- but to keep that quadrilateral both planar and convex, I have selected a parallelogram model. You specify the bottom left corner's coordinates ( in world space ) and two vectors indicating displacement from that point.

#version 150

// This is a vertex shader. Creates a parallel sided quadrilateral
// area based at lower left corner, with offsets along the sides.
// Both dimensions of texture coordinates are bound/clamped to
// zero and one at extents.

uniform vec3 base_position;
uniform vec3 height_offset;
uniform vec3 width_offset;

out vec2 pass_text_coords;

uniform mat4 CameraMatrix;

void main()
{
// Start at lower left corner.
vec3 position = base_position;
// With texture coordinates of zero.
pass_text_coords.st = vec2(0.0, 0.0);

// For odd numbered vertices.
if((gl_VertexID % 2) == 1) {
// Add the width_offset.
position += width_offset;
// With the 's' texture coordinate is 1.0.
pass_text_coords.s = 1.0;
}

// For the vertex numbered two & three.
if(gl_VertexID > 1) {
// Add the height offset.
position += height_offset;
// With the 't' texture coordinate being 1.0.
pass_text_coords.t = 1.0;
}

// Emit final position of the vertex.
gl_Position = CameraMatrix * vec4(position, 1.0f);
}

- the interesting ( OpenGL Shading Language ) feature here is the gl_VertexID inbuilt variable. It counts from zero to however many vertices are invoked by a given call to glDrawArrays() ( either four or six times per triangle pair, depending upon another optimisation ).

- that parallelogram can be wherever you choose to put it in your modelling/world space, subject to transforms like any other OpenGL geometric primitive and subsequent projections ( perspective for a 3D look, orthographic for the HUD ).

- in summary the interior of the parallelogram is painted with the pixel map representing some chosen text in a certain font as selected. You get the full advantages of font processing prior to glyph construction, especially kerning and conjoined glyphs.

- my encapsulation is via C++ class interfaces of course, and I have chosen the following key constructor :

TextString::TextString(glm::vec3 position,
	  	       glm::vec3 height_offset,
		       glm::vec3 width_offset,
		       TTF_Font* font,
		       const char* text,
		       SDL_Color foreground)


... so you have to fully specify from the get-go. However once instantiated there are several methods available to change any of the above parameters individually, with invisible reconstruction of the back-end objects and devices using magic incantations. :-)

- AND all of that without going outside of the provided libraries ie. it remains a cross-platform solution. Phew ! :-)

Now if only I could track down that bloody pointer. Jeeves, pass me Brown Bessie ......

Cheers, Mike.

( edit ) Sharp punters will note that no color information needs to be provided on a per vertex basis. So those points are natively invisible or non-rendered, only serving to define the extents of the quadrilateral and texture coordinates to be later interpolated upon. Indeed vertex positions are deduced by access to uniform variables - implying direct load from client side code and not via any OpenGL array objects. So this is an example of when one only needs a Vertex Array Object to trigger pipeline activity for a certain number of instances, the rest is defined intra-shader. This is the most efficient choice for a small number of vertices.

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: 6588
Credit: 317507858
RAC: 374648

Also : #1. The reason you

Also :

#1. The reason you want a planar and convex shape is because of what happens if you don't. The basic/default interpolation method provided in the pipeline could yield fragments bridging across the exterior of the shape ie. interpolation becomes extrapolation.

{ FWIW : there are two interpolation methods available.

The default is perspective/affine which accounts for foreshortening with depth from the viewpoint. For texturing this is necessary to give the impression that a surface texture was applied as if it was part of the geometry before any other transform, when in fact we actually did it the other way around. Just think of how you should mark the positions of equally spaced railway ties as the rails appear to converge in the distance.

The other is simple linear/flat ie. not accounting for any 3D aspects. It will be equivalent to perspective if the geometric primitive is viewed en face. If you are doing mainly orthographic projections then it is a more efficient choice. }

#2. I will provide variants of TextString to give the shaded and blended versions in addition to solid fill.

#3. Pointer problem solved. The issue ?

SDL_Surface* SDL_ConvertSurfaceFormat(SDL_Surface* src,
                                      Uint32       pixel_format,
                                      Uint32       flags)


returns a NULL value on error. So it is right & proper to check that case, with a failure pathway to handle, before any subsequent dereferencing. ***Blush***. That was a Coding 101 Numpty Prize right there Mike ! :-)

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

Comment viewing options

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