OpenGl + SDL not working inside thread? (solved)

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
theHobbit
Posts: 65
Joined: Sat Sep 30, 2006 5:26 am

OpenGl + SDL not working inside thread? (solved)

Post by theHobbit »

Hello.

I'm trying to use SDL + OpenGL and do the drawing stuff inside a thread. But the app crashes whenever I call some OpenGL routine inside a thread. However it works fine if it's done in the main func. Like this:

Code: Select all

#include <stdio.h>
#include <stdlib.h>

#include <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>

int width = 480;
int height = 272;

int main&#40; int argc, char *argv&#91;&#93; &#41;
&#123;    
    SDL_Init &#40;SDL_INIT_VIDEO&#41;;
    
    if &#40;!SDL_SetVideoMode&#40; width, height, 32, SDL_OPENGL &#41;&#41; &#123;
        fprintf &#40;stdout, "Failed to create window\n"&#41;;
        SDL_Quit&#40; &#41;;
        return 0;
    &#125;
    
    glViewport&#40; 0, 0, width, height &#41;;
    glMatrixMode&#40;GL_PROJECTION&#41;;
    glLoadIdentity&#40;&#41;;
    gluPerspective&#40;45, width/height, 1, 10&#41;;
    glMatrixMode&#40;GL_MODELVIEW&#41;;
    glClear&#40;GL_COLOR_BUFFER_BIT&#41;;
	
	static int rotation = 0;
    float bheight;

    bheight = 3.0f;
    
    glLoadIdentity&#40;&#41;;
    gluLookAt&#40;0, 0, 5, 0, 0, 0, 0, 1, 0&#41;; 

    // Clear buffer
    glClearColor&#40;0.0f, 0.0f, 0.0f, 0.0f&#41;;
    glClear&#40;GL_COLOR_BUFFER_BIT&#41;;

    glColor3f&#40;1.0f, 0.0f, 0.0f&#41;;

    // Spin round a bit
    glRotatef&#40;rotation++, 0, 0, 1&#41;;

    // Draw bar
    glBegin&#40;GL_POLYGON&#41;;
    glVertex3f&#40;-0.1, -1, 0&#41;;
    glVertex3f&#40;0.1, -1, 0&#41;;
    glVertex3f&#40;0.1, bheight, 0&#41;;
    glVertex3f&#40;-0.1, bheight, 0&#41;;
    glEnd&#40;&#41;;

    glFinish&#40;&#41;;

    SDL_GL_SwapBuffers&#40;&#41;;
    
    SDL_Delay&#40; 5000 &#41;;
    SDL_Quit&#40; &#41;;
    return 0;
&#125;
But for some reason the app crashes when I try to do the rendering inside a thread like this:

Code: Select all

#include <stdio.h>
#include <stdlib.h>

#include <SDL/SDL.h>
#include <SDL/SDL_thread.h>
#include <GL/gl.h>
#include <GL/glu.h>

SDL_Thread *thread = NULL;

int width = 480;
int height = 272;

int func&#40; void *data &#41;
&#123;              
    while &#40;1&#41; &#123;
    static int rotation = 0;
    float bheight;

    bheight = 3.0f;
    
    glLoadIdentity&#40;&#41;;
    gluLookAt&#40;0, 0, 5, 0, 0, 0, 0, 1, 0&#41;; 

    // Clear buffer
    glClearColor&#40;0.0f, 0.0f, 0.0f, 0.0f&#41;;
    glClear&#40;GL_COLOR_BUFFER_BIT&#41;;

    glColor3f&#40;1.0f, 0.0f, 0.0f&#41;;

    // Spin round a bit
    glRotatef&#40;rotation++, 0, 0, 1&#41;;

    // Draw bar
    glBegin&#40;GL_POLYGON&#41;;
    glVertex3f&#40;-0.1, -1, 0&#41;;
    glVertex3f&#40;0.1, -1, 0&#41;;
    glVertex3f&#40;0.1, bheight, 0&#41;;
    glVertex3f&#40;-0.1, bheight, 0&#41;;
    glEnd&#40;&#41;;

    glFinish&#40;&#41;;

    SDL_GL_SwapBuffers&#40;&#41;;

    SDL_Delay&#40;1000 / 70&#41;;
  &#125;
&#125;

int main&#40; int argc, char *argv&#91;&#93; &#41;
&#123;    
    SDL_Init &#40;SDL_INIT_VIDEO&#41;;
    
    if &#40;!SDL_SetVideoMode&#40; width, height, 32, SDL_OPENGL &#41;&#41; &#123;
        fprintf &#40;stdout, "Failed to create window\n"&#41;;
        SDL_Quit&#40; &#41;;
        return 0;
    &#125;
    
    glViewport&#40; 0, 0, width, height &#41;;
    glMatrixMode&#40;GL_PROJECTION&#41;;
    glLoadIdentity&#40;&#41;;
    gluPerspective&#40;45, width/height, 1, 10&#41;;
    glMatrixMode&#40;GL_MODELVIEW&#41;;
    glClear&#40;GL_COLOR_BUFFER_BIT&#41;;

    thread = SDL_CreateThread&#40; func, NULL &#41;;     
	    
    SDL_Delay&#40; 5000 &#41;;
    SDL_Quit&#40; &#41;;
    return 0;
&#125;
I need this inside a thread because I'm working on something like a visualizer interface. Is there anyway to solve this? Hope anyone can help.
Sayounara
Last edited by theHobbit on Sat Sep 15, 2007 2:23 am, edited 1 time in total.
saulotmalo2
Posts: 43
Joined: Mon Sep 10, 2007 9:32 am

Post by saulotmalo2 »

i'm not sure about this but try using this while(1) on the main thread... is weird but it is for ensure that the thread creates well (also i have noticed that you're using SDL_Delay but it is only for try.

Code: Select all

#include <stdio.h>
#include <stdlib.h>

#include <SDL/SDL.h>
#include <SDL/SDL_thread.h>
#include <GL/gl.h>
#include <GL/glu.h>

SDL_Thread *thread = NULL;

int width = 480;
int height = 272;

int func&#40; void *data &#41;
&#123;             
    while &#40;1&#41; &#123;
    static int rotation = 0;
    float bheight;

    bheight = 3.0f;
   
    glLoadIdentity&#40;&#41;;
    gluLookAt&#40;0, 0, 5, 0, 0, 0, 0, 1, 0&#41;;

    // Clear buffer
    glClearColor&#40;0.0f, 0.0f, 0.0f, 0.0f&#41;;
    glClear&#40;GL_COLOR_BUFFER_BIT&#41;;

    glColor3f&#40;1.0f, 0.0f, 0.0f&#41;;

    // Spin round a bit
    glRotatef&#40;rotation++, 0, 0, 1&#41;;

    // Draw bar
    glBegin&#40;GL_POLYGON&#41;;
    glVertex3f&#40;-0.1, -1, 0&#41;;
    glVertex3f&#40;0.1, -1, 0&#41;;
    glVertex3f&#40;0.1, bheight, 0&#41;;
    glVertex3f&#40;-0.1, bheight, 0&#41;;
    glEnd&#40;&#41;;

    glFinish&#40;&#41;;

    SDL_GL_SwapBuffers&#40;&#41;;

    SDL_Delay&#40;1000 / 70&#41;;
  &#125;
&#125;

int main&#40; int argc, char *argv&#91;&#93; &#41;
&#123;   
    SDL_Init &#40;SDL_INIT_VIDEO&#41;;
   
    if &#40;!SDL_SetVideoMode&#40; width, height, 32, SDL_OPENGL &#41;&#41; &#123;
        fprintf &#40;stdout, "Failed to create window\n"&#41;;
        SDL_Quit&#40; &#41;;
        return 0;
    &#125;
   
    glViewport&#40; 0, 0, width, height &#41;;
    glMatrixMode&#40;GL_PROJECTION&#41;;
    glLoadIdentity&#40;&#41;;
    gluPerspective&#40;45, width/height, 1, 10&#41;;
    glMatrixMode&#40;GL_MODELVIEW&#41;;
    glClear&#40;GL_COLOR_BUFFER_BIT&#41;;

    thread = SDL_CreateThread&#40; func, NULL &#41;;     
    while&#40;1&#41;&#123; &#125;  
    SDL_Delay&#40; 5000 &#41;;
    SDL_Quit&#40; &#41;;
    return 0;
&#125; 
User avatar
Jim
Posts: 476
Joined: Sat Jul 02, 2005 10:06 pm
Location: Sydney
Contact:

Post by Jim »

This bit

Code: Select all

    while&#40;1&#41;&#123; &#125; 
in your main loop is going to suck up all the CPU time. You need to put a sleep in there.

Jim
saulotmalo2
Posts: 43
Joined: Mon Sep 10, 2007 9:32 am

Post by saulotmalo2 »

yes, it slows down a lot the CPU but i tell him to try in order of testing if the problem was that the thread creation cost is to high not for ever. also as i've said before he is already using a SDL_Delay but i'm not sure of this working good.
theHobbit
Posts: 65
Joined: Sat Sep 30, 2006 5:26 am

Post by theHobbit »

Thanks tryied it but with the same results. Maybe OpenGL isn't thread safe?
saulotmalo2
Posts: 43
Joined: Mon Sep 10, 2007 9:32 am

Post by saulotmalo2 »

another question may be... are you sure the code inside is executing? i mean have you tried to put a cout or printf in order of knowing if it is running well? It sounds weird but when something doesn't work most times is a very simple thing other times can be because big problems ;)
theHobbit
Posts: 65
Joined: Sat Sep 30, 2006 5:26 am

Post by theHobbit »

Thanks for the fast reply. Yep I put

Code: Select all

    fprintf&#40; stdout, "Inside Thread" &#41;;
just before the

Code: Select all

glLoadIdentity&#40;&#41;;
    gluLookAt&#40;0, 0, 5, 0, 0, 0, 0, 1, 0&#41;; 
routines and yes the stdout.txt file says a lot of 'Inside Thread' strings :)
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

A quick check of the SDL code shows that SDL_CreateThread() doesn't create a thread with the PSP_THREAD_ATTR_VFPU attribute set, so any use of the VFPU will crash the PSP. I do believe PSPGL is rife with VFPU usage.
theHobbit
Posts: 65
Joined: Sat Sep 30, 2006 5:26 am

Post by theHobbit »

Thanks a lot J.F. I have changed this line in the SDL_systhread.c file:

Code: Select all

thread->handle = sceKernelCreateThread&#40;"SDL thread", ThreadEntry, 
					       priority, 0x8000, 0, NULL&#41;;
with this:

Code: Select all

thread->handle = sceKernelCreateThread&#40;"SDL thread", ThreadEntry, 
					       priority, 0x8000, PSP_THREAD_ATTR_VFPU, NULL&#41;;
Rebuilt SDL, and is working now : ). Well hope that doesn't break something else...

Thanks Everyone!!
jimparis
Posts: 1145
Joined: Fri Jun 10, 2005 4:21 am
Location: Boston

Post by jimparis »

Committed in rev. 2315
Post Reply