SDL and OpenGL error in Terminal (Unlocking Blocker)

I Run a SDL2 App with the SDL_WINDOW_OPENGL in option in his source-code and I got this error in Terminal but the App run.

Unlocking BLocker with sem 2836083 from wrong thread 152273, current holder 152275 (see issue #6400).

I have changing the code for SDL_WINDOW_SHOWN and this error disappear.

This is problably about OpenGL/Software. but when I use the function SDL_GetRenderDriverInfo that display -software and -opengl in terminal. (it’s a sort of compatibility check)
What SDL doing on Haiku with the Opengl mode actually? And what is this error report?

Wich is the best way for OpenGL software in haiku? I have see subject about Mesa.

Probably you can find some extra info here:
https://dev.haiku-os.org/ticket/6400

1 Like

If you want to do plain OpenGL programming, you can skip SDL and use BGlView directly. We also provide an EGL implementation for more portability, but I don’t know how stable it is.

1 Like

Thank for reply extrowerk, that answer the troublle well.
It’s seem to be effectively associate about OpenGL use and of a function called LockGL() / UnlockGL() on her haiku port. SDL App with OpenGL context seem to be affected with it.

Thank PulkoMandy I will checking it for tutorials about it.

Ok, I just post what I find about BGIView because I don’t find any tutorial with source for use it on Haiku exept theory on the Be book website.

Here is an example code to put in cpp file:
// sample BGLView app from the Be Book, modified to stress direct mode support.

#include <stdio.h>

#include <Application.h>
#include <DirectWindow.h>
#include <CheckBox.h>
#include <GLView.h>
#include <GL/glu.h>

#define REDRAW_MSG	'rdrw'

class SampleGLView : public BGLView
{
public:
    SampleGLView(BRect frame, uint32 type);
    virtual void   AttachedToWindow(void);
    virtual void   FrameResized(float newWidth, float newHeight);
    virtual void   MessageReceived(BMessage * msg);
    virtual void   KeyDown(const char* bytes, int32 numBytes);

    void         Render(void);

private:
    void         gInit(void);
    void         gDraw(float rotation = 0);
    void         gReshape(int width, int height);

    float        width;
    float        height;
    float		rotate;
};



class SampleGLWindow : public BDirectWindow
{
public:
    SampleGLWindow(BRect frame, uint32 type);
    ~SampleGLWindow();

    virtual bool QuitRequested();
    virtual void DirectConnected( direct_buffer_info *info );

private:
    SampleGLView   *theView;
    BMessageRunner *updateRunner;
};


class SampleGLApp : public BApplication
{
public:
    SampleGLApp();
private:
    SampleGLWindow      *theWindow;
};


SampleGLApp::SampleGLApp()
    : BApplication("application/x-vnd.Haiku-GLDirectMode")
{
    BRect windowRect;
    uint32 type = BGL_RGB|BGL_DOUBLE|BGL_DEPTH;

    windowRect.Set(50, 50, 350, 350);

    theWindow = new SampleGLWindow(windowRect, type);
}



SampleGLWindow::SampleGLWindow(BRect frame, uint32 type)
    : BDirectWindow(frame, "GLDirectMode", B_TITLED_WINDOW, 0)
{
    float minWidth = 0.0f;
    float maxWidth = 0.0f;
    float minHeight = 0.0f;
    float maxHeight = 0.0f;

    GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight);
    SetSizeLimits(50.0f, maxWidth, 50.0f, maxHeight);

    BRect r = Bounds();

    r.InsetBy(10, 10);
    theView = new SampleGLView(r, type);
    AddChild(theView);
    Show();

    updateRunner = new BMessageRunner(BMessenger(theView),
                                      new BMessage(REDRAW_MSG), 1000000/60 /* 60 fps */);

    theView->Render();
}


SampleGLWindow::~SampleGLWindow()
{
    delete updateRunner;
}


bool SampleGLWindow::QuitRequested()
{
    theView->EnableDirectMode(false);
    be_app->PostMessage(B_QUIT_REQUESTED);
    return true;
}


void SampleGLWindow::DirectConnected(direct_buffer_info *info)
{
    theView->DirectConnected(info);
    theView->EnableDirectMode(true);
}

// ----

SampleGLView::SampleGLView(BRect frame, uint32 type)
    : BGLView(frame, "SampleGLView", B_FOLLOW_ALL_SIDES, 0, type), rotate(0)
{
    width = frame.right-frame.left;
    height = frame.bottom-frame.top;
}


void SampleGLView::AttachedToWindow(void)
{
    BGLView::AttachedToWindow();
    LockGL();
    gInit();
    gReshape(width, height);
    UnlockGL();
    MakeFocus();
}


void SampleGLView::FrameResized(float newWidth, float newHeight)
{
    BGLView::FrameResized(newWidth, newHeight);

    LockGL();

    width = newWidth;
    height = newHeight;

    gReshape(width,height);

    UnlockGL();
    Render();
}


void SampleGLView::gInit(void)
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
}



void SampleGLView::gDraw(float rotation)
{
    /* Clear the buffer, clear the matrix */
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    /* A step backward, then spin the cube */
    glTranslatef(0, 0, -5);
    glRotatef(rotation, 0, 0, 1);
    glRotatef(rotation, 1, 0.6, 0);

    /* We tell we want to draw quads */
    glBegin (GL_QUADS);

    /* Every four calls to glVertex, a quad is drawn */
    glColor3f (0, 0, 0);
    glVertex3f (-1, -1, -1);
    glColor3f (0, 0, 1);
    glVertex3f (-1, -1,  1);
    glColor3f (0, 1, 1);
    glVertex3f (-1,  1,  1);
    glColor3f (0, 1, 0);
    glVertex3f (-1,  1, -1);

    glColor3f (1, 0, 0);
    glVertex3f ( 1, -1, -1);
    glColor3f (1, 0, 1);
    glVertex3f ( 1, -1,  1);
    glColor3f (1, 1, 1);
    glVertex3f ( 1,  1,  1);
    glColor3f (1, 1, 0);
    glVertex3f ( 1,  1, -1);

    glColor3f (0, 0, 0);
    glVertex3f (-1, -1, -1);
    glColor3f (0, 0, 1);
    glVertex3f (-1, -1,  1);
    glColor3f (1, 0, 1);
    glVertex3f ( 1, -1,  1);
    glColor3f (1, 0, 0);
    glVertex3f ( 1, -1, -1);

    glColor3f (0, 1, 0);
    glVertex3f (-1,  1, -1);
    glColor3f (0, 1, 1);
    glVertex3f (-1,  1,  1);
    glColor3f (1, 1, 1);
    glVertex3f ( 1,  1,  1);
    glColor3f (1, 1, 0);
    glVertex3f ( 1,  1, -1);

    glColor3f (0, 0, 0);
    glVertex3f (-1, -1, -1);
    glColor3f (0, 1, 0);
    glVertex3f (-1,  1, -1);
    glColor3f (1, 1, 0);
    glVertex3f ( 1,  1, -1);
    glColor3f (1, 0, 0);
    glVertex3f ( 1, -1, -1);

    glColor3f (0, 0, 1);
    glVertex3f (-1, -1,  1);
    glColor3f (0, 1, 1);
    glVertex3f (-1,  1,  1);
    glColor3f (1, 1, 1);
    glVertex3f ( 1,  1,  1);
    glColor3f (1, 0, 1);
    glVertex3f ( 1, -1,  1);

    /* No more quads */
    glEnd ();

    /* End */
    glFlush ();
}


void SampleGLView::gReshape(int width, int height)
{
    glViewport(0, 0, width, height);
    if (height) {  // Avoid Divide By Zero error...
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(45, width / (float) height, 1, 500);
        glMatrixMode(GL_MODELVIEW);
    }
}




void SampleGLView::MessageReceived(BMessage * msg)
{
    switch (msg->what) {
    case REDRAW_MSG:
        Render();
        /* Rotate a bit more */
        rotate++;
        break;

    default:
        BGLView::MessageReceived(msg);
    }
}

void SampleGLView::KeyDown(const char *bytes, int32 numBytes)
{
    static bool moved = false;
    switch (bytes[0]) {
    case B_SPACE:
        if (moved) {
            MoveBy(-30, -30);
            moved = false;
        } else {
            MoveBy(30, 30);
            moved = true;
        }
        break;
    default:
        BView::KeyDown(bytes, numBytes);
        break;
    }
}

int main(int argc, char *argv[])
{
    SampleGLApp *app = new SampleGLApp;
    app->Run();
    delete app;
    return 0;
}
void SampleGLView::Render(void) {
   LockGL();
   gDraw(rotate);
   SwapBuffers();
   UnlockGL();
}

And the command line i use to compile it is:
g++ -o GLView exampleGLView.cpp -lbe -lgame -lGL -lGLU

That make an OpenGL Cube rotating in Window.

An other way is possible by using GLUT.h

just need to solve the mouse cursor trouble (black square around it)

1 Like

That bug is on our side, unfortunately there seem to be no good way to fix it unless we implement hardware cursors (I may look into that for the Intel driver someday)

I try to find a function in Haiku API that can get the mouse cursor position (x and y). And a function that hide the API cursor and after create one in the OpenGL window.

Is there a way to do it?

The mouse position is sent to views in their MouseMoved hook. So you subclass BView (or BGlView) and implement that function to get the coordinates.

You can set the cursor using BView::SetCursor (there are a few default ones or you can create a custom BCursor with an all-transparent sprite).

1 Like

It cased by using BDirectWindow. It use direct access to front buffer and erase cursor. Replace it with BWindow and delete DirectConnected.

See https://github.com/X547/HaikuUtils/tree/master/OpenGLTest.

1 Like

Thank for your Help your tricks work fine.

Watch:
screenshot3

I’m a beginner in C++ and OpenGL.
I have done one think I don’t really understand in the code.

it this line…
virtual void MouseMoved(BPoint Coord,uint32 intoView,const BMessage * msg2);

That seem to be un function declaration but the preset is “virtual” and after void…I don’t really understand what is doing this virtual.
I put this line in the code under a Class with public functions.(I guess very not sure)…I have copied the prototype of the line above it to do it.

class SampleGLView : public BGLView
{
public:
    SampleGLView(BRect frame, uint32 type);
    virtual void   AttachedToWindow(void);
    virtual void   FrameResized(float newWidth, float newHeight);
    virtual void   MessageReceived(BMessage * msg);
    virtual void   KeyDown(const char* bytes, int32 numBytes);
    virtual void MouseMoved(BPoint Coord,uint32 intoView,const BMessage * msg2);

    void         Render(void);

after the core of the function…
void SampleGLView::MouseMoved(BPoint Coord,uint32 intoView,const BMessage * msg2)
{

	//Teste si la souris bouge dans la fenêtre ou pas.
	if(intoView==1)
	{
		cout<<"Vous etes dans la fenetre\n";
		cout<<"X:"<<Coord.x<<"| Y:"<<Coord.y<<"\n";
	}
	else
		cout<<"Vous etes hors de la fenetre\n";
}

And that work perfectly. (Display the Coordinate of the mouse when we are inside the Window). I have just erase too the lines about DirectConnected and the cursor is Ok now. (–>the transparancy work well).

But I don’t understand why I don’t must to push the include file “View.h” in the code for it work. MouseMoved and KeyDown seem to be function from that include. But the app work nice now so.

Full code:

// sample BGLView app from the Be Book, modified to stress direct mode support.
#include <stdio.h>
#include <Application.h>
#include <DirectWindow.h>
#include <CheckBox.h>
#include <GLView.h>
#include <GL/glu.h>
#include <iostream>
using namespace std;
#define REDRAW_MSG	'rdrw'



class SampleGLView : public BGLView
{
public:
    SampleGLView(BRect frame, uint32 type);
    virtual void   AttachedToWindow(void);
    virtual void   FrameResized(float newWidth, float newHeight);
    virtual void   MessageReceived(BMessage * msg);
    virtual void   KeyDown(const char* bytes, int32 numBytes);
    virtual void MouseMoved(BPoint Coord,uint32 intoView,const BMessage * msg2);

    void         Render(void);

private:
    void         gInit(void);
    void         gDraw(float rotation = 0);
    void         gReshape(int width, int height);

    float        width;
    float        height;
    float		rotate;
};



class SampleGLWindow : public BDirectWindow
{
public:
    SampleGLWindow(BRect frame, uint32 type);
    ~SampleGLWindow();

    virtual bool QuitRequested();
 //   virtual void DirectConnected( direct_buffer_info *info );

private:
    SampleGLView   *theView;
    BMessageRunner *updateRunner;
};


class SampleGLApp : public BApplication
{
public:
    SampleGLApp();
private:
    SampleGLWindow      *theWindow;
};


SampleGLApp::SampleGLApp()
    : BApplication("application/x-vnd.Haiku-GLDirectMode")
{
    BRect windowRect;
    uint32 type = BGL_RGB|BGL_DOUBLE|BGL_DEPTH;

    windowRect.Set(50, 50, 350, 350);

    theWindow = new SampleGLWindow(windowRect, type);
}



SampleGLWindow::SampleGLWindow(BRect frame, uint32 type)
    : BDirectWindow(frame, "GLDirectMode", B_TITLED_WINDOW, 0)
{
    float minWidth = 0.0f;
    float maxWidth = 0.0f;
    float minHeight = 0.0f;
    float maxHeight = 0.0f;

    GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight);
    SetSizeLimits(50.0f, maxWidth, 50.0f, maxHeight);

    BRect r = Bounds();

    r.InsetBy(10, 10);
    theView = new SampleGLView(r, type);
    AddChild(theView);
    Show();

    updateRunner = new BMessageRunner(BMessenger(theView),
                                      new BMessage(REDRAW_MSG), 1000000/60 /* 60 fps */);

    theView->Render();
}


SampleGLWindow::~SampleGLWindow()
{
    delete updateRunner;
}


bool SampleGLWindow::QuitRequested()
{
    theView->EnableDirectMode(false);
    be_app->PostMessage(B_QUIT_REQUESTED);
    return true;
}


/*void SampleGLWindow::DirectConnected(direct_buffer_info *info)
{
    theView->DirectConnected(info);
    theView->EnableDirectMode(true);
}*/

// ----

SampleGLView::SampleGLView(BRect frame, uint32 type)
    : BGLView(frame, "SampleGLView", B_FOLLOW_ALL_SIDES, 0, type), rotate(0)
{
    width = frame.right-frame.left;
    height = frame.bottom-frame.top;
}


void SampleGLView::AttachedToWindow(void)
{
    BGLView::AttachedToWindow();
    LockGL();
    gInit();
    gReshape(width, height);
    UnlockGL();
    MakeFocus();
}


void SampleGLView::FrameResized(float newWidth, float newHeight)
{
    BGLView::FrameResized(newWidth, newHeight);

    LockGL();

    width = newWidth;
    height = newHeight;

    gReshape(width,height);

    UnlockGL();
    Render();
}


void SampleGLView::gInit(void)
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
}



void SampleGLView::gDraw(float rotation)
{
    /* Clear the buffer, clear the matrix */
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    /* A step backward, then spin the cube */
    glTranslatef(0, 0, -5);
    glRotatef(rotation, 0, 0, 1);
    glRotatef(rotation, 1, 0.6, 0);

    /* We tell we want to draw quads */
    glBegin (GL_QUADS);

    /* Every four calls to glVertex, a quad is drawn */
    glColor3f (0, 0, 0);
    glVertex3f (-1, -1, -1);
    glColor3f (0, 0, 1);
    glVertex3f (-1, -1,  1);
    glColor3f (0, 1, 1);
    glVertex3f (-1,  1,  1);
    glColor3f (0, 1, 0);
    glVertex3f (-1,  1, -1);

    glColor3f (1, 0, 0);
    glVertex3f ( 1, -1, -1);
    glColor3f (1, 0, 1);
    glVertex3f ( 1, -1,  1);
    glColor3f (1, 1, 1);
    glVertex3f ( 1,  1,  1);
    glColor3f (1, 1, 0);
    glVertex3f ( 1,  1, -1);

    glColor3f (0, 0, 0);
    glVertex3f (-1, -1, -1);
    glColor3f (0, 0, 1);
    glVertex3f (-1, -1,  1);
    glColor3f (1, 0, 1);
    glVertex3f ( 1, -1,  1);
    glColor3f (1, 0, 0);
    glVertex3f ( 1, -1, -1);

    glColor3f (0, 1, 0);
    glVertex3f (-1,  1, -1);
    glColor3f (0, 1, 1);
    glVertex3f (-1,  1,  1);
    glColor3f (1, 1, 1);
    glVertex3f ( 1,  1,  1);
    glColor3f (1, 1, 0);
    glVertex3f ( 1,  1, -1);

    glColor3f (0, 0, 0);
    glVertex3f (-1, -1, -1);
    glColor3f (0, 1, 0);
    glVertex3f (-1,  1, -1);
    glColor3f (1, 1, 0);
    glVertex3f ( 1,  1, -1);
    glColor3f (1, 0, 0);
    glVertex3f ( 1, -1, -1);

    glColor3f (0, 0, 1);
    glVertex3f (-1, -1,  1);
    glColor3f (0, 1, 1);
    glVertex3f (-1,  1,  1);
    glColor3f (1, 1, 1);
    glVertex3f ( 1,  1,  1);
    glColor3f (1, 0, 1);
    glVertex3f ( 1, -1,  1);

    /* No more quads */
    glEnd ();

    /* End */
    glFlush ();
}


void SampleGLView::gReshape(int width, int height)
{
    glViewport(0, 0, width, height);
    if (height) {  // Avoid Divide By Zero error...
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(45, width / (float) height, 1, 500);
        glMatrixMode(GL_MODELVIEW);
    }
}




void SampleGLView::MessageReceived(BMessage * msg)
{
    switch (msg->what) {
    case REDRAW_MSG:
        Render();
        /* Rotate a bit more */
        rotate++;
        break;

    default:
        BGLView::MessageReceived(msg);
    }
}

void SampleGLView::KeyDown(const char *bytes, int32 numBytes)
{
    static bool moved = false;
    
    switch (bytes[0]) {
    //Si on appuye sur Espace on sswitch et on déplace le champ d'OpenGL
    case B_SPACE:
        if (moved) {
            MoveBy(-30, -30);
            moved = false;
        } else {
            MoveBy(30, 30);
            moved = true;
        }
        break;
    default:
        BView::KeyDown(bytes, numBytes);
        break;
    }
}

void SampleGLView::MouseMoved(BPoint Coord,uint32 intoView,const BMessage * msg2)
{
	//Teste si la souris bouge dans la fenêtre ou pas.
	if(intoView==1)
	{
		cout<<"Vous etes dans la fenetre\n";
		cout<<"X:"<<Coord.x<<"| Y:"<<Coord.y<<"\n";
	}
	else
		cout<<"Vous etes hors de la fenetre\n";
}


int main(int argc, char *argv[])
{
	int y=0,x=0;
    SampleGLApp *app = new SampleGLApp;
    app->Run();
    
    delete app;
    return 0;
}
void SampleGLView::Render(void) {
   LockGL();
   gDraw(rotate);
   SwapBuffers();
   UnlockGL();
}

For view the Coordinate you must run the app from a terminal.
Thank :slightly_smiling_face:

Ok, so a short “crash course” about C++, virtual methods, and inheritance.

“virtual” means a method can be implemented/replaced in subclasses.

So, for example, BView has a MouseMoved method which is virtual. It has an implementation that does nothing. It calls it whenever the mouse moves.

Your SampleGLView inherits BGLView, which inherits BView. This means you can declare a new MouseMoved implementation for that class. Now, when the mouse moves, BView code will call MouseMoved, but because the method is “virtual”, and you provided a different implementation for it, your code is called instead.

2 Likes

I have try to use MouseMoved function with no the virtual before and it work too.

Yes, because it is already declared virtual in BView. As long as your method has the same name and parameters, it will be seen by the compiler.

C++ virtual keyword only plays the role when you instantiate a pointer of some class by constructor of its subclass, in this case, BGLView *view = new SimpleGLView(...). In this case calling view->MouseMoved(...) will call SimpleGLView::MouseMoved(...) because it is declared virtual. If it would not, the implementation BGLView::MouseMoved(...) would be called.

This mechanism of C++ to control method dispatching is different from Java.