Im writing a NeHe tutorial on how to use modules (.so and .dll) and how to
separate generic code that works on both OSs from whats not.
Okay here is the problem:
The window never gets created (and YES I am calling create_window()) and
the screen freezes in the create_window() code. However you can still
terminate the app without any probs. The wierd thing is that it sometimes
freezes at different places!
It usually freezes somewhere here, but sometimes a bit futher down:
cout << "Creating glX context
";
m_ctx = glXCreateContext(a_bp_x11_window.m_display, vi, 0, GL_TRUE);
//m_ctx = glXCreateContext(m_x11_window->m_display, vi, 0, GL_TRUE);
// create a color map
cout << "Creating colormap
";
cmap = XCreateColormap(m_x11_window->m_display, RootWindow(m_x11_window->m_display, vi->screen),
vi->visual, AllocNone);
m_x11_window->m_attr.colormap = cmap;
m_x11_window->m_attr.border_pixel = 0;
Because of this I suspect that there might be some problem with the linking
or something, but since im not an expert on neither glX or libs I dunno.
Also I know its not a driver problem since I have another program that does
the exact thing (the create_window() code is almost EXACTLY the same)
with the difference that both generic OpenGL and GLX code are in the same
class.
Futhermore I have been able to compile and run the windows version.
There is quite alot of code so here is a quick brief:
I have two final targets: lesson48_linux and renderer_glx.so
lesson48_linux doesnt do much except setting up a X11 loop, loading the
renderer from renderer_glx.so and telling it to start rendering.
Its in renderer_glx.so that everything happens.
Its composed of:
#1: Generic OpenGL that has been tested on windows (renderer_opengl.o)
this does all the actual rendering
#2: GLX code for setting up a glX context and stuff (glx_renderer.o)
Here lies the problem
#3: GLX renderer factory which simply returns a instance of cRenderer_glx
(C++ name mangling thingy)
Given the complexity i doubt anyone can help me but its worth a shoot.
Anyway here is the code (note that there is alot of **** that im going
to remove/fix afterwards like for example texture loading),
all the glX code is at the end so you might want to quickly scroll there.
</font><blockquote><font size=“1” face=“Verdana, Arial”>code:</font><hr /><pre style=“font-size:x-small; font-family: monospace;”>// Main Makefile:
// ->lesson/linux/
CC = g++
LD = g++
CFLAGS = -fPIC -Wall -pedantic -ansi
DYNLINKFLAGS = -fPIC -Wall -pedantic -ansi -shared -rdynamic
default: lesson48_linux
lesson48_linux: lesson48_linux.o
(CC) (CFLAGS) -o lesson48_linux lesson48_linux.o -L/usr/X11R6/lib -lXxf86vm
lesson48_linux.o: lesson48_linux.cc renderer_x11.hpp
(CC) (CFLAGS) -c lesson48_linux.cc
clean:
@echo Cleaning up…
@rm ./lesson48_linux
@rm ./*.o
@echo Done.
// Renderer Makefile:
// ->lesson/linux/glx/
CC = g++
LD = g++
CFLAGS = -fPIC -Wall -pedantic -ansi
DYNLINKFLAGS = -fPIC -Wall -pedantic -ansi -shared -rdynamic
default: renderer_glx.so
#The final module
renderer_glx.so: renderer_opengl.o renderer_glx.o renderer_glx_factory.o
(LD) -o renderer_glx.so renderer_glx.o renderer_opengl.o renderer_glx_factory.o -L/usr/X11R6/lib -lGL -lGLU -lXxf86vm (DYNLINKFLAGS)
#The factory object-file (this will end up in final module and simply return an instance of cRenderer_glx
renderer_glx_factory.o: renderer_glx.o
(CC) -c renderer_glx_factory.cc -o renderer_glx_factory.o (CFLAGS)
renderer_glx.o: renderer_glx.cc renderer_glx.hpp …/renderer_x11.hpp
(CC) -c renderer_glx.cc -o renderer_glx.o (CFLAGS)
#Object-file for generic OpenGL code
renderer_opengl.o: …/…/opengl/renderer_opengl.hpp …/…/opengl/renderer_opengl.cc
(CC) -c ../../opengl/renderer_opengl.cc -o renderer_opengl.o (CFLAGS)
clean:
@echo Cleaning up…
@rm ./.o
@rm ./.so
@echo Done.
// Lesson48_linux.cc
// ->lesson/linux/
/*
- This code was created by Alexander “BBB” Brink 2005 for NeHe
- Visit NeHe’s site at http://nehe.gamedev.net/
*/
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/xf86vmode.h>
#include <X11/keysym.h>
#include <iostream>
using namespace std;
#include <dlfcn.h>
#include “renderer_x11.hpp”
bp_x11_window g_x11_window;
iRenderer_x11 *g_x11_renderer = NULL;
bool g_done = false;
void keyPressed(KeySym a_key)
{
switch (a_key)
{
case XK_Escape:
g_done = true;
break;
case XK_q:
g_done = true;
break;
case XK_F1:
g_x11_renderer->m_kill_window();
g_x11_window.m_fullscreen = !g_x11_window.m_fullscreen;
g_x11_renderer->m_create_x11_window(g_x11_window);
break;
}
}
int main(int argc, char **argv)
{
XEvent event;
KeySym key;
g_done = false;
// default to fullscreen
g_x11_window.m_fullscreen = false;
void *x11_renderer_lib = dlopen("./glx/renderer_glx.so", RTLD_LAZY);
if (!x11_renderer_lib)
{
cout << "Could not load renderer lib!
";
cout << "Error: " << dlerror() << " .
";
return 1;
}
x11_renderer_factory_ptr *x11_renderer_factory =
(x11_renderer_factory_ptr*) dlsym(x11_renderer_lib, "renderer_x11_factory");
g_x11_renderer = x11_renderer_factory();
g_x11_window.m_width = 1024;
g_x11_window.m_height = 768;
g_x11_window.m_fullscreen = true;
g_x11_window.m_window_test = 5;
g_x11_renderer->m_create_x11_window(g_x11_window);
cout << "m_x11_window->m_window_test is: " << g_x11_window.m_window_test << "
";
XSelectInput(g_x11_window.m_display, g_x11_window.m_win, ExposureMask | PointerMotionMask | ButtonMotionMask);
// wait for events
while (!g_done)
{
// handle the events in the queue
while (XPending(g_x11_window.m_display) > 0)
{
XNextEvent(g_x11_window.m_display, &event);
switch (event.type)
{
case MotionNotify:
//g_x11_renderer->m_notify_cursor_pos(event.xmotion.x, event.xmotion.y);
break;
case Expose:
if (event.xexpose.count != 0)
break;
g_x11_renderer->m_render_frame();
break;
case ConfigureNotify:
// call resizeGLScene only if our window-size changed
if ((event.xconfigure.width != g_x11_window.m_width)