More Raspberry Pi experiments…

My little c++ opengl tutorial project now has imgui support. I have created a github repository for it here if you’d like to try it:

https://github.com/blitz-research/opengldev

It still doesn’t do a whole lot, I just wrote a slightly more sophisticated shader and used imgui to let the user twiddle with the uniforms in real time.

There is also a fancy ‘demo’ widget that comes with ImGui shown in the screenshot above, on the right. ImGui has a huge variety of widgets available and the demo widget lets you have a play with them all. I was *almost* tempted to write a little compiler for its text editor, until I realized it would have to be an ‘immediate mode’ compiler (as it’s an immdiate mode GUI!), ie: you’d have to ‘feed’ the compiler a line at a time which probably involve some form of continuation mechanism inside the compiler, something c++ doesn’t support.

I also included my ‘_clang-format’ file in the repos. This provides a set of formatting rules that can be used to automatically format your c++ source code whenever you save it. For instance, it can change tabs to space, move braces around and limit line lengths etc, so that your source code can have a consistent style. This feature needs to be enabled in QtCreator via the Beautifier options in the tools-options menu. It’s a bit fiddly to get going sometimes but well worth it IMO.

Next up, I think I might try coming up with a more interesting shader, maybe attempt a starfield or blackhole or something? I think I’ve been watching too many SEA videos!

Bye,
Mark

Let the Raspberry Pi experiments begin!

Yay, my Raspberry Pi 400 finally arrived last week! It didn’t arrive until the last day of my christmas break, so I haven’t had much of a chance to play with it so far.

But I did have a decent hack at it today and I am super impressed so far. The keyboard is surprisingly cool – I was a little worried I’d have to plug in a ‘real’ keyboard to be able to use it seriously, which would have been pretty weird because it really only is a keyboard – but that’s definitely not the case, you just need to learn a few keyboard combos for home/end/up/down etc and you’re off.

The hardware seems to be OK, although it was definitely starting to get a bit laggy when I was using Qt Creator, to the point where you could ‘see’ the text scrolling happening in chunks. But it was still entirely usable and load/compile times were fine so I suspect this may be down to a still slightly underpowered GPU – well, compared to my desktop setup anyway!

It may also be something to do with the fact I’m using 64-bit Manjaro, as opposed to ‘stock’ 32-bit Raspbian which apparently has the most optimally tweaked drivers. I’ll probably explore that later as it’s still sitting there on an SD card waiting to be booted up again, but so far performance is definitely good enough for me to stick with the current setup.

Anyway, I had a blast writing a little GLES3 demo which I hope to expand on in future. It’s basically just a simple ‘hello triangle(s)’ demo, but I got to use a few GLES3-only tricks I learned while exploring webgpu recently. The coolest of these is being able to draw stuff without vertex/index buffers thanks to the ‘gl_VertexID’ built-in variable. This is just an int that contains the index of the vertex currently being processed by the vertex shader, but it’s great for drawing simple things like triangles/cubes etc as you can just stick vertex coordinates in the vertex shader via ‘const vec2[] vertices=…’ etc, which you can then index using gl_VertexID. Much nicer than having to create a vertex buffer, fill it with data, bind to attributes indices etc. Compiling shaders still sucks though…

There is also gl_InstanceID for instanced rendering, but in a way this is sort of redundant if you know how many vertices are in the model, as you can just draw vertices * instances vertices and use mod/div on gl_VertexId to simulate instancing. Much to play with!

I think I’ll try and turn this into a semi-regular ‘tutorial’ sort of thing. I was thinking of starting a git repos for it but it’s really only one file right now so that seems a bit overkilly! The plan for the next ‘episode’ is to add ImGui support and at that point a repos is probably worth it, so it can wait until then.

Until then, here’s the source code for hello triangles and a simple ‘CMakeLists.txt’ file for building it with. If you’re using Qt Creator, which should be available on all distros via the package manager, you can just open ‘CMakeLists.txt’ as a project, hit build/run and that should be it. If you’re not using Qt Creator, you should just be able to use ‘cmake’ directly to build it but I haven’t tried that yet. You’ll also need to install the binary tools Qt Creator does for you, so even if you don’t want to use it, install Qt Creator is probably a good way to get setup.

The only other thing you should need to install is the ‘glfw’ library, which again should available for all distros via the package manager. This package contains the headers and libraries for glfw, a simple, lightweight windowing library for creating windows you can use opengl to render to.

// File: main.cpp

#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#define GLFW_INCLUDE_ES31
#include <GLFW/glfw3.h>

const char* vshaderSource = R"(

#version 300 es

precision highp float;

const vec2[3] vertices=vec2[](
vec2(-1.0,-1.0),
vec2(0.0,1.0),
vec2(1.0,-1.0));

const float pi2=6.28319;

out float color;

void main() {

    vec2 v = vertices[gl_VertexID] * 0.025;
    float an = float(gl_InstanceID) * pi2 / 100.0;
    v += vec2(cos(an),sin(an)) * 0.9;

    gl_Position = vec4(v.x,v.y,0.0,1.0);

    color = float(gl_InstanceID) / 100.0;
}

)";

const char* fshaderSource = R"(

#version 300 es

precision highp float;

in float color;

out vec4 fragColor;

void main() {

    fragColor=vec4(1.0, color, 0.0,1.0);
}

)";

GLuint compileShader(GLenum type, const char* source) {

    GLuint shader = glCreateShader(type);
    glShaderSource(shader, 1, &source, nullptr);
    glCompileShader(shader);

    GLint status = 0;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
    if (status != GL_TRUE) {
        GLint length;
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
        char* log = new char[length];
        glGetShaderInfoLog(shader, length, nullptr, log);
        log[length - 1] = 0;
        printf("Compile shader failed:%s\n", log);
        delete[] log;
        exit(1);
    }
    return shader;
}

int main() {

    assert(glfwInit());

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
    glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
    GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL);
    assert(window);

    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);

    GLuint vshader = compileShader(GL_VERTEX_SHADER, vshaderSource);
    GLuint fshader = compileShader(GL_FRAGMENT_SHADER, fshaderSource);
    GLuint program = glCreateProgram();
    glAttachShader(program, vshader);
    glAttachShader(program, fshader);
    glLinkProgram(program);
    glUseProgram(program);

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

    while (!glfwWindowShouldClose(window)) {

        glClear(GL_COLOR_BUFFER_BIT);

        glDrawArraysInstanced(GL_TRIANGLES, 0, 3, 100);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }
}
# File: CMakeLists.txt

cmake_minimum_required(VERSION 3.5)

project(opengltest LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(opengltest main.cpp)

target_link_libraries(opengltest glfw GLESv2)

Confessions of a Linux geek

Ok, looks like it’s time to come clean, it appears I have somehow turned into a massive Linux geek.

It took long enough I guess, but as much as I’ve always liked the idea of Linux it’s always had a ton of rough edges I just found too annoying to be inspired to learn how to fix. I just don’t get into the ‘OS maintenance’ side of computers.

But we use Linux a lot at work and I was getting a bit more comfortable with it so I decided to give it a month on my home machine to see if I could hack it ‘full time’. And probably just a week later I was fully converted. Linux seems to have matured incredibly over the last few years to the point where there it is far less creaky than it used to be. And presentation wise, it’s just so much more pleasant to use than the terminally dull Windows.

Linux has always been very powerful ‘if you know what your doing’, but if not it can be kind of overwhelming. The ‘control freak’ in me has always hated having to paste ‘magic words’ posted on stack overflow into /etc config files etc, I like to know how everything works all the time. There is of course still the occasional need to go googling for the various spells and incantations required to make things work, but there seems to be much less of it than there used to be. And it usually involves solving ‘good’ problems you created yourself, eg: by adding some cool new piece of software, and not because the OS just crapped itself for no good reason.

I was worried about not being able to play games very well on Linux, but I knew there were at least a few games available on Linux and I still had the PS4 to play on so bit the bullet. But even that fear turned out to be a big bogey-man. With Steam being super Linux friendly, and with the Wine/Proton Windows emulation layers, I haven’t yet found that a game in my Steam library that WONT run flawlessly on Linux. In fact, there are 2 games that used to crash consistently on Windows that I can ONLY run reliably on Linux. The one gaming exception here has been ‘Star Citizen’ which I haven’t been able to get going yet. But it’s apparently possible so I’m gonna give it another shot soon.

My distro of choice for now is ‘Manjaro’. I like its look and feel a lot (I use the XFCE desktop version but there are many others), it comes with a useful default setup so you’re not constantly having to install things to do basic stuff, and best of all it has a ton of software packages available for it. In particular it supports AUR, the ‘Arch User Repository’, a massive repository of packages in source code (only?) form that build themselves when you install them. This works 97% of the time but when it doesn’t you can view the ‘build script’ it uses so can generally just paste everything into a tmp directory and start hacking yourself. This is also a great way to learn how to build stuff from source in general. Usually there will just be some dependencies the package has forgotten to list.

But Manjaro is just one of a ton of very polished distros around these days. The first thing I did when I decided to try Linux was to setup live installers for a bunch of distros on a bunch of USB sticks and give them all a whirl. In fact, for my ‘month of Linux’ on my home machine I was running Manjaro entirely from a 128G USB stick the whole time!

Anyway, that’s it for now. IMO, If you’re getting a bit bored of computers and haven’t tried Linux for a while, I suggest giving it a go again. It has certainly been something of a revelation for me and I think it has ‘fired me up’ a bit again!

Bye,
Mark

Escape from lockdown!

Well, for some weird reason this morning I got the itch to do some web tinkering and blogging so I’m back baby! Amazingly, the domain marksibly.com was also up for grabs so grab it I did.

As I write this, New Zealand is coming out of a 3 month corona virus lockdown, which seems to have been very effective (so far). We have had ‘only’ 22 deaths out of 1100+ cases, although there have recently been a few newly imported cases and I guess there will be for quite a while yet.

The lockdown experience was pretty surreal. Going to the supermarket involved queing for a while (not for very long where I live but there were reports of huge queues in other areas) and going to the dairy meant following a one-in, one-out protocol. Going to buy booze did, however, involve some serious queuing, especially in my part of town where you can’t buy booze in supermarkets. Plus, since buying was a hassle, you tended to buy more than you normally would…

But everyone I encountered navigating this strange new world dealt with it all in a super relaxed way. No one threw a wobbly or muttered ‘hurry up’ to themselves or anything potentially aggravating like that. The were a few super-kitted-out survivalist types around, which looked super surreal. Especially when they were checking out half the freakin’ supermarket’s stock of baked beans through a checkout aisle staffed by a teenage checkout girl with virtually no protective clothing at all.

At worse it was all a minor inconvenience, and well worth how many ever lives were saved. And we’ll never know how many that is whether it was 10 or 10000. Of course, there was a certain contigent of people freaking out about The Economy the whole time, but we were lucky enough to have a ‘slightly left-of-center’ govt in at the time vs the ‘slightly right-of-center’ version we have the rest of the time.

But despite these minor inconveniences, I think I mostly enjoyed lockdown TBH. The streets were incredibly quiet which was a little spooky but also very peaceful and even weirdly beautiful. In a way, it felt like a brief glimpse into a much quieter alternate reality that could be happening on a far more chilled out earth, far far away.

Anyway, that’s enough to get me started.

Bye!
Mark