Raspberrypi 4でOpenGLES(ウィンドウの表示)

開発環境

環境構築

ライブラリのインストール

sudo apt install libgles2-mesa-dev libegl1-mesa-dev xorg-dev

ソースコード

main.cpp

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <GLES2/gl2.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <iostream>
#include <unistd.h>

bool InitEGL(Display* xDisplay, Window& xWin, EGLDisplay& display, EGLContext &context, EGLSurface& surface) {
    display = eglGetDisplay(static_cast<EGLNativeDisplayType>(xDisplay));
    if (display == EGL_NO_DISPLAY) {
        std::cout << "Failed to get Display" << std::endl;
        return false;
    }

    if (!eglInitialize(display, nullptr, nullptr)) {
        std::cout << "Failed to init EGL" << std::endl;
        return false;
    }

    EGLint attr[] = {EGL_BUFFER_SIZE, 16, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE};
    EGLConfig config = nullptr;
    EGLint numConfigs = 0;
    if (!eglChooseConfig(display, attr, &config, 1, &numConfigs)) {
        std::cout << "Failed to choose Config" << std::endl;
        return false;
    }

    if (numConfigs != 1) {
        std::cout << "Error numConfigs" << std::endl;
        return false;
    }

    surface = eglCreateWindowSurface(display, config, xWin, nullptr);
    if (surface == EGL_NO_SURFACE) {
        std::cout << "Failed to create WindowSurface" << std::endl;
        return false;
    }

    EGLint ctxattr[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
    context = eglCreateContext(display, config, EGL_NO_CONTEXT, ctxattr);
    if (context == EGL_NO_CONTEXT) {
        std::cout << "Failed to create context" << std::endl;
        return false;
    }

    eglMakeCurrent(display, surface, surface, context);

    return true;
}

void MainLoop(Display* xDisplay, EGLDisplay display, EGLSurface surface) {
    while (true) {
        XPending(xDisplay);
        glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        eglSwapBuffers(display, surface);

    }
}

int main(int argc, char*argv[]) {
    Display* xDisplay = XOpenDisplay(nullptr);
    if (xDisplay == nullptr) {
        std::cout << "Failed to open display" << std::endl;
        return -1;
    }

    Window xWindow = XCreateSimpleWindow(xDisplay, DefaultRootWindow(xDisplay), 100, 100, 640, 480, 1, BlackPixel(xDisplay, 0), WhitePixel(xDisplay, 0));

    XMapWindow(xDisplay, xWindow);

    EGLDisplay display = nullptr;
    EGLContext context = nullptr;
    EGLSurface surface = nullptr;

    if (!InitEGL(xDisplay, xWindow, display, context, surface)) {
        return -1;
    }

    MainLoop(xDisplay, display, surface);


    eglDestroyContext(display, context);
    eglDestroySurface(display, surface);
    eglTerminate(display);

    XDestroyWindow(xDisplay, xWindow);
    XCloseDisplay(xDisplay);
    
    return 0;
}

Makefile

CC      = g++
CFLAGS  = -Wall -Weffc++
TARGET = program

OBJS    = $(SRCS:.cpp=.o)

INCDIR =
LIBS =  -L/usr/lib -lX11 -lEGL -lGL

SRCS = main.cpp

$(TARGET): $(OBJS)
    $(CC) -o $(TARGET) $(OBJS) $(LIBS)

$(OBJS): $(SRCS)
    $(CC) $(CFLAGS) $(INCDIR) -c $(SRCS)

all:
    clean $(OBJS) $(TARGET)

clean: $(TARGET)
    rm $(OBJS)

参考資料

www.mztn.org

qiita.com