mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 17:35:34 -04:00
add GraphicsEngine::open_windows(), GLGraphicsStateGuardian::_edge_clamp
This commit is contained in:
parent
baea752ded
commit
587de59ae8
@ -86,7 +86,7 @@ const bool show_buffers = config_display.GetBool("show-buffers", false);
|
||||
// buffer. This may be desired if you know your graphics API does not
|
||||
// support render-directly-to-texture and you want to minimize
|
||||
// framebuffer memory.
|
||||
const bool prefer_parasite_buffer = config_display.GetBool("prefer-parasite-buffer", false);
|
||||
const bool prefer_parasite_buffer = config_display.GetBool("prefer-parasite-buffer", true);
|
||||
|
||||
// Set this true to make GraphicsOutput::make_render_texture() first
|
||||
// try to create a single-buffered offscreen buffer, before falling
|
||||
|
@ -503,6 +503,50 @@ render_frame() {
|
||||
_app_pcollector.start();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsEngine::open_windows
|
||||
// Access: Published
|
||||
// Description: Fully opens (or closes) any windows that have
|
||||
// recently been requested open or closed, without
|
||||
// rendering any frames. It is not necessary to call
|
||||
// this explicitly, since windows will be automatically
|
||||
// opened or closed when the next frame is rendered, but
|
||||
// you may call this if you want your windows now
|
||||
// without seeing a frame go by.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsEngine::
|
||||
open_windows() {
|
||||
MutexHolder holder(_lock);
|
||||
|
||||
if (!_windows_sorted) {
|
||||
do_resort_windows();
|
||||
}
|
||||
|
||||
_app.do_windows(this);
|
||||
|
||||
Threads::const_iterator ti;
|
||||
for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
|
||||
RenderThread *thread = (*ti).second;
|
||||
if (thread->_thread_state == TS_wait) {
|
||||
thread->_thread_state = TS_do_windows;
|
||||
thread->_cv.signal();
|
||||
}
|
||||
thread->_cv_mutex.release();
|
||||
}
|
||||
|
||||
// We do it twice, to allow both cull and draw to process the
|
||||
// window.
|
||||
for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
|
||||
RenderThread *thread = (*ti).second;
|
||||
if (thread->_thread_state == TS_wait) {
|
||||
thread->_thread_state = TS_do_windows;
|
||||
thread->_cv.signal();
|
||||
}
|
||||
thread->_cv_mutex.release();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsEngine::sync_frame
|
||||
// Access: Published
|
||||
@ -747,6 +791,24 @@ cull_bin_draw(GraphicsStateGuardian *gsg, DisplayRegion *dr) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsEngine::make_contexts
|
||||
// Access: Private
|
||||
// Description: Called in the draw thread, this calls make_context()
|
||||
// on each window on the list to guarantee its graphics
|
||||
// context gets created.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsEngine::
|
||||
make_contexts(const GraphicsEngine::Windows &wlist) {
|
||||
Windows::const_iterator wi;
|
||||
for (wi = wlist.begin(); wi != wlist.end(); ++wi) {
|
||||
GraphicsOutput *win = (*wi);
|
||||
if (win->needs_context()) {
|
||||
win->make_context();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsEngine::process_events
|
||||
// Access: Private
|
||||
@ -1321,6 +1383,25 @@ do_frame(GraphicsEngine *engine) {
|
||||
do_callbacks(CB_post_frame);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsEngine::WindowRenderer::do_windows
|
||||
// Access: Public
|
||||
// Description: Attempts to fully open or close any windows or
|
||||
// buffers associated with this thread, but does not
|
||||
// otherwise perform any rendering. (Normally, this
|
||||
// step is handled during do_frame(); call this method
|
||||
// only if you want these things to open immediately.)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsEngine::WindowRenderer::
|
||||
do_windows(GraphicsEngine *engine) {
|
||||
MutexHolder holder(_wl_lock);
|
||||
|
||||
engine->process_events(_window);
|
||||
|
||||
engine->make_contexts(_cdraw);
|
||||
engine->make_contexts(_draw);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsEngine::WindowRenderer::do_flip
|
||||
// Access: Public
|
||||
@ -1542,6 +1623,13 @@ thread_main() {
|
||||
_thread_state = TS_wait;
|
||||
break;
|
||||
|
||||
case TS_do_windows:
|
||||
do_windows(_engine);
|
||||
do_pending(_engine);
|
||||
do_release(_engine);
|
||||
_thread_state = TS_wait;
|
||||
break;
|
||||
|
||||
case TS_terminate:
|
||||
do_pending(_engine);
|
||||
do_close(_engine);
|
||||
|
@ -88,6 +88,7 @@ PUBLISHED:
|
||||
bool is_empty() const;
|
||||
|
||||
void render_frame();
|
||||
void open_windows();
|
||||
void sync_frame();
|
||||
void flip_frame();
|
||||
|
||||
@ -100,6 +101,7 @@ public:
|
||||
TS_do_frame,
|
||||
TS_do_flip,
|
||||
TS_do_release,
|
||||
TS_do_windows,
|
||||
TS_terminate
|
||||
};
|
||||
|
||||
@ -139,6 +141,7 @@ private:
|
||||
|
||||
void cull_bin_draw(const Windows &wlist);
|
||||
void cull_bin_draw(GraphicsStateGuardian *gsg, DisplayRegion *dr);
|
||||
void make_contexts(const Windows &wlist);
|
||||
|
||||
void process_events(const Windows &wlist);
|
||||
void flip_windows(const Windows &wlist);
|
||||
@ -171,6 +174,7 @@ private:
|
||||
void remove_window(GraphicsOutput *window);
|
||||
void resort_windows();
|
||||
void do_frame(GraphicsEngine *engine);
|
||||
void do_windows(GraphicsEngine *engine);
|
||||
void do_flip(GraphicsEngine *engine);
|
||||
void do_release(GraphicsEngine *engine);
|
||||
void do_close(GraphicsEngine *engine);
|
||||
|
@ -160,17 +160,6 @@ is_valid() const {
|
||||
return _is_valid;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsOutput::flip_ready
|
||||
// Access: Published
|
||||
// Description: Returns true if a frame has been rendered and needs
|
||||
// to be flipped, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GraphicsOutput::
|
||||
flip_ready() const {
|
||||
return _flip_ready;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsOutput::get_sort
|
||||
// Access: Published
|
||||
@ -243,6 +232,28 @@ win_display_regions_changed() {
|
||||
_display_regions_stale = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsOutput::flip_ready
|
||||
// Access: Public
|
||||
// Description: Returns true if a frame has been rendered and needs
|
||||
// to be flipped, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GraphicsOutput::
|
||||
flip_ready() const {
|
||||
return _flip_ready;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsOutput::needs_context
|
||||
// Access: Public
|
||||
// Description: Returns true if make_context() still needs to be
|
||||
// called, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GraphicsOutput::
|
||||
needs_context() const {
|
||||
return _needs_context;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsOutput::operator <
|
||||
// Access: Public
|
||||
|
@ -52,6 +52,7 @@ GraphicsOutput(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
|
||||
_is_valid = false;
|
||||
_copy_texture = false;
|
||||
_flip_ready = false;
|
||||
_needs_context = true;
|
||||
_sort = 0;
|
||||
|
||||
int mode = gsg->get_properties().get_frame_buffer_mode();
|
||||
@ -365,7 +366,15 @@ make_texture_buffer(const string &name, int x_size, int y_size) {
|
||||
if (sb_gsg != (GraphicsStateGuardian *)NULL) {
|
||||
buffer = engine->make_buffer(sb_gsg, name, sort, x_size, y_size, true);
|
||||
if (buffer != (GraphicsOutput *)NULL) {
|
||||
return buffer;
|
||||
// Check the buffer for goodness.
|
||||
engine->open_windows();
|
||||
if (buffer->is_valid()) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// No good; delete the buffer and keep trying.
|
||||
engine->remove_window(buffer);
|
||||
buffer = (GraphicsOutput *)NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -376,7 +385,13 @@ make_texture_buffer(const string &name, int x_size, int y_size) {
|
||||
// source window is double-buffered.
|
||||
buffer = engine->make_buffer(gsg, name, sort, x_size, y_size, true);
|
||||
if (buffer != (GraphicsOutput *)NULL) {
|
||||
return buffer;
|
||||
engine->open_windows();
|
||||
if (buffer->is_valid()) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
engine->remove_window(buffer);
|
||||
buffer = (GraphicsOutput *)NULL;
|
||||
}
|
||||
|
||||
// Looks like we have to settle for a parasite buffer.
|
||||
@ -492,6 +507,12 @@ begin_frame() {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (needs_context()) {
|
||||
if (!make_context()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Okay, we already have a GSG, so activate it.
|
||||
make_current();
|
||||
return _gsg->begin_frame();
|
||||
@ -550,6 +571,22 @@ end_frame() {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsOutput::make_context
|
||||
// Access: Public, Virtual
|
||||
// Description: If _needs_context is true, this will be called
|
||||
// in the draw thread prior to rendering into the
|
||||
// window. It should attempt to create a graphics
|
||||
// context, and return true if successful, false
|
||||
// otherwise. If it returns false the window will be
|
||||
// considered failed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsOutput::
|
||||
make_context() {
|
||||
_needs_context = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsOutput::make_current
|
||||
// Access: Public, Virtual
|
||||
|
@ -80,7 +80,6 @@ PUBLISHED:
|
||||
INLINE int get_y_size() const;
|
||||
INLINE bool has_size() const;
|
||||
INLINE bool is_valid() const;
|
||||
INLINE bool flip_ready() const;
|
||||
|
||||
virtual bool is_active() const;
|
||||
|
||||
@ -109,6 +108,8 @@ public:
|
||||
public:
|
||||
// These are not intended to be called directly by the user.
|
||||
INLINE void win_display_regions_changed();
|
||||
INLINE bool needs_context() const;
|
||||
INLINE bool flip_ready() const;
|
||||
|
||||
INLINE bool operator < (const GraphicsOutput &other) const;
|
||||
|
||||
@ -129,6 +130,7 @@ public:
|
||||
|
||||
// This method is called in the draw thread prior to issuing any
|
||||
// drawing commands for the window.
|
||||
virtual bool make_context();
|
||||
virtual void make_current();
|
||||
virtual void release_gsg();
|
||||
|
||||
@ -151,6 +153,7 @@ protected:
|
||||
PT(Texture) _texture;
|
||||
bool _copy_texture;
|
||||
bool _flip_ready;
|
||||
bool _needs_context;
|
||||
|
||||
private:
|
||||
INLINE void determine_display_regions() const;
|
||||
|
@ -64,6 +64,7 @@ ParasiteBuffer(GraphicsOutput *host, const string &name,
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ParasiteBuffer::
|
||||
~ParasiteBuffer() {
|
||||
_is_valid = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -615,14 +615,14 @@ enable_multisample(bool val) {
|
||||
if (_multisample_enabled != val) {
|
||||
_multisample_enabled = val;
|
||||
if (val) {
|
||||
#ifdef GL_MULTISAMPLE_SGIS
|
||||
GLP(Enable)(GL_MULTISAMPLE_SGIS);
|
||||
#endif
|
||||
if (_supports_multisample) {
|
||||
GLP(Enable)(GL_MULTISAMPLE);
|
||||
}
|
||||
GLP(Hint)(GL_POINT_SMOOTH_HINT, GL_NICEST);
|
||||
} else {
|
||||
#ifdef GL_MULTISAMPLE_SGIS
|
||||
GLP(Disable)(GL_MULTISAMPLE_SGIS);
|
||||
#endif
|
||||
if (_supports_multisample) {
|
||||
GLP(Disable)(GL_MULTISAMPLE);
|
||||
}
|
||||
GLP(Hint)(GL_POINT_SMOOTH_HINT, GL_FASTEST);
|
||||
}
|
||||
}
|
||||
|
@ -380,6 +380,8 @@ reset() {
|
||||
_current_projection_mat = LMatrix4f::ident_mat();
|
||||
_projection_mat_stack_count = 0;
|
||||
|
||||
report_my_gl_errors();
|
||||
|
||||
// Make sure the GL state matches all of our initial attribute
|
||||
// states.
|
||||
CPT(RenderAttrib) dta = DepthTestAttrib::make(DepthTestAttrib::M_less);
|
||||
@ -419,7 +421,7 @@ reset() {
|
||||
// Output the vendor and version strings.
|
||||
show_gl_string("GL_VENDOR", GL_VENDOR);
|
||||
show_gl_string("GL_RENDERER", GL_RENDERER);
|
||||
show_gl_string("GL_VERSION", GL_VERSION);
|
||||
get_gl_version();
|
||||
|
||||
// Save the extensions tokens.
|
||||
save_extensions((const char *)glGetString(GL_EXTENSIONS));
|
||||
@ -427,6 +429,14 @@ reset() {
|
||||
report_extensions();
|
||||
|
||||
_supports_bgr = has_extension("GL_EXT_bgra");
|
||||
_supports_multisample = has_extension("GL_ARB_multisample");
|
||||
|
||||
_edge_clamp = GL_CLAMP;
|
||||
if (has_extension("GL_SGIS_texture_edge_clamp") ||
|
||||
is_at_least_version(1, 2)) {
|
||||
_edge_clamp = GL_CLAMP_TO_EDGE;
|
||||
}
|
||||
|
||||
_error_count = 0;
|
||||
|
||||
report_my_gl_errors();
|
||||
@ -2663,6 +2673,47 @@ show_gl_string(const string &name, GLenum id) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::get_gl_version
|
||||
// Access: Protected
|
||||
// Description: Queries the runtime version of OpenGL in use.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
get_gl_version() {
|
||||
_gl_version_major = 0;
|
||||
_gl_version_minor = 0;
|
||||
_gl_version_release = 0;
|
||||
|
||||
const GLubyte *text = GLP(GetString)(GL_VERSION);
|
||||
if (text == (const GLubyte *)NULL) {
|
||||
GLCAT.debug()
|
||||
<< "Unable to query GL_VERSION\n";
|
||||
} else {
|
||||
string input((const char *)text);
|
||||
size_t space = input.find(' ');
|
||||
if (space != string::npos) {
|
||||
input = input.substr(0, space);
|
||||
}
|
||||
|
||||
vector_string components;
|
||||
tokenize(input, components, ".");
|
||||
if (components.size() >= 1) {
|
||||
string_to_int(components[0], _gl_version_major);
|
||||
}
|
||||
if (components.size() >= 2) {
|
||||
string_to_int(components[1], _gl_version_minor);
|
||||
}
|
||||
if (components.size() >= 3) {
|
||||
string_to_int(components[2], _gl_version_release);
|
||||
}
|
||||
|
||||
GLCAT.debug()
|
||||
<< "GL_VERSION = " << (const char *)text << ", decoded to "
|
||||
<< _gl_version_major << "." << _gl_version_minor
|
||||
<< "." << _gl_version_release << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::save_extensions
|
||||
// Access: Protected
|
||||
@ -2725,6 +2776,26 @@ has_extension(const string &extension) const {
|
||||
return (_extensions.find(extension) != _extensions.end());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::is_at_least_version
|
||||
// Access: Public
|
||||
// Description: Returns true if the runtime GL version number is at
|
||||
// least the indicated value, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(GraphicsStateGuardian)::
|
||||
is_at_least_version(int major, int minor, int release) const {
|
||||
if (_gl_version_major < major) {
|
||||
return false;
|
||||
}
|
||||
if (_gl_version_minor < minor) {
|
||||
return false;
|
||||
}
|
||||
if (_gl_version_release < release) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::set_draw_buffer
|
||||
@ -2918,12 +2989,10 @@ compute_gl_image_size(int xsize, int ysize, int external_format, int type) {
|
||||
pixel_width = 2 * num_components;
|
||||
break;
|
||||
|
||||
#ifdef GL_UNSIGNED_BYTE_3_3_2_EXT
|
||||
case GL_UNSIGNED_BYTE_3_3_2_EXT:
|
||||
case GL_UNSIGNED_BYTE_3_3_2:
|
||||
nassertr(num_components == 3, 0);
|
||||
pixel_width = 1;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case GL_FLOAT:
|
||||
pixel_width = 4 * num_components;
|
||||
@ -3255,7 +3324,7 @@ get_texture_wrap_mode(Texture::WrapMode wm) {
|
||||
}
|
||||
switch (wm) {
|
||||
case Texture::WM_clamp:
|
||||
return GL_CLAMP;
|
||||
return _edge_clamp;
|
||||
case Texture::WM_repeat:
|
||||
return GL_REPEAT;
|
||||
|
||||
@ -3269,7 +3338,7 @@ get_texture_wrap_mode(Texture::WrapMode wm) {
|
||||
break;
|
||||
}
|
||||
GLCAT.error() << "Invalid Texture::WrapMode value!\n";
|
||||
return GL_CLAMP;
|
||||
return _edge_clamp;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -3332,10 +3401,8 @@ get_image_type(PixelBuffer::Type type) {
|
||||
return GL_UNSIGNED_BYTE;
|
||||
case PixelBuffer::T_unsigned_short:
|
||||
return GL_UNSIGNED_SHORT;
|
||||
#ifdef GL_UNSIGNED_BYTE_3_3_2_EXT
|
||||
case PixelBuffer::T_unsigned_byte_332:
|
||||
return GL_UNSIGNED_BYTE_3_3_2_EXT;
|
||||
#endif
|
||||
return GL_UNSIGNED_BYTE_3_3_2;
|
||||
case PixelBuffer::T_float:
|
||||
return GL_FLOAT;
|
||||
|
||||
@ -3480,9 +3547,7 @@ get_fog_mode_type(Fog::Mode m) const {
|
||||
case Fog::M_exponential: return GL_EXP;
|
||||
case Fog::M_exponential_squared: return GL_EXP2;
|
||||
/*
|
||||
#ifdef GL_FOG_FUNC_SGIS
|
||||
case Fog::M_spline: return GL_FOG_FUNC_SGIS;
|
||||
#endif
|
||||
*/
|
||||
|
||||
default:
|
||||
@ -3525,13 +3590,10 @@ print_gfx_visual() {
|
||||
|
||||
GLP(GetBooleanv)( GL_STEREO, &j ); cout << "Stereo? " << (int)j << endl;
|
||||
|
||||
#ifdef GL_MULTISAMPLE_SGIS
|
||||
GLP(GetBooleanv)( GL_MULTISAMPLE_SGIS, &j ); cout << "Multisample? "
|
||||
<< (int)j << endl;
|
||||
#endif
|
||||
#ifdef GL_SAMPLES_SGIS
|
||||
GLP(GetIntegerv)( GL_SAMPLES_SGIS, &i ); cout << "Samples: " << i << endl;
|
||||
#endif
|
||||
if (_supports_multisample) {
|
||||
GLP(GetBooleanv)( GL_MULTISAMPLE, &j ); cout << "Multisample? " << (int)j << endl;
|
||||
GLP(GetIntegerv)( GL_SAMPLES, &i ); cout << "Samples: " << i << endl;
|
||||
}
|
||||
|
||||
GLP(GetBooleanv)( GL_BLEND, &j ); cout << "Blend? " << (int)j << endl;
|
||||
GLP(GetBooleanv)( GL_POINT_SMOOTH, &j ); cout << "Point Smooth? "
|
||||
|
@ -133,10 +133,12 @@ protected:
|
||||
static bool report_errors_loop(int line, const char *source_file,
|
||||
GLenum error_code, int &error_count);
|
||||
void show_gl_string(const string &name, GLenum id);
|
||||
void get_gl_version();
|
||||
void save_extensions(const char *extensions);
|
||||
virtual void get_extra_extensions();
|
||||
void report_extensions() const;
|
||||
bool has_extension(const string &extension) const;
|
||||
bool is_at_least_version(int major, int minor, int release = 0) const;
|
||||
|
||||
virtual bool slot_new_light(int light_id);
|
||||
virtual void enable_lighting(bool enable);
|
||||
@ -299,8 +301,11 @@ protected:
|
||||
|
||||
int _pass_number;
|
||||
|
||||
int _gl_version_major, _gl_version_minor, _gl_version_release;
|
||||
pset<string> _extensions;
|
||||
bool _supports_bgr;
|
||||
bool _supports_multisample;
|
||||
GLenum _edge_clamp;
|
||||
|
||||
int _error_count;
|
||||
|
||||
|
@ -152,6 +152,45 @@ end_frame() {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: wglGraphicsBuffer::make_context
|
||||
// Access: Public, Virtual
|
||||
// Description: If _needs_context is true, this will be called
|
||||
// in the draw thread prior to rendering into the
|
||||
// window. It should attempt to create a graphics
|
||||
// context, and return true if successful, false
|
||||
// otherwise. If it returns false the window will be
|
||||
// considered failed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool wglGraphicsBuffer::
|
||||
make_context() {
|
||||
PStatTimer timer(_make_current_pcollector);
|
||||
|
||||
wglGraphicsStateGuardian *wglgsg;
|
||||
DCAST_INTO_R(wglgsg, _gsg, false);
|
||||
|
||||
if (_pbuffer_dc) {
|
||||
HGLRC context = wglgsg->get_context(_pbuffer_dc);
|
||||
if (context) {
|
||||
wglMakeCurrent(_pbuffer_dc, context);
|
||||
wglgsg->reset_if_new();
|
||||
_needs_context = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
} else {
|
||||
HGLRC context = wglgsg->get_context(_window_dc);
|
||||
if (context) {
|
||||
wglMakeCurrent(_window_dc, context);
|
||||
wglgsg->reset_if_new();
|
||||
_needs_context = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: wglGraphicsBuffer::make_current
|
||||
// Access: Public, Virtual
|
||||
|
@ -49,6 +49,7 @@ public:
|
||||
virtual bool begin_frame();
|
||||
virtual void end_frame();
|
||||
|
||||
virtual bool make_context();
|
||||
virtual void make_current();
|
||||
virtual void release_gsg();
|
||||
|
||||
|
@ -147,6 +147,33 @@ wglGraphicsWindow::
|
||||
~wglGraphicsWindow() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: wglGraphicsWindow::make_context
|
||||
// Access: Public, Virtual
|
||||
// Description: If _needs_context is true, this will be called
|
||||
// in the draw thread prior to rendering into the
|
||||
// window. It should attempt to create a graphics
|
||||
// context, and return true if successful, false
|
||||
// otherwise. If it returns false the window will be
|
||||
// considered failed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool wglGraphicsWindow::
|
||||
make_context() {
|
||||
PStatTimer timer(_make_current_pcollector);
|
||||
|
||||
wglGraphicsStateGuardian *wglgsg;
|
||||
DCAST_INTO_R(wglgsg, _gsg, false);
|
||||
|
||||
HGLRC context = wglgsg->get_context(_hdc);
|
||||
if (context) {
|
||||
wglMakeCurrent(_hdc, context);
|
||||
wglgsg->reset_if_new();
|
||||
_needs_context = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: wglGraphicsWindow::make_current
|
||||
// Access: Public, Virtual
|
||||
@ -161,15 +188,8 @@ make_current() {
|
||||
wglGraphicsStateGuardian *wglgsg;
|
||||
DCAST_INTO_V(wglgsg, _gsg);
|
||||
HGLRC context = wglgsg->get_context(_hdc);
|
||||
if (context) {
|
||||
wglMakeCurrent(_hdc, context);
|
||||
|
||||
// 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.
|
||||
// (We can't just call reset() when we construct the GSG, because
|
||||
// reset() requires having a current context.)
|
||||
wglgsg->reset_if_new();
|
||||
}
|
||||
nassertv(context);
|
||||
wglMakeCurrent(_hdc, context);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -33,6 +33,7 @@ public:
|
||||
const string &name);
|
||||
virtual ~wglGraphicsWindow();
|
||||
|
||||
virtual bool make_context();
|
||||
virtual void make_current();
|
||||
virtual void release_gsg();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user