View previous topic :: View next topic |
Author |
Message |
Digited
Joined: 30 Oct 2007 Posts: 19
|
Posted: Sun Mar 02, 2008 4:20 pm Post subject: DerelictGL: any way to use without SDL? |
|
|
subj. Sorry if it's simple, I'm a real noob in linux and X, search didn't help. I've tried to mix X11 .d-headers from Bindings project with DerelictGL glx.d, but too many conflicts everywhere...
I need to create an X window (fullscreen or not) and do all the X system stuff manually, and use OpenGL. Is DerelictGL suitable for this? |
|
Back to top |
|
|
aldacron
Joined: 05 May 2004 Posts: 1322 Location: Seoul, South Korea
|
Posted: Sun Mar 02, 2008 7:38 pm Post subject: Re: DerelictGL: any way to use without SDL? |
|
|
Digited wrote: | subj. Sorry if it's simple, I'm a real noob in linux and X, search didn't help. I've tried to mix X11 .d-headers from Bindings project with DerelictGL glx.d, but too many conflicts everywhere...
I need to create an X window (fullscreen or not) and do all the X system stuff manually, and use OpenGL. Is DerelictGL suitable for this? |
DerelictGL is certainly intended to be used with modules other than SDL. Even without seeing precisely what your conflicts are, I think I can guess.
The platform specific modules in Derelict (currently wgl.d and glx.d) require platform specific definitions. The problem is that no assumptions can be made about which particular external platform modules someone will be using, so all the type declarations need to be internalized by Derelict. These types were declared publicly in wgl.d and glx.d. Conflicts in the wgl.d module were discovered early on when people were using it with other external Win32 modules. As a fix, the type declarations were made private. This still caused a problem later on with the signatures of the wgl functions and had to be worked around again.
Looking at the glx.d module, I see that the type declarations are all public. So when you import glx.d in a module that also imports other X11 modules, the type declarations conflict. I suppose you are the first person to use glx.d with external X11 modules (that has reported the problem anyway). I see two workarounds:
1) in any module that imports glx.d, don't import any X11 modules. This may not be possible, so likely isn't the best thing to try.
2) wrap the type declarations in glx.d with a private block. This will keep the declarations from conflicting with other modules. However, it could (and likely will) cause problems with the function signatures. You can see a similar problem with the wgl.d module in this recent thread.
I suggest you try the second option. If you get it working satisfactorily, I'd appreciate it if you could let me know what you needed to do, i.e. was the private block enough or did you need to make any other changes, etc. I'd like to know how it works before I update the trunk, since I currently have no way to test any Linux changes myself.
The only way to really kill this issue is to include a full set of platform-specific modules (win32, X11) in Derelict and ask people to use those instead of Tango/Phobos/Bindings/Whatever platform modules in DerelictGL apps. Not a very feasible thing to do. _________________ The One With D | The One With Aldacron | D Bits |
|
Back to top |
|
|
Lutger
Joined: 25 May 2006 Posts: 91
|
Posted: Wed Mar 05, 2008 8:31 am Post subject: |
|
|
I have the same problem. The only way to get it to work currently is to do a renamed import so the symbols won't conflict, and then cast everywhere.
Wrapping conflicting types in glx in a private block won't help, since D still thinks it is a conflict even if one of the symbols is private. This has been discussed on the newsgroup but I can't remember the reasoning for this behavior. And then you still need the casts.
Next to distributing the X11 libraries the only thing I can think of is making the functions that give conflicts into templates. You can instantiate templates with modules, so the user can then instanciate these functions with the X11 binding of choice. This might not be as bad as it sounds, I don't think there are a lot of such functions.
This is probably what I'm going to do myself, if you (Aldacron) or anybody would like to have the result just tell me.
P.S. there may be some constants missing in derelict.glx.d, I didn't find GLX_RGBA for example. I'm new with opengl in linux so I don't know yet what is supposed to be here, when I figure it out I will post or send a patch if you like. |
|
Back to top |
|
|
Lutger
Joined: 25 May 2006 Posts: 91
|
Posted: Wed Mar 05, 2008 9:33 am Post subject: |
|
|
Well my suggestion with templates is a bit annoying. I think for both wgl and glx, in the ideal situation you should be able to assume that they are installed and know where that is. glx.h does depend on x11.h after all.
But since we don't have such standards yet in D, another workaround is to let glx import a configuration module, say glxconfig.d, where the user can edit a single line to say where derelict should look for the X11 library. By default it would remain as is and declare it's own types. That's better? |
|
Back to top |
|
|
aldacron
Joined: 05 May 2004 Posts: 1322 Location: Seoul, South Korea
|
Posted: Wed Mar 05, 2008 7:48 pm Post subject: |
|
|
Lutger wrote: | But since we don't have such standards yet in D, another workaround is to let glx import a configuration module, say glxconfig.d, where the user can edit a single line to say where derelict should look for the X11 library. By default it would remain as is and declare it's own types. That's better? |
I'd like to avoid that if possible, but it may be the only solution short of hiding everything behind an object interface (which would defeat the purpose of the modules in the first place) or requiring specific Win32/X11 modules. What I did with wgl was to just to remove the type and alias declarations for the HANDLE types (HDC and HGLRC) and used void* in their place, since that's what they are declared as anyway. But I don't see a way to do anything similar with glx, since all of the types are structs. _________________ The One With D | The One With Aldacron | D Bits |
|
Back to top |
|
|
Digited
Joined: 30 Oct 2007 Posts: 19
|
Posted: Sat Mar 08, 2008 2:49 am Post subject: |
|
|
I really need help with launching OpenGL:
Code: | module dtest;
import
tango.stdc.stdio,
tango.stdc.stdlib,
tango.io.Console,
x11.Xlib,
x11.Xatom,
x11.Xutil,
derelict.opengl.gl,
derelict.opengl.glu,
derelict.opengl.glx;
alias derelict.opengl.glx dglx;
alias x11.Xlib.Display xdisp;
alias x11.Xlib.Window xwind;
//-----------------------------------------------------------------------------
// GLOBALS
//-----------------------------------------------------------------------------
xdisp* g_pDisplayX = null;
dglx.Display* g_pDisplayGL = null;
xwind g_window;
bool g_bDoubleBuffered = GL_TRUE;
uint g_textureID = 0;
float g_fSpinX = 0.0f;
float g_fSpinY = 0.0f;
int g_nLastMousePositX = 0;
int g_nLastMousePositY = 0;
bool g_bMousing = false;
struct Vertex3
{
float
tu, tv,
x, y, z;
static Vertex3 opCall( float _tu, float _tv, float _x, float _y, float _z )
{
Vertex3 v;
v.tu = _tu;
v.tv = _tv;
v.x = _x;
v.y = _y;
v.z = _z;
return v;
}
}
Vertex3[] g_quadVertices;
struct BMPImage
{
uint
width,
height;
char *data;
}
//-----------------------------------------------------------------------------
// Name: main()
// Desc:
//-----------------------------------------------------------------------------
int main( char[][] argv )
{
g_quadVertices =
[
Vertex3( 0.0f, 0.0f, -1.0f, -1.0f, 0.0f ),
Vertex3( 1.0f, 0.0f, 1.0f, -1.0f, 0.0f ),
Vertex3( 1.0f, 1.0f, 1.0f, 1.0f, 0.0f ),
Vertex3( 0.0f, 1.0f, -1.0f, 1.0f, 0.0f )
];
XSetWindowAttributes windowAttributes;
dglx.XVisualInfo* visualInfo = null;
_XEvent event;
Colormap colorMap;
GLXContext glxContext;
int errorBase,
eventBase;
// Open a connection to the X server
g_pDisplayX = XOpenDisplay( null );
if( !g_pDisplayX )
{
Cerr( "could not open display" );
return -1;
}
DerelictGL.load();
g_pDisplayGL = cast( dglx.Display* )g_pDisplayX;
// Make sure OpenGL's GLX extension supported
if( !glXQueryExtension( g_pDisplayGL, &errorBase, &eventBase ))
{
Cerr( "X server has no OpenGL GLX extension" );
return -1;
}
// Find an appropriate visual
int[] doubleBufferVisual =
[
GLX_RGBA, // Needs to support OpenGL
GLX_DEPTH_SIZE, 16, // Needs to support a 16 bit depth buffer
GLX_DOUBLEBUFFER, // Needs to support double-buffering
0 // end of list
];
// Try for the double-bufferd visual first
visualInfo = glXChooseVisual( g_pDisplayGL, XDefaultScreen( g_pDisplayX ), doubleBufferVisual.ptr );
if( !visualInfo )
{
Cerr( "no RGB visual with depth buffer" );
return -1;
}
// Create an OpenGL rendering context
glxContext = glXCreateContext( g_pDisplayGL,
visualInfo,
null, // No sharing of display lists
GL_TRUE ); // Direct rendering if possible
if( !glxContext )
{
Cerr( "could not create rendering context" );
return -1;
}
// Create an X colormap since we're probably not using the default visual
colorMap = XCreateColormap( g_pDisplayX,
XRootWindow(g_pDisplayX, visualInfo.screen),
cast( _N4* )visualInfo.visual,
AllocNone );
windowAttributes.colormap = colorMap;
windowAttributes.border_pixel = 0;
windowAttributes.event_mask = ExposureMask |
VisibilityChangeMask |
KeyPressMask |
KeyReleaseMask |
ButtonPressMask |
ButtonReleaseMask |
PointerMotionMask |
StructureNotifyMask |
SubstructureNotifyMask |
FocusChangeMask;
// Create an X window with the selected visual
g_window = XCreateWindow( g_pDisplayX,
XRootWindow(g_pDisplayX, visualInfo.screen),
0, 0, // x/y position of top-left outside corner of the window
640, 480, // Width and height of window
0, // Border width
visualInfo.depth,
InputOutput,
cast( _N4* )visualInfo.visual,
CWBorderPixel | CWColormap | CWEventMask,
&windowAttributes );
XSetStandardProperties( g_pDisplayX,
g_window,
"GLX Sample",
"GLX Sample",
None,
null,
0,
null );
// Bind the rendering context to the window
glXMakeCurrent( g_pDisplayGL, cast(GLXDrawable)g_window, glxContext );
// Request the X window to be displayed on the screen
XMapWindow( g_pDisplayX, g_window );
// Init OpenGL...
init();
// Enter the render loop and don't forget to dispatch X events as
// they occur.
while(1)
{
do
{
XNextEvent( g_pDisplayX, &event );
switch( event.type )
{
case ButtonPress:
{
if( event.xbutton.button == 1 )
{
g_nLastMousePositX = event.xmotion.x;
g_nLastMousePositY = event.xmotion.y;
g_bMousing = true;
}
}
break;
case ButtonRelease:
{
if( event.xbutton.button == 1 )
g_bMousing = false;
}
break;
case KeyPress:
{
Cout( "KeyPress event\n" );
}
break;
case KeyRelease:
{
Cout( "KeyRelease event\n" );
}
break;
case MotionNotify:
{
if( g_bMousing )
{
g_fSpinX -= (event.xmotion.x - g_nLastMousePositX);
g_fSpinY -= (event.xmotion.y - g_nLastMousePositY);
g_nLastMousePositX = event.xmotion.x;
g_nLastMousePositY = event.xmotion.y;
}
}
break;
case Expose:
{
Cout( "Expose event\n" );
}
break;
case ConfigureNotify:
{
glViewport( 0, 0, event.xconfigure.width, event.xconfigure.height );
}
}
}
while( XPending(g_pDisplayX) ); // Loop to compress events
render();
}
}
//-----------------------------------------------------------------------------
// Name: init()
// Desc: Init OpenGL context for rendering
//-----------------------------------------------------------------------------
void init()
{
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( 45.0f, 640.0f / 480.0f, 0.1f, 100.0f);
}
//-----------------------------------------------------------------------------
// Name: render()
// Desc: Called when the GLX window is ready to render
//-----------------------------------------------------------------------------
void render()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslatef( 0.0f, 0.0f, -5.0f );
glRotatef( -g_fSpinY, 1.0f, 0.0f, 0.0f );
glRotatef( -g_fSpinX, 0.0f, 1.0f, 0.0f );
glInterleavedArrays( GL_T2F_V3F, 0, g_quadVertices.ptr );
glDrawArrays( GL_QUADS, 0, 4 );
glXSwapBuffers( g_pDisplayGL, cast(GLXDrawable)g_window ); // Buffer swap does implicit glFlush
}
void ShutdownGL()
{
//
}
//-------------------------------------------------------------------------
// subj
//-------------------------------------------------------------------------
void ShutdownWindow()
{
XDestroyWindow( g_pDisplayX, g_window );
XCloseDisplay( g_pDisplayX );
} |
I'm trying to compile this under openSUSE 10.3 using DMD for linux v1.026, gcc 4.2.1 below, tango Frank, latest DerelictGL & DerelictUtil and X11 from Bindings. This code is not brilliant and is a bit unfinished.
Small problems:
1. aliases don't work for pointers on them - look at the casts... Is it a bug or a feature of D?
2. DerelictGL conflicts a lot with Xlib, look at g_pDisplayX and g_pDisplayGL - I did this to avoid lots of casts...
Is it possible to separate X window creation code from OpenGL stuff, like mode and GC creation?
Big problems: the code compiles, but does not link: ld says:
dmd -g -debug -I../vtm/dependent -I/usr/local/include/d -c hello.d -ofobj/Debug/hello.o
gcc -o bin/Debug/dtest obj/Debug/hello.o -lX11 -lopengl32 -lglu32 -lderelictutil -lpthread -lm -ltango-base-dmd -ltango-user-dmd
/usr/lib/gcc/i586-suse-linux/4.2.1/../../../../i586-suse-linux/bin/ld: Dwarf Error: Could not find abbrev number 120.
obj/Debug/hello.o: In function `_Dmain':
hello.d.text._Dmain+0xf9): undefined reference to `_D3x114Xlib7_XEvent6__initZ'
collect2: ld returned 1 exit status
What is a dwarf error with abbrev no120?.. ld seems can't find initialisation of Xlib's union "XEvent"... That's two last strange errors, I suppose.
help |
|
Back to top |
|
|
aldacron
Joined: 05 May 2004 Posts: 1322 Location: Seoul, South Korea
|
Posted: Sat Mar 08, 2008 5:50 am Post subject: |
|
|
This one is beyond my means right now. I'll see if I can point to this thread one or two of the guys who help with Derelict on Linux. _________________ The One With D | The One With Aldacron | D Bits |
|
Back to top |
|
|
Lutger
Joined: 25 May 2006 Posts: 91
|
Posted: Sat Mar 08, 2008 6:47 am Post subject: |
|
|
I could get your example to compile, but not run*, probably something wrong with my configuration here.
Changing this declaration: '_XEvent event;' into this:
'XEvent event;' will probably help with linker errors.
As for the dwarf error, some googling suggests that it is related to missing or corrupted debug info in the object files.
* these are the errors:
Quote: | X Error of failed request: BadMatch (invalid parameter attributes)
Major opcode of failed request: 1 (X_CreateWindow)
Serial number of failed request: 16
Current serial number in output stream: 19 |
|
|
Back to top |
|
|
Digited
Joined: 30 Oct 2007 Posts: 19
|
Posted: Sat Mar 08, 2008 1:52 pm Post subject: |
|
|
Lutger wrote: | Changing this declaration: '_XEvent event;' into this:
'XEvent event;' will probably help with linker errors. |
It didn't, and I tried it first...
Can anyone give a link to or post here the source of window creation with OpenGL setup on linux (with DerelictGL but without GLFW(_gld), SDL or GLUT/freeglut)? Or even without DerelictGL? |
|
Back to top |
|
|
Digited
Joined: 30 Oct 2007 Posts: 19
|
Posted: Thu Mar 20, 2008 1:08 pm Post subject: |
|
|
At last, everything works. Here's how it does:
1. example module
Code: |
module dtest;
import
tango.stdc.stdio,
tango.stdc.stdlib,
tango.io.Console,
X11.Xlib,
X11.Xatom,
X11.Xutil,
X11.keysymdef,
derelict.opengl.gl,
derelict.opengl.glu,
derelict.opengl.glx;
alias derelict.opengl.glx dglx;
alias X11.Xlib.Display xdisp;
alias X11.Xlib.Window xwind;
//-----------------------------------------------------------------------------
// GLOBALS
//-----------------------------------------------------------------------------
xdisp* g_pDisplayX = null;
dglx.Display* g_pDisplayGL= null;
xwind g_window;
GLXContext glxContext;
float g_fSpinX = 0.0f;
float g_fSpinY = 0.0f;
long frames = 0;
struct Vertex3
{
float
tu, tv,
x, y, z;
static Vertex3 opCall( float _tu, float _tv, float _x, float _y, float _z )
{
Vertex3 v;
v.tu = _tu;
v.tv = _tv;
v.x = _x;
v.y = _y;
v.z = _z;
return v;
}
}
Vertex3[] g_quadVertices;
struct BMPImage
{
uint
width,
height;
char *data;
}
static this()
{
g_quadVertices =
[
Vertex3( 0.0f, 0.0f, -1.0f, -1.0f, 0.0f ),
Vertex3( 1.0f, 0.0f, 1.0f, -1.0f, 0.0f ),
Vertex3( 1.0f, 1.0f, 1.0f, 1.0f, 0.0f ),
Vertex3( 0.0f, 1.0f, -1.0f, 1.0f, 0.0f )
];
DerelictGL.load();
DerelictGLU.load();
}
//-----------------------------------------------------------------------------
/// entry point
//-----------------------------------------------------------------------------
int main( char[][] argv )
{
Cout( "Program started. Fasten ya seatbeltz!" )().newline;
XSetWindowAttributes windowAttributes;
dglx.XVisualInfo* visualInfo = null;
XEvent event;
Colormap colorMap;
int errorBase,
eventBase;
// Open a connection to the X server
g_pDisplayX = XOpenDisplay( null );
if( !g_pDisplayX )
{
Cerr( "could not open display" );
return -1;
}
g_pDisplayGL = cast( dglx.Display* )g_pDisplayX;
// Make sure OpenGL's GLX extension supported
if( !glXQueryExtension( g_pDisplayGL, &errorBase, &eventBase ))
{
Cerr( "X server has no OpenGL GLX extension" );
return -1;
}
// Find an appropriate visual
int[] doubleBufferVisual =
[
GLX_RGBA, // Needs to support OpenGL
GLX_DEPTH_SIZE, 16, // Needs to support a 16 bit depth buffer
GLX_DOUBLEBUFFER, // Needs to support double-buffering
0 // end of list
];
// Try for the double-bufferd visual first
visualInfo = glXChooseVisual( g_pDisplayGL, XDefaultScreen( g_pDisplayX ), doubleBufferVisual.ptr );
if( !visualInfo )
{
Cerr( "no RGB visual with depth buffer" )();
return -1;
}
// Create an OpenGL rendering context
glxContext = glXCreateContext(
g_pDisplayGL,
visualInfo,
null, // No sharing of display lists
GL_TRUE ); // Direct rendering if possible
if( !glxContext )
{
Cerr( "could not create rendering context" )();
return -1;
}
// Create an X colormap since we're probably not using the default visual
colorMap = XCreateColormap(
g_pDisplayX,
XRootWindow( g_pDisplayX, visualInfo.screen ),
cast( _N4* )visualInfo.visual,
AllocNone );
windowAttributes.colormap = colorMap;
windowAttributes.border_pixel = 0;
windowAttributes.event_mask = ExposureMask |
VisibilityChangeMask |
KeyPressMask |
KeyReleaseMask |
ButtonPressMask |
ButtonReleaseMask |
PointerMotionMask |
StructureNotifyMask |
SubstructureNotifyMask |
FocusChangeMask;
// Create an X window with the selected visual
g_window = XCreateWindow(
g_pDisplayX,
XRootWindow( g_pDisplayX, visualInfo.screen ),
0, 0, // x/y position of top-left outside corner of the window
640, 480, // Width and height of window
0, // Border width
visualInfo.depth,
InputOutput,
cast( _N4* )visualInfo.visual,
CWBorderPixel | CWColormap | CWEventMask,
&windowAttributes );
XSetStandardProperties(
g_pDisplayX,
g_window,
"Hello GLX!",
"Hello GLX!",
None,
null,
0,
null );
// Bind the rendering context to the window
glXMakeCurrent( g_pDisplayGL, cast(GLXDrawable)g_window, glxContext );
// Request the X window to be displayed on the screen
XMapWindow( g_pDisplayX, g_window );
// Init OpenGL...
InitOpenGL();
int key = 0;
bool running = true;
while( running )
{
while( XPending( g_pDisplayX ) ) // Loop to compress events
{
XNextEvent( g_pDisplayX, &event );
switch( event.type )
{
case KeyPress:
// Now try pimary keysym
key = XKeycodeToKeysym( g_pDisplayX, event.xkey.keycode, 0 );
switch( key )
{
// Special keys (non character keys)
case XK_Escape:
Cout( "Escape keypress cathed. Stopping program cycle..." )().newline;
running = false;
break;
default:
break;
}
break;
case Expose:
break;
case ConfigureNotify:
glViewport( 0, 0, event.xconfigure.width, event.xconfigure.height );
break;
// Was the window destroyed?
case DestroyNotify:
running = false;
break;
default:
break;
}
}
Render();
}
Cout( "Main cycle ended. Starting shutdown..." )().newline;
ShutdownGL();
ShutdownWindow();
Cout( "Game over." )().newline;
return 0;
}
//-----------------------------------------------------------------------------
// Name: init()
// Desc: Init OpenGL context for rendering
//-----------------------------------------------------------------------------
void InitOpenGL()
{
glClearColor( 0.5f, 0.5f, 0.5f, 1.0f );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( 45.0f, 640.0f / 480.0f, 0.1f, 100.0f);
}
//-----------------------------------------------------------------------------
// Name: render()
// Desc: Called when the GLX window is ready to render
//-----------------------------------------------------------------------------
void Render()
{
frames++;
g_fSpinX += 0.1f;
g_fSpinY -= 0.2f;
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslatef( 0.0f, 0.0f, -5.0f );
glRotatef( -g_fSpinY, 1.0f, 0.0f, 0.0f );
glRotatef( -g_fSpinX, 0.0f, 1.0f, 0.0f );
glInterleavedArrays( GL_T2F_V3F, 0, g_quadVertices.ptr );
glDrawArrays( GL_QUADS, 0, 4 );
glXSwapBuffers( g_pDisplayGL, cast(GLXDrawable)g_window ); // Buffer swap does implicit glFlush
}
//-------------------------------------------------------------------------
// subj
//-------------------------------------------------------------------------
void ShutdownGL()
{
glXMakeCurrent( g_pDisplayGL, 0, null ); // Release the context
glXDestroyContext( g_pDisplayGL, glxContext );
}
//-------------------------------------------------------------------------
// subj
//-------------------------------------------------------------------------
void ShutdownWindow()
{
XUnmapWindow( g_pDisplayX, g_window ); // unmap the window
XDestroyWindow( g_pDisplayX, g_window ); //destroy the window
XCloseDisplay( g_pDisplayX ); //close the display
}
|
It uses tango, but it's easy to port to phobos (Cout only).
2. I use x11 bindings from Schooner project (and they differ from Bindings' x11, I was wrong in post above). Somehow, when I tried compile them to a static lib and then link to app, code didn't link because of **XEvent_init** missing. Now I suppose, that was because I named X11 as system X11.a, so maybe only system lib was really linked... I'm not sure. Now I include them (except glx.d) to project and compile - and linking succeeds.
3. I manually added to DerelictGL-glx.d all declarations(const defines) from x11's glx.d, as they are used for window creation routines. You can see them here, lines 66-270.
4. I linked system X11.a (/usr/lib), DerelictUtil, DerelictGL and DerelictGLU (I'll use it later).
And so it finally works, and we start to test freetype lib and port our engine to tango and add linux rendering support... |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|