X support

This commit is contained in:
David Rose 2008-05-04 08:00:12 +00:00
parent 90d7caf0a9
commit 19e0b0824c
18 changed files with 2548 additions and 109 deletions

View File

@ -14,11 +14,13 @@
#define SOURCES \
config_tinydisplay.cxx config_tinydisplay.h \
tinyGeomMunger.I tinyGeomMunger.cxx tinyGeomMunger.h \
tinyGraphicsPipe.I tinyGraphicsPipe.cxx tinyGraphicsPipe.h \
tinyGraphicsWindow.h tinyGraphicsWindow.I tinyGraphicsWindow.cxx \
tinySDLGraphicsPipe.I tinySDLGraphicsPipe.cxx tinySDLGraphicsPipe.h \
tinySDLGraphicsWindow.h tinySDLGraphicsWindow.I tinySDLGraphicsWindow.cxx \
tinyGraphicsStateGuardian.h tinyGraphicsStateGuardian.I \
tinyGraphicsStateGuardian.cxx \
tinyTextureContext.I tinyTextureContext.cxx tinyTextureContext.h \
tinyXGraphicsPipe.I tinyXGraphicsPipe.cxx tinyXGraphicsPipe.h \
tinyXGraphicsWindow.h tinyXGraphicsWindow.I tinyXGraphicsWindow.cxx \
api.c arrays.c clear.c clip.c error.c get.c \
glu.c image_util.c init.c light.c list.c \
matrix.c memory.c misc.c msghandling.c msghandling.h \

View File

@ -17,8 +17,10 @@
////////////////////////////////////////////////////////////////////
#include "config_tinydisplay.h"
#include "tinyGraphicsPipe.h"
#include "tinyGraphicsWindow.h"
#include "tinySDLGraphicsPipe.h"
#include "tinySDLGraphicsWindow.h"
#include "tinyXGraphicsPipe.h"
#include "tinyXGraphicsWindow.h"
#include "tinyGraphicsStateGuardian.h"
#include "tinyGeomMunger.h"
#include "tinyTextureContext.h"
@ -33,6 +35,29 @@ ConfigureFn(config_tinydisplay) {
init_libtinydisplay();
}
ConfigVariableString display_cfg
("display", "",
PRC_DESC("Specify the X display string for the default display. If this "
"is not specified, $DISPLAY is used."));
ConfigVariableBool x_error_abort
("x-error-abort", false,
PRC_DESC("Set this true to trigger and abort (and a stack trace) on receipt "
"of an error from the X window system. This can make it easier "
"to discover where these errors are generated."));
ConfigVariableInt x_wheel_up_button
("x-wheel-up-button", 4,
PRC_DESC("This is the mouse button index of the wheel_up event: which "
"mouse button number does the system report when the mouse wheel "
"is rolled one notch up?"));
ConfigVariableInt x_wheel_down_button
("x-wheel-down-button", 5,
PRC_DESC("This is the mouse button index of the wheel_down event: which "
"mouse button number does the system report when the mouse wheel "
"is rolled one notch down?"));
////////////////////////////////////////////////////////////////////
// Function: init_libtinydisplay
// Description: Initializes the library. This must be called at
@ -49,15 +74,23 @@ init_libtinydisplay() {
}
initialized = true;
TinyGraphicsPipe::init_type();
TinyGraphicsWindow::init_type();
TinyGraphicsStateGuardian::init_type();
TinyGeomMunger::init_type();
TinyTextureContext::init_type();
GraphicsPipeSelection *selection = GraphicsPipeSelection::get_global_ptr();
selection->add_pipe_type(TinyGraphicsPipe::get_class_type(),
TinyGraphicsPipe::pipe_constructor);
#ifdef IS_LINUX
TinyXGraphicsPipe::init_type();
TinyXGraphicsWindow::init_type();
selection->add_pipe_type(TinyXGraphicsPipe::get_class_type(),
TinyXGraphicsPipe::pipe_constructor);
#endif
TinySDLGraphicsPipe::init_type();
TinySDLGraphicsWindow::init_type();
selection->add_pipe_type(TinySDLGraphicsPipe::get_class_type(),
TinySDLGraphicsPipe::pipe_constructor);
PandaSystem *ps = PandaSystem::get_global_ptr();
ps->add_system("TinyGL");

View File

@ -21,9 +21,17 @@
#include "pandabase.h"
#include "notifyCategoryProxy.h"
#include "configVariableString.h"
#include "configVariableBool.h"
#include "configVariableInt.h"
NotifyCategoryDecl(tinydisplay, EXPCL_PANDAGL, EXPTP_PANDAGL);
extern EXPCL_PANDAGL void init_libtinydisplay();
extern ConfigVariableString display_cfg;
extern ConfigVariableBool x_error_abort;
extern ConfigVariableInt x_wheel_up_button;
extern ConfigVariableInt x_wheel_down_button;
#endif

View File

@ -37,9 +37,9 @@ static const ZB_fillTriangleFunc fill_tri_funcs
[2 /* depth write: zon, zoff */]
[3 /* color write: noblend, blend, nocolor */]
[3 /* alpha test: anone, aless, amore */]
[2 /* ztest: znone, zless */]
[3 /* white, flat, smooth */]
[3 /* untextured, textured, perspective textured */] = {
[2 /* depth test: znone, zless */]
[3 /* shading: white, flat, smooth */]
[3 /* texturing: untextured, textured, perspective textured */] = {
{ // depth write zon
{ // color write noblend
{ // alpha test anone
@ -586,6 +586,8 @@ reset() {
free_pointers();
GraphicsStateGuardian::reset();
glInit(_current_frame_buffer);
_c = gl_get_context();
_c->draw_triangle_front = gl_draw_triangle_fill;
@ -811,6 +813,8 @@ begin_frame(Thread *current_thread) {
return false;
}
_c->zb = _current_frame_buffer;
#ifdef DO_PSTATS
_vertices_immediate_pcollector.clear_level();
#endif
@ -1151,26 +1155,26 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
// as well use the flat shading model.
shade_model = ShadeModelAttrib::M_flat;
}
int color_state = 2; // smooth
int shading_state = 2; // smooth
if (shade_model == ShadeModelAttrib::M_flat) {
color_state = 1; // flat
shading_state = 1; // flat
if (_c->current_color.X == 1.0f &&
_c->current_color.Y == 1.0f &&
_c->current_color.Z == 1.0f &&
_c->current_color.W == 1.0f) {
color_state = 0; // white
shading_state = 0; // white
}
}
int texture_state = 0; // untextured
int texturing_state = 0; // untextured
if (_c->texture_2d_enabled) {
texture_state = 2; // perspective-correct textures
texturing_state = 2; // perspective-correct textures
if (_c->matrix_model_projection_no_w_transform) {
texture_state = 1; // non-perspective-correct textures
texturing_state = 1; // non-perspective-correct textures
}
}
_c->zb_fill_tri = fill_tri_funcs[depth_write_state][color_write_state][alpha_test_state][depth_test_state][color_state][texture_state];
_c->zb_fill_tri = fill_tri_funcs[depth_write_state][color_write_state][alpha_test_state][depth_test_state][shading_state][texturing_state];
//_c->zb_fill_tri = ZB_fillTriangleFlat_zless;
return true;

View File

@ -22,11 +22,12 @@
#include "pandabase.h"
#include "graphicsStateGuardian.h"
#include "tinyGraphicsPipe.h"
#include "tinySDLGraphicsPipe.h"
#include "tinygl.h"
extern "C" {
#include "zmath.h"
#include "zbuffer.h"
}
class TinyTextureContext;
@ -34,11 +35,10 @@ struct GLContext;
struct GLVertex;
struct GLImage;
////////////////////////////////////////////////////////////////////
// Class : TinyGraphicsStateGuardian
// Description : An interface to TinySDGL (an implementation of TinyGL
// over SDL).
// Description : An interface to the TinyGL software rendering code
// within this module.
////////////////////////////////////////////////////////////////////
class TinyGraphicsStateGuardian : public GraphicsStateGuardian {
public:
@ -118,6 +118,10 @@ private:
INLINE static GLenum get_light_id(int index);
public:
// Filled in by the Tiny*GraphicsWindow at begin_frame().
ZBuffer *_current_frame_buffer;
private:
GLContext *_c;

View File

@ -1,4 +1,4 @@
// Filename: tinyGraphicsPipe.I
// Filename: tinySDLGraphicsPipe.I
// Created by: drose (24Apr08)
//
////////////////////////////////////////////////////////////////////

View File

@ -1,4 +1,4 @@
// Filename: tinyGraphicsPipe.cxx
// Filename: tinySDLGraphicsPipe.cxx
// Created by: drose (24Apr08)
//
////////////////////////////////////////////////////////////////////
@ -16,21 +16,21 @@
//
////////////////////////////////////////////////////////////////////
#include "tinyGraphicsPipe.h"
#include "tinyGraphicsWindow.h"
#include "tinySDLGraphicsPipe.h"
#include "tinySDLGraphicsWindow.h"
#include "tinyGraphicsStateGuardian.h"
#include "config_tinydisplay.h"
#include "frameBufferProperties.h"
TypeHandle TinyGraphicsPipe::_type_handle;
TypeHandle TinySDLGraphicsPipe::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsPipe::Constructor
// Function: TinySDLGraphicsPipe::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
TinyGraphicsPipe::
TinyGraphicsPipe() {
TinySDLGraphicsPipe::
TinySDLGraphicsPipe() {
_is_valid = true;
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
@ -41,12 +41,12 @@ TinyGraphicsPipe() {
}
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsPipe::Destructor
// Function: TinySDLGraphicsPipe::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
TinyGraphicsPipe::
~TinyGraphicsPipe() {
TinySDLGraphicsPipe::
~TinySDLGraphicsPipe() {
if (SDL_WasInit(SDL_INIT_VIDEO)) {
SDL_QuitSubSystem(SDL_INIT_VIDEO);
}
@ -55,7 +55,7 @@ TinyGraphicsPipe::
}
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsPipe::get_interface_name
// Function: TinySDLGraphicsPipe::get_interface_name
// Access: Published, Virtual
// Description: Returns the name of the rendering interface
// associated with this GraphicsPipe. This is used to
@ -64,29 +64,29 @@ TinyGraphicsPipe::
// particular platform, so the name should be meaningful
// and unique for a given platform.
////////////////////////////////////////////////////////////////////
string TinyGraphicsPipe::
string TinySDLGraphicsPipe::
get_interface_name() const {
return "TinyGL";
}
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsPipe::pipe_constructor
// Function: TinySDLGraphicsPipe::pipe_constructor
// Access: Public, Static
// Description: This function is passed to the GraphicsPipeSelection
// object to allow the user to make a default
// TinyGraphicsPipe.
// TinySDLGraphicsPipe.
////////////////////////////////////////////////////////////////////
PT(GraphicsPipe) TinyGraphicsPipe::
PT(GraphicsPipe) TinySDLGraphicsPipe::
pipe_constructor() {
return new TinyGraphicsPipe;
return new TinySDLGraphicsPipe;
}
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsPipe::make_output
// Function: TinySDLGraphicsPipe::make_output
// Access: Protected, Virtual
// Description: Creates a new window on the pipe, if possible.
////////////////////////////////////////////////////////////////////
PT(GraphicsOutput) TinyGraphicsPipe::
PT(GraphicsOutput) TinySDLGraphicsPipe::
make_output(const string &name,
const FrameBufferProperties &fb_prop,
const WindowProperties &win_prop,
@ -99,12 +99,12 @@ make_output(const string &name,
return NULL;
}
TinyGraphicsStateGuardian *glxgsg = 0;
TinyGraphicsStateGuardian *tinygsg = 0;
if (gsg != 0) {
DCAST_INTO_R(glxgsg, gsg, NULL);
DCAST_INTO_R(tinygsg, gsg, NULL);
}
// First thing to try: a TinyGraphicsWindow
// First thing to try: a TinySDLGraphicsWindow
if (retry == 0) {
if (((flags&BF_require_parasite)!=0)||
@ -116,8 +116,8 @@ make_output(const string &name,
((flags&BF_can_bind_every)!=0)) {
return NULL;
}
return new TinyGraphicsWindow(this, name, fb_prop, win_prop,
flags, gsg, host);
return new TinySDLGraphicsWindow(this, name, fb_prop, win_prop,
flags, gsg, host);
}
// Nothing else left to try.

View File

@ -1,4 +1,4 @@
// Filename: tinyGraphicsPipe.h
// Filename: tinySDLGraphicsPipe.h
// Created by: drose (24Apr08)
//
////////////////////////////////////////////////////////////////////
@ -16,8 +16,8 @@
//
////////////////////////////////////////////////////////////////////
#ifndef TINYGRAPHICSPIPE_H
#define TINYGRAPHICSPIPE_H
#ifndef TINYSDLGRAPHICSPIPE_H
#define TINYSDLGRAPHICSPIPE_H
#include "pandabase.h"
#include "graphicsWindow.h"
@ -26,14 +26,14 @@
class FrameBufferProperties;
////////////////////////////////////////////////////////////////////
// Class : TinyGraphicsPipe
// Description : This graphics pipe represents the interface for
// to TinySDGL (an implementation of TinyGL over SDL).
// Class : TinySDLGraphicsPipe
// Description : This graphics pipe manages SDL windows for rendering
// TinyGL software buffers.
////////////////////////////////////////////////////////////////////
class TinyGraphicsPipe : public GraphicsPipe {
class TinySDLGraphicsPipe : public GraphicsPipe {
public:
TinyGraphicsPipe();
virtual ~TinyGraphicsPipe();
TinySDLGraphicsPipe();
virtual ~TinySDLGraphicsPipe();
virtual string get_interface_name() const;
static PT(GraphicsPipe) pipe_constructor();
@ -54,7 +54,7 @@ public:
}
static void init_type() {
GraphicsPipe::init_type();
register_type(_type_handle, "TinyGraphicsPipe",
register_type(_type_handle, "TinySDLGraphicsPipe",
GraphicsPipe::get_class_type());
}
virtual TypeHandle get_type() const {
@ -66,6 +66,6 @@ private:
static TypeHandle _type_handle;
};
#include "tinyGraphicsPipe.I"
#include "tinySDLGraphicsPipe.I"
#endif

View File

@ -1,4 +1,4 @@
// Filename: tinyGraphicsWindow.I
// Filename: tinySDLGraphicsWindow.I
// Created by: drose (24Apr08)
//
////////////////////////////////////////////////////////////////////

View File

@ -1,4 +1,4 @@
// Filename: tinyGraphicsWindow.cxx
// Filename: tinySDLGraphicsWindow.cxx
// Created by: drose (24Apr08)
//
////////////////////////////////////////////////////////////////////
@ -16,24 +16,24 @@
//
////////////////////////////////////////////////////////////////////
#include "tinyGraphicsWindow.h"
#include "tinySDLGraphicsWindow.h"
#include "tinyGraphicsStateGuardian.h"
#include "config_tinydisplay.h"
#include "tinyGraphicsPipe.h"
#include "tinySDLGraphicsPipe.h"
#include "mouseButton.h"
#include "keyboardButton.h"
#include "graphicsPipe.h"
#include "tinygl.h"
TypeHandle TinyGraphicsWindow::_type_handle;
TypeHandle TinySDLGraphicsWindow::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsWindow::Constructor
// Function: TinySDLGraphicsWindow::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
TinyGraphicsWindow::
TinyGraphicsWindow(GraphicsPipe *pipe,
TinySDLGraphicsWindow::
TinySDLGraphicsWindow(GraphicsPipe *pipe,
const string &name,
const FrameBufferProperties &fb_prop,
const WindowProperties &win_prop,
@ -52,16 +52,16 @@ TinyGraphicsWindow(GraphicsPipe *pipe,
}
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsWindow::Destructor
// Function: TinySDLGraphicsWindow::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
TinyGraphicsWindow::
~TinyGraphicsWindow() {
TinySDLGraphicsWindow::
~TinySDLGraphicsWindow() {
}
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsWindow::begin_frame
// Function: TinySDLGraphicsWindow::begin_frame
// Access: Public, Virtual
// Description: This function will be called within the draw thread
// before beginning rendering for a given frame. It
@ -69,27 +69,52 @@ TinyGraphicsWindow::
// if the frame should be rendered, or false if it
// should be skipped.
////////////////////////////////////////////////////////////////////
bool TinyGraphicsWindow::
bool TinySDLGraphicsWindow::
begin_frame(FrameMode mode, Thread *current_thread) {
return true;
begin_frame_spam(mode);
if (_gsg == (GraphicsStateGuardian *)NULL) {
return false;
}
TinyGraphicsStateGuardian *tinygsg;
DCAST_INTO_R(tinygsg, _gsg, false);
tinygsg->_current_frame_buffer = _frame_buffer;
tinygsg->reset_if_new();
_gsg->set_current_properties(&get_fb_properties());
return _gsg->begin_frame(current_thread);
}
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsWindow::end_frame
// Function: TinySDLGraphicsWindow::end_frame
// Access: Public, Virtual
// Description: This function will be called within the draw thread
// after rendering is completed for a given frame. It
// should do whatever finalization is required.
////////////////////////////////////////////////////////////////////
void TinyGraphicsWindow::
void TinySDLGraphicsWindow::
end_frame(FrameMode mode, Thread *current_thread) {
end_frame_spam(mode);
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
if (mode == FM_render) {
// end_render_texture();
copy_to_textures();
}
_gsg->end_frame(current_thread);
if (mode == FM_render) {
trigger_flip();
if (_one_shot) {
prepare_for_deletion();
}
}
}
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsWindow::begin_flip
// Function: TinySDLGraphicsWindow::begin_flip
// Access: Public, Virtual
// Description: This function will be called within the draw thread
// after end_frame() has been called on all windows, to
@ -102,7 +127,7 @@ end_frame(FrameMode mode, Thread *current_thread) {
// end_flip(), to make it easier to flip all of the
// windows at the same time.
////////////////////////////////////////////////////////////////////
void TinyGraphicsWindow::
void TinySDLGraphicsWindow::
begin_flip() {
if (SDL_MUSTLOCK(_screen)) {
if (SDL_LockSurface(_screen) < 0) {
@ -120,7 +145,7 @@ begin_flip() {
}
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsWindow::process_events
// Function: TinySDLGraphicsWindow::process_events
// Access: Public, Virtual
// Description: Do whatever processing is necessary to ensure that
// the window responds to user events. Also, honor any
@ -129,7 +154,7 @@ begin_flip() {
// This function is called only within the window
// thread.
////////////////////////////////////////////////////////////////////
void TinyGraphicsWindow::
void TinySDLGraphicsWindow::
process_events() {
GraphicsWindow::process_events();
@ -195,7 +220,7 @@ process_events() {
}
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsWindow::set_properties_now
// Function: TinySDLGraphicsWindow::set_properties_now
// Access: Public, Virtual
// Description: Applies the requested set of properties to the
// window, if possible, for instance to request a change
@ -211,7 +236,7 @@ process_events() {
// derived classes to implement extensions to this
// function.
////////////////////////////////////////////////////////////////////
void TinyGraphicsWindow::
void TinySDLGraphicsWindow::
set_properties_now(WindowProperties &properties) {
GraphicsWindow::set_properties_now(properties);
if (!properties.is_any_specified()) {
@ -221,25 +246,25 @@ set_properties_now(WindowProperties &properties) {
}
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsWindow::close_window
// Function: TinySDLGraphicsWindow::close_window
// Access: Protected, Virtual
// Description: Closes the window right now. Called from the window
// thread.
////////////////////////////////////////////////////////////////////
void TinyGraphicsWindow::
void TinySDLGraphicsWindow::
close_window() {
glClose();
GraphicsWindow::close_window();
}
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsWindow::open_window
// Function: TinySDLGraphicsWindow::open_window
// Access: Protected, Virtual
// Description: Opens the window right now. Called from the window
// thread. Returns true if the window is successfully
// opened, or false if there was a problem.
////////////////////////////////////////////////////////////////////
bool TinyGraphicsWindow::
bool TinySDLGraphicsWindow::
open_window() {
// GSG Creation/Initialization
@ -278,7 +303,7 @@ open_window() {
return false;
}
glInit(_frame_buffer);
tinygsg->_current_frame_buffer = _frame_buffer;
// Now that we have made the context current to a window, we can
// reset the GSG state if this is the first time it has been used.
@ -290,12 +315,12 @@ open_window() {
}
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsWindow::create_frame_buffer
// Function: TinySDLGraphicsWindow::create_frame_buffer
// Access: Private
// Description: Creates a suitable frame buffer for the current
// window size.
////////////////////////////////////////////////////////////////////
void TinyGraphicsWindow::
void TinySDLGraphicsWindow::
create_frame_buffer() {
if (_frame_buffer != NULL) {
ZB_close(_frame_buffer);
@ -329,12 +354,12 @@ create_frame_buffer() {
}
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsWindow::get_keyboard_button
// Function: TinySDLGraphicsWindow::get_keyboard_button
// Access: Private, Static
// Description: Maps from an SDL keysym to the corresponding Panda
// ButtonHandle.
////////////////////////////////////////////////////////////////////
ButtonHandle TinyGraphicsWindow::
ButtonHandle TinySDLGraphicsWindow::
get_keyboard_button(SDLKey sym) {
switch (sym) {
case SDLK_BACKSPACE: return KeyboardButton::backspace();
@ -478,12 +503,12 @@ get_keyboard_button(SDLKey sym) {
}
////////////////////////////////////////////////////////////////////
// Function: TinyGraphicsWindow::get_mouse_button
// Function: TinySDLGraphicsWindow::get_mouse_button
// Access: Private, Static
// Description: Maps from an SDL mouse button index to the
// corresponding Panda ButtonHandle.
////////////////////////////////////////////////////////////////////
ButtonHandle TinyGraphicsWindow::
ButtonHandle TinySDLGraphicsWindow::
get_mouse_button(Uint8 button) {
switch (button) {
case SDL_BUTTON_LEFT:

View File

@ -1,4 +1,4 @@
// Filename: tinyGraphicsWindow.h
// Filename: tinySDLGraphicsWindow.h
// Created by: drose (24Apr08)
//
////////////////////////////////////////////////////////////////////
@ -16,12 +16,12 @@
//
////////////////////////////////////////////////////////////////////
#ifndef TINYGRAPHICSWINDOW_H
#define TINYGRAPHICSWINDOW_H
#ifndef TINYSDLGRAPHICSWINDOW_H
#define TINYSDLGRAPHICSWINDOW_H
#include "pandabase.h"
#include "tinyGraphicsPipe.h"
#include "tinySDLGraphicsPipe.h"
#include "graphicsWindow.h"
#include "buttonHandle.h"
@ -31,20 +31,19 @@ extern "C" {
}
////////////////////////////////////////////////////////////////////
// Class : TinyGraphicsWindow
// Description : An interface to TinySDGL (an implementation of TinyGL
// over SDL).
// Class : TinySDLGraphicsWindow
// Description : This graphics window class is implemented via SDL.
////////////////////////////////////////////////////////////////////
class TinyGraphicsWindow : public GraphicsWindow {
class TinySDLGraphicsWindow : public GraphicsWindow {
public:
TinyGraphicsWindow(GraphicsPipe *pipe,
const string &name,
const FrameBufferProperties &fb_prop,
const WindowProperties &win_prop,
int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host);
virtual ~TinyGraphicsWindow();
TinySDLGraphicsWindow(GraphicsPipe *pipe,
const string &name,
const FrameBufferProperties &fb_prop,
const WindowProperties &win_prop,
int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host);
virtual ~TinySDLGraphicsWindow();
virtual bool begin_frame(FrameMode mode, Thread *current_thread);
virtual void end_frame(FrameMode mode, Thread *current_thread);
@ -74,7 +73,7 @@ public:
}
static void init_type() {
GraphicsWindow::init_type();
register_type(_type_handle, "TinyGraphicsWindow",
register_type(_type_handle, "TinySDLGraphicsWindow",
GraphicsWindow::get_class_type());
}
virtual TypeHandle get_type() const {
@ -86,6 +85,6 @@ private:
static TypeHandle _type_handle;
};
#include "tinyGraphicsWindow.I"
#include "tinySDLGraphicsWindow.I"
#endif

View File

@ -0,0 +1,76 @@
// Filename: tinyXGraphicsPipe.I
// Created by: drose (03May08)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: TinyXGraphicsPipe::get_display
// Access: Public
// Description: Returns a pointer to the X display associated with
// the pipe: the display on which to create the windows.
////////////////////////////////////////////////////////////////////
INLINE Display *TinyXGraphicsPipe::
get_display() const {
return _display;
}
////////////////////////////////////////////////////////////////////
// Function: TinyXGraphicsPipe::get_screen
// Access: Public
// Description: Returns the X screen number associated with the pipe.
////////////////////////////////////////////////////////////////////
INLINE int TinyXGraphicsPipe::
get_screen() const {
return _screen;
}
////////////////////////////////////////////////////////////////////
// Function: TinyXGraphicsPipe::get_root
// Access: Public
// Description: Returns the handle to the root window on the pipe's
// display.
////////////////////////////////////////////////////////////////////
INLINE Window TinyXGraphicsPipe::
get_root() const {
return _root;
}
////////////////////////////////////////////////////////////////////
// Function: TinyXGraphicsPipe::get_im
// Access: Public
// Description: Returns the input method opened for the pipe, or NULL
// if the input method could not be opened for some
// reason.
////////////////////////////////////////////////////////////////////
INLINE XIM TinyXGraphicsPipe::
get_im() const {
return _im;
}
////////////////////////////////////////////////////////////////////
// Function: TinyXGraphicsPipe::get_hidden_cursor
// Access: Public
// Description: Returns an invisible Cursor suitable for assigning to
// windows that have the cursor_hidden property set.
////////////////////////////////////////////////////////////////////
INLINE Cursor TinyXGraphicsPipe::
get_hidden_cursor() {
if (_hidden_cursor == None) {
make_hidden_cursor();
}
return _hidden_cursor;
}

View File

@ -0,0 +1,337 @@
// Filename: tinyXGraphicsPipe.cxx
// Created by: drose (03May08)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "pandabase.h"
#ifdef IS_LINUX
#include "tinyXGraphicsPipe.h"
#include "tinyXGraphicsWindow.h"
#include "tinyGraphicsStateGuardian.h"
#include "config_tinydisplay.h"
#include "frameBufferProperties.h"
TypeHandle TinyXGraphicsPipe::_type_handle;
bool TinyXGraphicsPipe::_error_handlers_installed = false;
TinyXGraphicsPipe::ErrorHandlerFunc *TinyXGraphicsPipe::_prev_error_handler;
TinyXGraphicsPipe::IOErrorHandlerFunc *TinyXGraphicsPipe::_prev_io_error_handler;
ReMutex TinyXGraphicsPipe::_x_mutex;
////////////////////////////////////////////////////////////////////
// Function: TinyXGraphicsPipe::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
TinyXGraphicsPipe::
TinyXGraphicsPipe(const string &display) {
string display_spec = display;
if (display_spec.empty()) {
display_spec = display_cfg;
}
if (display_spec.empty()) {
display_spec = ExecutionEnvironment::get_environment_variable("DISPLAY");
}
if (display_spec.empty()) {
display_spec = ":0.0";
}
// The X docs say we should do this to get international character
// support from the keyboard.
setlocale(LC_ALL, "");
// But it's important that we use the "C" locale for numeric
// formatting, since all of the internal Panda code assumes this--we
// need a decimal point to mean a decimal point.
setlocale(LC_NUMERIC, "C");
_is_valid = false;
_supported_types = OT_window | OT_buffer | OT_texture_buffer;
_display = NULL;
_screen = 0;
_root = (Window)NULL;
_im = (XIM)NULL;
_hidden_cursor = None;
install_error_handlers();
_display = XOpenDisplay(display_spec.c_str());
if (!_display) {
tinydisplay_cat.error()
<< "Could not open display \"" << display_spec << "\".\n";
return;
}
if (!XSupportsLocale()) {
tinydisplay_cat.warning()
<< "X does not support locale " << setlocale(LC_ALL, NULL) << "\n";
}
XSetLocaleModifiers("");
_screen = DefaultScreen(_display);
_root = RootWindow(_display, _screen);
_display_width = DisplayWidth(_display, _screen);
_display_height = DisplayHeight(_display, _screen);
_is_valid = true;
// Connect to an input method for supporting international text
// entry.
_im = XOpenIM(_display, NULL, NULL, NULL);
if (_im == (XIM)NULL) {
tinydisplay_cat.warning()
<< "Couldn't open input method.\n";
}
// What styles does the current input method support?
/*
XIMStyles *im_supported_styles;
XGetIMValues(_im, XNQueryInputStyle, &im_supported_styles, NULL);
for (int i = 0; i < im_supported_styles->count_styles; i++) {
XIMStyle style = im_supported_styles->supported_styles[i];
cerr << "style " << i << ". " << hex << style << dec << "\n";
}
XFree(im_supported_styles);
*/
// Get some X atom numbers.
_wm_delete_window = XInternAtom(_display, "WM_DELETE_WINDOW", false);
_net_wm_window_type = XInternAtom(_display, "_NET_WM_WINDOW_TYPE", false);
_net_wm_window_type_splash = XInternAtom(_display, "_NET_WM_WINDOW_TYPE_SPLASH", false);
_net_wm_window_type_fullscreen = XInternAtom(_display, "_NET_WM_WINDOW_TYPE_FULLSCREEN", false);
_net_wm_state = XInternAtom(_display, "_NET_WM_STATE", false);
_net_wm_state_fullscreen = XInternAtom(_display, "_NET_WM_STATE_FULLSCREEN", false);
_net_wm_state_above = XInternAtom(_display, "_NET_WM_STATE_ABOVE", false);
_net_wm_state_below = XInternAtom(_display, "_NET_WM_STATE_BELOW", false);
_net_wm_state_add = XInternAtom(_display, "_NET_WM_STATE_ADD", false);
_net_wm_state_remove = XInternAtom(_display, "_NET_WM_STATE_REMOVE", false);
}
////////////////////////////////////////////////////////////////////
// Function: TinyXGraphicsPipe::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
TinyXGraphicsPipe::
~TinyXGraphicsPipe() {
release_hidden_cursor();
if (_im) {
XCloseIM(_im);
}
if (_display) {
XCloseDisplay(_display);
}
}
////////////////////////////////////////////////////////////////////
// Function: TinyXGraphicsPipe::get_interface_name
// Access: Published, Virtual
// Description: Returns the name of the rendering interface
// associated with this GraphicsPipe. This is used to
// present to the user to allow him/her to choose
// between several possible GraphicsPipes available on a
// particular platform, so the name should be meaningful
// and unique for a given platform.
////////////////////////////////////////////////////////////////////
string TinyXGraphicsPipe::
get_interface_name() const {
return "OpenGL";
}
////////////////////////////////////////////////////////////////////
// Function: TinyXGraphicsPipe::pipe_constructor
// Access: Public, Static
// Description: This function is passed to the GraphicsPipeSelection
// object to allow the user to make a default
// TinyXGraphicsPipe.
////////////////////////////////////////////////////////////////////
PT(GraphicsPipe) TinyXGraphicsPipe::
pipe_constructor() {
return new TinyXGraphicsPipe;
}
////////////////////////////////////////////////////////////////////
// Function: TinyXGraphicsPipe::get_preferred_window_thread
// Access: Public, Virtual
// Description: Returns an indication of the thread in which this
// GraphicsPipe requires its window processing to be
// performed: typically either the app thread (e.g. X)
// or the draw thread (Windows).
////////////////////////////////////////////////////////////////////
GraphicsPipe::PreferredWindowThread
TinyXGraphicsPipe::get_preferred_window_thread() const {
// Actually, since we're creating the graphics context in
// open_window() now, it appears we need to ensure the open_window()
// call is performed in the draw thread for now, even though X wants
// all of its calls to be single-threaded.
// This means that all X windows may have to be handled by the same
// draw thread, which we didn't intend (though the global _x_mutex
// may allow them to be technically served by different threads,
// even though the actual X calls will be serialized). There might
// be a better way.
return PWT_draw;
}
////////////////////////////////////////////////////////////////////
// Function: TinyXGraphicsPipe::make_output
// Access: Protected, Virtual
// Description: Creates a new window on the pipe, if possible.
////////////////////////////////////////////////////////////////////
PT(GraphicsOutput) TinyXGraphicsPipe::
make_output(const string &name,
const FrameBufferProperties &fb_prop,
const WindowProperties &win_prop,
int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host,
int retry,
bool &precertify) {
if (!_is_valid) {
return NULL;
}
TinyGraphicsStateGuardian *tinygsg = 0;
if (gsg != 0) {
DCAST_INTO_R(tinygsg, gsg, NULL);
}
// First thing to try: a TinyXGraphicsWindow
if (retry == 0) {
if (((flags&BF_require_parasite)!=0)||
((flags&BF_refuse_window)!=0)||
((flags&BF_resizeable)!=0)||
((flags&BF_size_track_host)!=0)||
((flags&BF_rtt_cumulative)!=0)||
((flags&BF_can_bind_color)!=0)||
((flags&BF_can_bind_every)!=0)) {
return NULL;
}
return new TinyXGraphicsWindow(this, name, fb_prop, win_prop,
flags, gsg, host);
}
// Nothing else left to try.
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: TinyXGraphicsPipe::make_hidden_cursor
// Access: Private
// Description: Called once to make an invisible Cursor for return
// from get_hidden_cursor().
////////////////////////////////////////////////////////////////////
void TinyXGraphicsPipe::
make_hidden_cursor() {
nassertv(_hidden_cursor == None);
unsigned int x_size, y_size;
XQueryBestCursor(_display, _root, 1, 1, &x_size, &y_size);
Pixmap empty = XCreatePixmap(_display, _root, x_size, y_size, 1);
XColor black;
memset(&black, 0, sizeof(black));
_hidden_cursor = XCreatePixmapCursor(_display, empty, empty,
&black, &black, x_size, y_size);
XFreePixmap(_display, empty);
}
////////////////////////////////////////////////////////////////////
// Function: TinyXGraphicsPipe::release_hidden_cursor
// Access: Private
// Description: Called once to release the invisible cursor created
// by make_hidden_cursor().
////////////////////////////////////////////////////////////////////
void TinyXGraphicsPipe::
release_hidden_cursor() {
if (_hidden_cursor != None) {
XFreeCursor(_display, _hidden_cursor);
_hidden_cursor = None;
}
}
////////////////////////////////////////////////////////////////////
// Function: TinyXGraphicsPipe::install_error_handlers
// Access: Private, Static
// Description: Installs new Xlib error handler functions if this is
// the first time this function has been called. These
// error handler functions will attempt to reduce Xlib's
// annoying tendency to shut down the client at the
// first error. Unfortunately, it is difficult to play
// nice with the client if it has already installed its
// own error handlers.
////////////////////////////////////////////////////////////////////
void TinyXGraphicsPipe::
install_error_handlers() {
if (_error_handlers_installed) {
return;
}
_prev_error_handler = (ErrorHandlerFunc *)XSetErrorHandler(error_handler);
_prev_io_error_handler = (IOErrorHandlerFunc *)XSetIOErrorHandler(io_error_handler);
_error_handlers_installed = true;
}
////////////////////////////////////////////////////////////////////
// Function: TinyXGraphicsPipe::error_handler
// Access: Private, Static
// Description: This function is installed as the error handler for a
// non-fatal Xlib error.
////////////////////////////////////////////////////////////////////
int TinyXGraphicsPipe::
error_handler(Display *display, XErrorEvent *error) {
static const int msg_len = 80;
char msg[msg_len];
XGetErrorText(display, error->error_code, msg, msg_len);
tinydisplay_cat.error()
<< msg << "\n";
if (x_error_abort) {
abort();
}
// We return to allow the application to continue running, unlike
// the default X error handler which exits.
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: TinyXGraphicsPipe::io_error_handler
// Access: Private, Static
// Description: This function is installed as the error handler for a
// fatal Xlib error.
////////////////////////////////////////////////////////////////////
int TinyXGraphicsPipe::
io_error_handler(Display *display) {
tinydisplay_cat.fatal()
<< "X fatal error on display " << (void *)display << "\n";
// Unfortunately, we can't continue from this function, even if we
// promise never to use X again. We're supposed to terminate
// without returning, and if we do return, the caller will exit
// anyway. Sigh. Very poor design on X's part.
return 0;
}
#endif // IS_LINUX

View File

@ -0,0 +1,145 @@
// Filename: tinyXGraphicsPipe.h
// Created by: drose (03May08)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef TINYXGRAPHICSPIPE_H
#define TINYXGRAPHICSPIPE_H
#include "pandabase.h"
#ifdef IS_LINUX
#include "graphicsWindow.h"
#include "graphicsPipe.h"
#include "tinyGraphicsStateGuardian.h"
#include "pmutex.h"
#include "reMutex.h"
class FrameBufferProperties;
#ifdef CPPPARSER
// A simple hack so interrogate can parse this file.
typedef int Display;
typedef int Window;
typedef int XErrorEvent;
typedef int XVisualInfo;
typedef int Atom;
typedef int Cursor;
typedef int XIM;
typedef int XIC;
#else
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#endif // CPPPARSER
////////////////////////////////////////////////////////////////////
// Class : TinyXGraphicsPipe
// Description : This graphics pipe represents the interface for
// creating OpenGL graphics windows on an X-based
// (e.g. Unix) client.
////////////////////////////////////////////////////////////////////
class TinyXGraphicsPipe : public GraphicsPipe {
public:
TinyXGraphicsPipe(const string &display = string());
virtual ~TinyXGraphicsPipe();
virtual string get_interface_name() const;
static PT(GraphicsPipe) pipe_constructor();
INLINE Display *get_display() const;
INLINE int get_screen() const;
INLINE Window get_root() const;
INLINE XIM get_im() const;
INLINE Cursor get_hidden_cursor();
public:
virtual PreferredWindowThread get_preferred_window_thread() const;
public:
// Atom specifications.
Atom _wm_delete_window;
Atom _net_wm_window_type;
Atom _net_wm_window_type_splash;
Atom _net_wm_window_type_fullscreen;
Atom _net_wm_state;
Atom _net_wm_state_fullscreen;
Atom _net_wm_state_above;
Atom _net_wm_state_below;
Atom _net_wm_state_add;
Atom _net_wm_state_remove;
protected:
virtual PT(GraphicsOutput) make_output(const string &name,
const FrameBufferProperties &fb_prop,
const WindowProperties &win_prop,
int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host,
int retry,
bool &precertify);
private:
void make_hidden_cursor();
void release_hidden_cursor();
static void install_error_handlers();
static int error_handler(Display *display, XErrorEvent *error);
static int io_error_handler(Display *display);
Display *_display;
int _screen;
Window _root;
XIM _im;
Cursor _hidden_cursor;
typedef int ErrorHandlerFunc(Display *, XErrorEvent *);
typedef int IOErrorHandlerFunc(Display *);
static bool _error_handlers_installed;
static ErrorHandlerFunc *_prev_error_handler;
static IOErrorHandlerFunc *_prev_io_error_handler;
public:
// This Mutex protects any X library calls, which all have to be
// single-threaded.
static ReMutex _x_mutex;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
GraphicsPipe::init_type();
register_type(_type_handle, "TinyXGraphicsPipe",
GraphicsPipe::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#include "tinyXGraphicsPipe.I"
#endif // IS_LINUX
#endif

View File

@ -0,0 +1,18 @@
// Filename: tinyXGraphicsWindow.I
// Created by: drose (03May08)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,136 @@
// Filename: tinyXGraphicsWindow.h
// Created by: drose (03May08)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef TINYXGRAPHICSWINDOW_H
#define TINYXGRAPHICSWINDOW_H
#include "pandabase.h"
#ifdef IS_LINUX
#include "tinyXGraphicsPipe.h"
#include "graphicsWindow.h"
#include "buttonHandle.h"
////////////////////////////////////////////////////////////////////
// Class : TinyXGraphicsWindow
// Description : Opens a window on X11 to display the TinyGL software
// rendering.
////////////////////////////////////////////////////////////////////
class TinyXGraphicsWindow : public GraphicsWindow {
public:
TinyXGraphicsWindow(GraphicsPipe *pipe,
const string &name,
const FrameBufferProperties &fb_prop,
const WindowProperties &win_prop,
int flags,
GraphicsStateGuardian *gsg,
GraphicsOutput *host);
virtual ~TinyXGraphicsWindow();
virtual bool move_pointer(int device, int x, int y);
virtual bool begin_frame(FrameMode mode, Thread *current_thread);
virtual void end_frame(FrameMode mode, Thread *current_thread);
virtual void begin_flip();
virtual void process_events();
virtual void set_properties_now(WindowProperties &properties);
protected:
virtual void close_window();
virtual bool open_window();
private:
void set_wm_properties(const WindowProperties &properties,
bool already_mapped);
void setup_colormap(XVisualInfo *visual);
void handle_keystroke(XKeyEvent &event);
void handle_keypress(XKeyEvent &event);
void handle_keyrelease(XKeyEvent &event);
ButtonHandle get_button(XKeyEvent &key_event);
ButtonHandle get_mouse_button(XButtonEvent &button_event);
static Bool check_event(Display *display, XEvent *event, char *arg);
void open_raw_mice();
void poll_raw_mice();
void create_frame_buffer();
void create_ximage();
private:
ZBuffer *_frame_buffer;
int _pitch;
XImage *_ximage;
Display *_display;
int _screen;
Visual *_visual;
int _depth;
int _bytes_per_pixel;
Window _xwindow;
Colormap _colormap;
XIC _ic;
GC _gc;
long _event_mask;
bool _awaiting_configure;
Atom _wm_delete_window;
Atom _net_wm_window_type;
Atom _net_wm_window_type_splash;
Atom _net_wm_window_type_fullscreen;
Atom _net_wm_state;
Atom _net_wm_state_fullscreen;
Atom _net_wm_state_above;
Atom _net_wm_state_below;
Atom _net_wm_state_add;
Atom _net_wm_state_remove;
struct MouseDeviceInfo {
int _fd;
int _input_device_index;
string _io_buffer;
};
pvector<MouseDeviceInfo> _mouse_device_info;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
GraphicsWindow::init_type();
register_type(_type_handle, "TinyXGraphicsWindow",
GraphicsWindow::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};
#include "tinyXGraphicsWindow.I"
#endif // IS_LINUX
#endif

View File

@ -1,6 +1,6 @@
/*
* Z buffer: 16 bits Z / 16 bits color
* Z buffer: 16 bits Z / 32 bits color
*
*/
#include <stdlib.h>
@ -161,6 +161,33 @@ static void ZB_copyFrameBuffer5R6G5B(ZBuffer * zb,
}
}
/* XXX: not optimized */
static void ZB_copyFrameBufferRGB24(ZBuffer * zb,
void *buf, int linesize)
{
PIXEL *q;
unsigned char *p, *p1;
int y, n;
fprintf(stderr, "copyFrameBufferRGB24\n");
q = zb->pbuf;
p1 = (unsigned char *) buf;
for (y = 0; y < zb->ysize; y++) {
p = p1;
n = zb->xsize;
do {
p[0] = q[0];
p[1] = q[1];
p[2] = q[2];
q += 4;
p += 3;
} while (--n > 0);
p1 += linesize;
}
}
void ZB_copyFrameBuffer(ZBuffer * zb, void *buf,
int linesize)
{
@ -170,6 +197,11 @@ void ZB_copyFrameBuffer(ZBuffer * zb, void *buf,
ZB_copyFrameBuffer5R6G5B(zb, buf, linesize);
break;
#endif
#ifdef TGL_FEATURE_24_BITS
case ZB_MODE_RGB24:
ZB_copyFrameBufferRGB24(zb, buf, linesize);
break;
#endif
#ifdef TGL_FEATURE_32_BITS
case ZB_MODE_RGBA:
ZB_copyBuffer(zb, buf, linesize);