📄 glutwindow.cpp
字号:
// ___ ___ ___ ___ ___ // /\__\ ___ /\__\ /\ \ /\__\ /\ \. // /::| | /\ \ /::| | /::\ \ /:/ / /::\ \. // /:|:| | \:\ \ /:|:| | /:/\:\ \ /:/ / /:/\:\ \. // /:/|:|__|__ /::\__\ /:/|:| |__ /:/ \:\ \ /:/ / /::\~\:\ \. // /:/ |::::\__\ __/:/\/__/ /:/ |:| /\__\ /:/__/_\:\__\ /:/__/ /:/\:\ \:\__\.// \/__/~~/:/ / /\/:/ / \/__|:|/:/ / \:\ /\ \/__/ \:\ \ \:\~\:\ \/__/// /:/ / \::/__/ |:/:/ / \:\ \:\__\ \:\ \ \:\ \:\__\. // /:/ / \:\__\ |::/ / \:\/:/ / \:\ \ \:\ \/__/ // /:/ / \/__/ /:/ / \::/ / \:\__\ \:\__\. // \/__/ \/__/ \/__/ \/__/ \/__/ // // =============================================================================// Minimalist OpenGL Environment// =============================================================================//// This file is part of Minimalist OpenGL Environment (MinGLE)//// Version: 0.2.0// Author: Balazs Domonkos// Filename: src/GLUT/src/GLUTWindow.cpp// Creation Date: December 12th 2007// Revision Date: December 12th 2007////// The Minimalist OpenGL Environment is free software: you can// redistribute it and/or modify it under the terms of the GNU// General Public License as published by the Free Software// Foundation, either version 3 of the License, or (at your// option) any later version.//// The Minimalist OpenGL Environment is distributed in the hope// that it will be useful, but WITHOUT ANY WARRANTY; without// even the implied warranty of MERCHANTABILITY or FITNESS FOR// A PARTICULAR PURPOSE. See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License// along with Minimalist OpenGL Environment. If not, see // <http://www.gnu.org/licenses/>. See the COPYING file included // with this distribution file for license details.///// @file GLUTWindow.cpp/// GLUT rendering window class// Header that contains the declaration#include <GLUTWindow.h>// MinGLE headers#include <GLUTTimer.h>#include <System.h>// System headers#include <GL/glut.h>namespace MinGLE {GLUTWindow *GLUTWindow::msInstance = 0;bool GLUTWindow::mKeyRepeatOn = false;double GLUTWindow::mLastKeyEventTime = 0.0;unsigned char GLUTWindow::mLastNormalKey = 0;int GLUTWindow::mLastSpecialKey = 0;GLUTWindow::GLUTWindow(unsigned width, unsigned height, WindowAttributes::ColorMode colorMode, bool doubleBuffer, bool fullScreen, unsigned videoRate, unsigned char *colorBits, unsigned char depthBits, unsigned char stencilBits, unsigned char *accumColorBits, unsigned auxBuffers, bool stereo) : Window(width, height, colorMode, doubleBuffer, fullScreen, videoRate, colorBits, depthBits, stencilBits, accumColorBits, auxBuffers, stereo), mWindowId(-1), mGameModeSupported(false), mLastMouseActionTime(0.0) { // Save instance (only on GLUT window is possible) msInstance = this; unsigned int mode = 0; switch (mWindowAttributes->mColorMode) { case WindowAttributes::DIRECT_COLORS: mode |= GLUT_RGBA; break; case WindowAttributes::INDEXED_COLORS: mode |= GLUT_INDEX; break; } mode |= mWindowAttributes->mDoubleBuffer ? GLUT_DOUBLE : GLUT_SINGLE; if (mWindowAttributes->mColorBits[3]) mode |= GLUT_ALPHA; if (mWindowAttributes->mDepthBits) mode |= GLUT_DEPTH; if (mWindowAttributes->mStencilBits) mode |= GLUT_STENCIL; if (mWindowAttributes->mAccumColorBits[0] |mWindowAttributes->mAccumColorBits[1] |mWindowAttributes->mAccumColorBits[2] |mWindowAttributes->mAccumColorBits[3]) mode |= GLUT_ACCUM; // NOTE: Aux buffers are not supported if (mWindowAttributes->mStereo) mode |= GLUT_STEREO; // Init display mode glutInitDisplayMode(mode); // Detect supports mGameModeSupported = glutGameModeGet(GLUT_GAME_MODE_POSSIBLE); mGameModeSupported = false; if (mWindowAttributes->mFullScreen) { setFullScreen(true); } else { glutInitWindowPosition(mWindowAttributes->mLeft, mWindowAttributes->mTop); glutInitWindowSize(mWindowAttributes->mWidth, mWindowAttributes->mHeight); mWindowId = glutCreateWindow(mWindowAttributes->mTitle.c_str()); } // Try to disable key repeat _disableKeyRepeat(); // TODO: check errors}GLUTWindow::~GLUTWindow() {}void GLUTWindow::setPosition(int left, int top) { // Return from full screen if (mWindowAttributes->mFullScreen) setFullScreen(false); _setPosition(mWindowAttributes->mRecoveryLeft = left, mWindowAttributes->mRecoveryTop = top);}void GLUTWindow::setSize(unsigned width, unsigned height) { // Return from full screen if (mWindowAttributes->mFullScreen) setFullScreen(false); _setSize(mWindowAttributes->mRecoveryWidth = width, mWindowAttributes->mRecoveryHeight = height);}void GLUTWindow::setFullScreen(bool fullScreen) { // Leave game mode if (mWindowAttributes->mFullScreen && !fullScreen && mGameModeSupported) glutLeaveGameMode(); if (mWindowAttributes->mFullScreen = fullScreen) { // Enter game mode if supported if (mGameModeSupported) { // Just for sure _setPosition(0, 0); _setSize(System::getScreenWidth(), System::getScreenHeight()); char gameModeString[64]; sprintf( gameModeString, "%dx%d:%d@%d", mWindowAttributes->mWidth, mWindowAttributes->mHeight, mWindowAttributes->mColorBits[0] +mWindowAttributes->mColorBits[1] +mWindowAttributes->mColorBits[2] +mWindowAttributes->mColorBits[3], mWindowAttributes->mVideoRate ? mWindowAttributes->mVideoRate : 60); glutGameModeString(gameModeString); glutEnterGameMode(); } // Just fullscreen the window else { glutFullScreen(); } } else { setPosition(mWindowAttributes->mRecoveryLeft, mWindowAttributes->mRecoveryTop); setSize(mWindowAttributes->mRecoveryWidth, mWindowAttributes->mRecoveryHeight); }}void GLUTWindow::setVisible(bool visible) { if (mWindowAttributes->mVisible = visible) glutShowWindow(); else glutHideWindow(); mWindowAttributes->mIconified = false;}void GLUTWindow::iconify() { mWindowAttributes->mIconified = true; glutIconifyWindow();}void GLUTWindow::setTitle(const std::string& title) { mWindowAttributes->mTitle = title; glutSetWindowTitle(mWindowAttributes->mTitle.c_str()); glutSetIconTitle(mWindowAttributes->mTitle.c_str());}void GLUTWindow::finishFrame() { if (mWindowAttributes->mDoubleBuffer) glutSwapBuffers(); else glFlush(); // Call base implementation Window::finishFrame();}void GLUTWindow::redisplay() { glutPostRedisplay();}void GLUTWindow::clearFrame() { GLbitfield mask= GL_COLOR_BUFFER_BIT; if (mWindowAttributes->mDepthBits) mask |= GL_DEPTH_BUFFER_BIT; if (mWindowAttributes->mStencilBits) mask |= GL_STENCIL_BUFFER_BIT; if (mWindowAttributes->mAccumColorBits[0] |mWindowAttributes->mAccumColorBits[1] |mWindowAttributes->mAccumColorBits[2] |mWindowAttributes->mAccumColorBits[3]) mask |= GL_ACCUM_BUFFER_BIT; glClear(mask);}Timer *GLUTWindow::createTimer(double period, Timer::TimerType type) { return new GLUTTimer(this, period, type);}void GLUTWindow::_disableKeyRepeat() { // Try to disable key repeating in two ways glutIgnoreKeyRepeat(1); glutSetKeyRepeat(GLUT_KEY_REPEAT_OFF); // Check success if (glutDeviceGet(GLUT_DEVICE_KEY_REPEAT) != GLUT_KEY_REPEAT_OFF && !glutDeviceGet(GLUT_DEVICE_IGNORE_KEY_REPEAT)) { // Setting software repeat filtering. But don't expect very good results mKeyRepeatOn = true; mLastKeyEventTime = Timer::getSystemTime(); }}void GLUTWindow::_setupWindowListener() { // Always render when the window is invalid glutDisplayFunc(GLUTWindow::_onRender); glutReshapeFunc(GLUTWindow::_onResize); glutKeyboardFunc(_onNormalKeyboardEvent); glutSpecialFunc(_onSpecialKeyboardEvent); // FreeGLUT implementation supports not only keydown but also keyup events#ifdef __FREEGLUT_STD_H__ glutKeyboardUpFunc(_onNormalKeyboardUpEvent); glutSpecialUpFunc(_onSpecialKeyboardUpEvent);#endif glutMouseFunc(_onMouseEvent); glutMotionFunc(_onMotionEvent); glutPassiveMotionFunc(_onPassiveMotionEvent); glutEntryFunc(_onEntryEvent); _setupWindowListenerIdle();}void GLUTWindow::_setupWindowListenerIdle() { // If render on idle if (mWindowAttributes->mRenderMode == WindowAttributes::RENDER_WHEN_IDLE) glutIdleFunc(GLUTWindow::_onRender); // If we want to listen on idle event else if (mWindowAttributes->mListenOnIdle) glutIdleFunc(GLUTWindow::_onIdle); // Forget the idle event else glutIdleFunc(0);}void GLUTWindow::_windowIsReadyToBeShown() { // Start render triggering timer if (mWindowAttributes->mRenderMode == WindowAttributes::RENDER_ON_TIMER) mTimeTriggeredRenderController.startOperation();}void GLUTWindow::_close() { // We cannot quit from GLUT's event loop, kill this window delete this; // Closing a GLUT window means quitting from the application // since only one GLUT windows is allowed System::quit();}void GLUTWindow::_setPosition(int left, int top) { glutPositionWindow(mWindowAttributes->mLeft = left, mWindowAttributes->mTop = top);}void GLUTWindow::_setSize(unsigned width, unsigned height) { glutReshapeWindow(mWindowAttributes->mWidth = width, mWindowAttributes->mHeight = height);}void GLUTWindow::_onRender() { if (msInstance->mWindowAttributes->mAutoClearFrame) msInstance->clearFrame(); msInstance->_doRender(); if (msInstance->mWindowAttributes->mAutoFinishFrame) msInstance->finishFrame(); msInstance->checkRedisplay();}void GLUTWindow::_onIdle() { msInstance->_doIdle();}void GLUTWindow::_onResize(int width, int height) { msInstance->mWindowAttributes->mWidth = (unsigned) width; msInstance->mWindowAttributes->mHeight = (unsigned) height; if (msInstance->mWindowAttributes->mAutoUpdateViewport) glViewport(0, 0, (GLint) width, (GLint) height); msInstance->_doResize((unsigned) width, (unsigned) height);}void GLUTWindow::_onNormalKeyboardEvent(unsigned char glutCode, int x, int y) { // Register the mouse information msInstance->_doRegisterMouseMoveEvent(x, y); // Keyrepeat cannot be disabled (software filtering) if (mKeyRepeatOn) { // Only raise event when the elapsed time is big enough double now = Timer::getSystemTime(); if (glutCode != mLastNormalKey || now - mLastKeyEventTime >= KEY_EVENT_DELAY_THRESHOLD) { //printf("down: %.6f\n", now - mLastKeyEventTime); _handleNormalKeyboardEvent(glutCode, InputListener::KEY_DOWN); } mLastKeyEventTime = now; mLastNormalKey = glutCode; } else _handleNormalKeyboardEvent(glutCode, InputListener::KEY_DOWN);}void GLUTWindow::_onNormalKeyboardUpEvent(unsigned char glutCode, int x, int y) { // Register the mouse information msInstance->_doRegisterMouseMoveEvent(x, y); // Keyrepeat cannot be disabled (software filtering) if (mKeyRepeatOn) { // Only raise event when the elapsed time is big enough double now = Timer::getSystemTime(); if (glutCode != mLastNormalKey || now - mLastKeyEventTime >= KEY_EVENT_DELAY_THRESHOLD) { //printf("up: %.6f\n", now - mLastKeyEventTime); _handleNormalKeyboardEvent(glutCode, InputListener::KEY_UP); } mLastKeyEventTime = now; mLastNormalKey = glutCode; } else _handleNormalKeyboardEvent(glutCode, InputListener::KEY_UP);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -