00001
00002
00003
00004 #include "pbuffer.h"
00005
00006
00007 #ifdef GLX_SGIX_fbconfig
00008 const int gl::pixel_buffer::VISUAL_ATTRIBUTES_8BPP[] = {
00009 GLX_DRAWABLE_TYPE_SGIX, GLX_PBUFFER_BIT_SGIX,
00010 GLX_RENDER_TYPE_SGIX, GLX_RGBA_BIT_SGIX,
00011 GLX_DOUBLEBUFFER, GL_FALSE,
00012 GLX_RED_SIZE, 2,
00013 GLX_GREEN_SIZE, 2,
00014 GLX_BLUE_SIZE, 2,
00015 GLX_ALPHA_SIZE, 2,
00016 None
00017 };
00018
00019 const int gl::pixel_buffer::VISUAL_ATTRIBUTES_16BPP[] = {
00020 GLX_DRAWABLE_TYPE_SGIX, GLX_PBUFFER_BIT_SGIX,
00021 GLX_RENDER_TYPE_SGIX, GLX_RGBA_BIT_SGIX,
00022 GLX_DOUBLEBUFFER, GL_FALSE,
00023 GLX_RED_SIZE, 4,
00024 GLX_GREEN_SIZE, 4,
00025 GLX_BLUE_SIZE, 4,
00026 GLX_ALPHA_SIZE, 4,
00027 None,
00028 };
00029
00030 const int gl::pixel_buffer::VISUAL_ATTRIBUTES_24BPP[] = {
00031 GLX_DRAWABLE_TYPE_SGIX, GLX_PBUFFER_BIT_SGIX,
00032 GLX_RENDER_TYPE_SGIX, GLX_RGBA_BIT_SGIX,
00033 GLX_DOUBLEBUFFER, GL_FALSE,
00034 GLX_RED_SIZE, 6,
00035 GLX_GREEN_SIZE, 6,
00036 GLX_BLUE_SIZE, 6,
00037 GLX_ALPHA_SIZE, 6,
00038 None
00039 };
00040
00041 const int gl::pixel_buffer::VISUAL_ATTRIBUTES_32BPP[] = {
00042 GLX_DRAWABLE_TYPE_SGIX, GLX_PBUFFER_BIT_SGIX,
00043 GLX_RENDER_TYPE_SGIX, GLX_RGBA_BIT_SGIX,
00044 GLX_DOUBLEBUFFER, GL_FALSE,
00045 GLX_RED_SIZE, 8,
00046 GLX_GREEN_SIZE, 8,
00047 GLX_BLUE_SIZE, 8,
00048 GLX_ALPHA_SIZE, 8,
00049 None
00050 };
00051
00052 const int gl::pixel_buffer::PIXEL_BUFFER_ATTRIBUTES[] = {
00053 GLX_PRESERVED_CONTENTS_SGIX,
00054 None
00055 };
00056 #endif
00057
00058
00059
00060 bool gl::pixel_buffer::init(unsigned int w, unsigned int h, unsigned int bpp, GLXContext shared){
00061
00062
00063 if (m_initialized){
00064 set_error("Pixel buffer has already been initialized.");
00065 return false;
00066 }
00067
00068 #ifdef GLX_SGIX_fbconfig
00069 #ifdef GLX_SGIX_pbuffer
00070 int screen;
00071
00072
00073 if (w < 1)
00074 w = 1;
00075 if (h < 1)
00076 h = 1;
00077 if (bpp < 8)
00078 bpp = 8;
00079
00080
00081 if ((m_display = XOpenDisplay(NULL)) == NULL){
00082 set_error("Unable to open the X display.");
00083 return false;
00084 }
00085 screen = DefaultScreen(m_display);
00086
00087
00088 m_num_available_configs = 0;
00089 if (bpp < 16)
00090 m_available_configs = glXChooseFBConfigSGIX(m_display, screen, VISUAL_ATTRIBUTES_8BPP, &m_num_available_configs);
00091 else if (bpp < 24)
00092 m_available_configs = glXChooseFBConfigSGIX(m_display, screen, VISUAL_ATTRIBUTES_16BPP, &m_num_available_configs);
00093 else if (bpp < 32)
00094 m_available_configs = glXChooseFBConfigSGIX(m_display, screen, VISUAL_ATTRIBUTES_24BPP, &m_num_available_configs);
00095 else
00096 m_available_configs = glXChooseFBConfigSGIX(m_display, screen, VISUAL_ATTRIBUTES_32BPP, &m_num_available_configs);
00097 if (m_num_available_configs == 0){
00098 set_error("A framebuffer configuration with the chosen bit depth could not be found.");
00099 return false;
00100 }
00101
00102
00103 m_pixel_buffer = glXCreateGLXPbufferSGIX(m_display, m_available_configs[0], w, h, PIXEL_BUFFER_ATTRIBUTES);
00104 if (m_pixel_buffer == None){
00105 set_error("A pixel buffer could not be created.");
00106 return false;
00107 }
00108
00109
00110 GLuint texture_number;
00111 glGenTextures(1, &texture_number);
00112 m_texture.set(texture_number, w / h);
00113
00114
00115 m_pixel_buffer_context = glXCreateContextWithConfigSGIX(m_display, m_available_configs[0], GLX_RGBA_TYPE_SGIX,
00116 shared, GL_TRUE);
00117
00118
00119 m_width = w;
00120 m_height = h;
00121 m_bpp = bpp;
00122 m_initialized = true;
00123 return true;
00124 #endif
00125 #endif
00126 set_error("Pixel buffers are not supported on this machine.");
00127 return false;
00128 }
00129
00130
00131
00132 bool gl::pixel_buffer::init(unsigned int w, unsigned int h, unsigned int bpp, const int attributes[], GLXContext shared){
00133
00134
00135 if (m_initialized){
00136 set_error("Pixel buffer has already been initialized.");
00137 return false;
00138 }
00139
00140 #ifdef GLX_SGIX_fbconfig
00141 #ifdef GLX_SGIX_pbuffer
00142 int screen;
00143
00144
00145 if (w < 1)
00146 w = 1;
00147 if (h < 1)
00148 h = 1;
00149 if (bpp < 8)
00150 bpp = 8;
00151
00152
00153 if ((m_display = XOpenDisplay(NULL)) == NULL){
00154 set_error("Unable to open the X display.");
00155 return false;
00156 }
00157 screen = DefaultScreen(m_display);
00158
00159
00160 m_num_available_configs = 0;
00161 m_available_configs = glXChooseFBConfigSGIX(m_display, screen, attributes, &m_num_available_configs);
00162 if (m_num_available_configs == 0){
00163 set_error("A framebuffer configuration with the chosen attributes could not be found.");
00164 return false;
00165 }
00166
00167
00168 m_pixel_buffer = glXCreateGLXPbufferSGIX(m_display, m_available_configs[0], w, h, PIXEL_BUFFER_ATTRIBUTES);
00169 if (m_pixel_buffer == None){
00170 set_error("A pixel buffer could not be created.");
00171 return false;
00172 }
00173
00174
00175 GLuint texture_number;
00176 glGenTextures(1, &texture_number);
00177 m_texture.set(texture_number, (float)w/(float)h);
00178
00179
00180 m_pixel_buffer_context = glXCreateContextWithConfigSGIX(m_display, m_available_configs[0], GLX_RGBA_TYPE_SGIX,
00181 shared, GL_TRUE);
00182
00183
00184 m_width = w;
00185 m_height = h;
00186 m_bpp = bpp;
00187 m_initialized = true;
00188 return true;
00189 #endif
00190 #endif
00191 set_error("Pixel buffers are not supported on this machine.");
00192 return false;
00193 }
00194
00195
00196
00197 void gl::pixel_buffer::activate(void){
00198 #ifdef GLX_SGIX_fbconfig
00199 #ifdef GLX_SGIX_pbuffer
00200
00201 glXMakeContextCurrent(m_display, m_pixel_buffer, m_pixel_buffer, m_pixel_buffer_context);
00202 #endif
00203 #endif
00204 }
00205
00206
00207
00208 void gl::pixel_buffer::shutdown(void){
00209 if (m_initialized){
00210 #ifdef GLX_SGIX_fbconfig
00211 #ifdef GLX_SGIX_pbuffer
00212
00213 glXDestroyContext(m_display, m_pixel_buffer_context);
00214 m_pixel_buffer_context = NULL;
00215
00216
00217 glXDestroyGLXPbufferSGIX(m_display, m_pixel_buffer);
00218 #endif
00219 #endif
00220
00221 XCloseDisplay(m_display);
00222 m_display = NULL;
00223 m_initialized = false;
00224 }
00225 }