⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 display_window_opengl.cpp

📁 这是一款2d游戏引擎
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			} 
			catch (CL_Error& err)
			{
				CL_Log::log("debug", "Joystick Error: %1", err.message);
				done = true;
			}
		}
		else
		{
			CL_Log::log("debug", "Joystick Error: %1: %2", pathname, strerror(errno));
			done = true;
		}
	}
}

void CL_DisplayWindow_OpenGL::destroy_window()
{
	set_windowed();

	if (context)
	{
		if (!glXMakeCurrent(disp, None, NULL))
		{
			printf("Could not release drawing context.\n");
		}

		glXDestroyContext(disp, context);
		context = NULL;
	}

	keyboard = CL_InputDevice();
	mouse = CL_InputDevice();
	get_ic()->clear();

	if (window) XDestroyWindow(disp, window);
	window = 0;
	
	if (disp_ref_count > 0)
	{
		disp_ref_count--;
		if (disp_ref_count == 0)
		{
			XCloseDisplay(disp);
			disp = 0;
		}
	}
}

void CL_DisplayWindow_OpenGL::on_xevent(XEvent &event)
{
	//Disabled for now
}

void CL_DisplayWindow_OpenGL::flip()
{
	CL_GLStateChecker::from_gc(get_gc())->flush();
	XSync(disp,False);
	glXSwapBuffers(disp, window);
}

void CL_DisplayWindow_OpenGL::set_fullscreen(int width, int height, int bpp, int refresh_rate)
{
	if(fullscreen)
		return;

	// Vid-mode Switching
	int num_modes;
	XF86VidModeModeInfo **modes;
	XF86VidModeModeLine cur_mode;
	std::list<XF86VidModeModeInfo *> usable_modes;

	XF86VidModeGetModeLine(disp, 0, &dotclock, &cur_mode);

	old_mode.dotclock = dotclock;
	old_mode.hdisplay = cur_mode.hdisplay;
	old_mode.hsyncstart = cur_mode.hsyncstart;
	old_mode.hsyncend = cur_mode.hsyncend;
	old_mode.htotal = cur_mode.htotal;
	old_mode.vdisplay = cur_mode.vdisplay;
	old_mode.vsyncstart = cur_mode.vsyncstart;
	old_mode.vsyncend = cur_mode.vsyncend;
	old_mode.vtotal = cur_mode.vtotal;
	old_mode.flags = cur_mode.flags;
	old_mode.privsize = 0;

	XF86VidModeGetAllModeLines(disp, 0, &num_modes, &modes);

	for(int i = 0; i < num_modes; i++)
	{
		if(modes[i]->hdisplay == width && modes[i]->vdisplay == height)
		{
			CL_Log::log("debug", "Useable fullscreen mode found: %1x%2", width, height);
			usable_modes.push_back(modes[i]);
		}
	}
	
	if (usable_modes.empty())
	{
		CL_Log::log("debug", "No useable fullscreen modes available!");
	}
	
	if(!width)
		width = get_width();

	if(!height)
		height = get_height();

	if(!bpp)
		bpp = glx_bpp;

	//Hide Window
	XUnmapWindow(disp, window);
	XSync(disp, True);

	// Turn off WM control
	attributes.override_redirect = True;
	XChangeWindowAttributes(disp, window, CWBorderPixel | CWColormap | CWOverrideRedirect, &attributes);

	XMoveResizeWindow(disp, window, 0, 0, width, height);

	// Re-appear window
	XMapRaised(disp, window);
	XSync(disp, True);

	// Get input focus
	XSetInputFocus (disp,window, RevertToNone, CurrentTime);

	int x,y;

	set_position(0,0);

	// Move the mouse and switch moves
	XWarpPointer(disp, None, window, 0, 0, 0, 0, 0, 0);
	if (!usable_modes.empty())
	{
		XF86VidModeSwitchToMode(disp, 0, *(usable_modes.begin()));
	}
	XWarpPointer(disp, None, window, 0, 0, 0, 0, 0, 0);

	XGrabPointer(disp, window, True, 0, GrabModeAsync, GrabModeAsync, window, None, CurrentTime);
	
	XF86VidModeGetViewPort(disp, 0, &x, &y);

	set_position(x, y);
	
	if (!usable_modes.empty())
	{
		old_x = x;
		old_y = y;
	}
	else
	{
		// If we never managed to switch mode, tell restore mode code.
		old_x = -1;
		old_y = -1;
	}

	CL_Log::log("debug", "Viewport is %1x%2", x, y);

	XSync(disp, True);

	fullscreen = true;
}

void CL_DisplayWindow_OpenGL::set_windowed()
{
	if(!fullscreen)
		return;

	// Hide window
	XUnmapWindow(disp, window);
	XSync(disp, True);

	// Turn on WM control
	attributes.override_redirect = False;
	XChangeWindowAttributes(disp, window, CWBorderPixel | CWColormap | CWOverrideRedirect, &attributes);

	XMoveResizeWindow(disp, window, 0, 0, fullscreen_width, fullscreen_height);

	XMapRaised(disp, window);
	XSync(disp, True);

	fullscreen = false;

	// Only restore mode if we ever switched mode.
	if (old_x != -1 || old_y != -1)
	{
		XF86VidModeSwitchToMode(disp, 0, &old_mode);
		XF86VidModeSetViewPort(disp, 0, old_x, old_y);
	}

	XUngrabPointer(disp, CurrentTime);

	XSync(disp, True);
}

void CL_DisplayWindow_OpenGL::set_title(const std::string &title)
{
	XSetStandardProperties(disp, window, title.c_str(), title.c_str(), None, NULL, 0, NULL);
}

void CL_DisplayWindow_OpenGL::set_position(const CL_Rect &pos)
{
	set_position(pos.left, pos.top);
	XResizeWindow(disp, window, pos.get_width(), pos.get_height());
	set_size(pos.get_width(), pos.get_height());
}

void CL_DisplayWindow_OpenGL::set_position(int x, int y)
{
	XMoveWindow(disp, window, x, y);
}

void CL_DisplayWindow_OpenGL::set_size(int width, int height)
{
	fullscreen_width = width;
	fullscreen_height = height;
	sig_resize(width, height);
}

void CL_DisplayWindow_OpenGL::set_buffer_count(int flipping_buffers)
{
// Not implemented.
// We can't change how many buffer we use in OpenGL, the drivers pick for us
	CL_Log::log("debug", "CL_DisplayWindow_OpenGL::set_buffer_count is not implemented");
}

void CL_DisplayWindow_OpenGL::update(const CL_Rect &rect)
{
	CL_OpenGLState state(get_gc());
	state.set_active();
	state.setup_2d();

	clReadBuffer(CL_BACK);

	if(clGetError() == CL_NO_ERROR)		// Check if we got more than 1 buffer.
	{
		float raster_pos[4];

		clGetFloatv(CL_CURRENT_RASTER_POSITION, raster_pos);

		clDrawBuffer(CL_FRONT);
		clRasterPos3f(rect.left, rect.bottom, raster_pos[2]);

		clCopyPixels(rect.top, rect.left, rect.get_width(), rect.get_height(), CL_COLOR);

		// Return to drawing to the back buffer
		clDrawBuffer(CL_BACK);
	}
}

void CL_DisplayWindow_OpenGL::show_system_cursor()
{
	XDefineCursor(disp, window, system_cursor);
}

void CL_DisplayWindow_OpenGL::hide_system_cursor()
{
	XDefineCursor(disp, window, hidden_cursor);
}

void CL_DisplayWindow_OpenGL::cursor_changed()
{
// We have to extract the data from the cursor in order to display it

// At this point nothing more than hiding/unhiding the system cursor is supported
// I'm waiting for the release of XFree86 4.3, which has the Xcursor extension library.
// This will greatly simplify this, so I don't want to start implenting this.
// --MSR, Nov. 13, 2002
}

void CL_DisplayWindow_OpenGL::keep_alive()
{
	XEvent event, next_event;
	CL_Rect *rect;
	
	for (int i=XPending(disp); i>0; i--)
	{
		XNextEvent(disp, &event);
		switch(event.type)
		{
			//Resize or Move
			case ConfigureNotify:
				#ifdef DEBUG
					CL_Log::log("debug", "ConfigureNotify Event received");
				#endif
				set_size(event.xconfigure.width,event.xconfigure.height);
				break;
			case ClientMessage:
				#ifdef DEBUG
					CL_Log::log("debug", "Received ClientMessage, sending close signal");
				#endif
				sig_window_close();
				break;
			case Expose:
				// Repaint notification
				// Could be more efficient if we checked ahead for other
				// repaint notifications
				#ifdef DEBUG
					CL_Log::log("debug", "Expose Event received");
				#endif
				rect = new CL_Rect(event.xexpose.x, event.xexpose.y,
					event.xexpose.x + event.xexpose.width, event.xexpose.y + event.xexpose.height);
				sig_paint(*rect);
				delete rect;
				break;
			case FocusIn:
				#ifdef DEBUG
					CL_Log::log("debug", "Focus In");
				#endif
				focus = true;
				sig_got_focus();
				break;
			case FocusOut:
				#ifdef DEBUG
					CL_Log::log("debug", "Focus Out");
				#endif
				focus = false;
				sig_lost_focus();
				break;
			case KeyRelease:
				if( XEventsQueued( disp, QueuedAfterReading ) )
				{
					XPeekEvent( disp, &next_event );
					if( next_event.type == KeyPress &&
						next_event.xkey.window == event.xkey.window &&
						next_event.xkey.keycode == event.xkey.keycode &&
						next_event.xkey.time == event.xkey.time )
					{
						// Do not report anything for this event
						break;
					}
				}
			case KeyPress:
			case KeymapNotify:
			case ButtonPress:
			case ButtonRelease:
			case MotionNotify:
				sig_xevent(event);
				break;
			case PropertyNotify:
				#ifdef DEBUG
				// This looks to be mostly useless
				// I'm getting a lot of WM messages that aren't really useful.
				// --MSR, April 5, 2003
				/*
					if(event.xproperty.state == PropertyNewValue)
					{
						CL_Log::log("debug", "%1 has a new value", XGetAtomName(disp, event.xproperty.atom));
					}
				*/
				#endif
				break;
			#ifdef DEBUG
			case EnterNotify:
			case LeaveNotify:
				CL_Log::log("debug", "The mouse has left or entered the window");
				break;
			default:
				CL_Log::log("debug", "Unhandled event type: %1", event.type);
			#endif
		}
	}
}

// Local Variables: ***
// mode: clanlib ***
// End: ***

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -