X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2Fmoof%2Fvideo.cc;fp=src%2Fmoof%2Fvideo.cc;h=32278cc77ca25422e72595fffab04eeb692040b2;hp=0000000000000000000000000000000000000000;hb=831f04d4bc19a390415ac0bbac4331c7a65509bc;hpb=299af4f2047e767e5d79501c26444473bda64c64 diff --git a/src/moof/video.cc b/src/moof/video.cc new file mode 100644 index 0000000..32278cc --- /dev/null +++ b/src/moof/video.cc @@ -0,0 +1,394 @@ + +/*] Copyright (c) 2009-2010, Charles McGarvey [************************** +**] All rights reserved. +* +* vi:ts=4 sw=4 tw=75 +* +* Distributable under the terms and conditions of the 2-clause BSD license; +* see the file COPYING for a complete text of the license. +* +**************************************************************************/ + +#include + +#include "dispatcher.hh" +#include "image.hh" +#include "log.hh" +#include "settings.hh" +#include "video.hh" + + +namespace moof { + + +video::video(const std::string& caption) +{ + video::caption(caption); + init(); +} + +video::video(const class attributes& attribs) : + attributes_(attribs) +{ + init(); +} + +video::video(const std::string& caption, + const class attributes& attribs) : + attributes_(attribs) +{ + video::caption(caption); + init(); +} + +void video::init() +{ + context_ = 0; + flags_ = 0; + + fullscreen(attributes_.is_fullscreen); + resizable(attributes_.is_resizable); + set_opengl_attributes(); + cursor_visible(attributes_.is_cursor_visible); + cursor_captured(attributes_.is_cursor_captured); + mode(attributes_.mode); + + if (!current_) make_current(); +} + +void video::recreate_context() +{ + SDL_FreeSurface(context_); + context_ = 0; + mode(attributes_.mode); +} + +void video::set_opengl_attributes() +{ + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, + attributes_.color_buffer[0]); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, + attributes_.color_buffer[1]); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, + attributes_.color_buffer[2]); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, + attributes_.color_buffer[3]); + SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, + attributes_.frame_buffer); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, + attributes_.is_double_buffer); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, + attributes_.depth_buffer); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, + attributes_.stencil_buffer); + SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, + attributes_.accumulator_buffer[0]); + SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, + attributes_.accumulator_buffer[1]); + SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, + attributes_.accumulator_buffer[2]); + SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, + attributes_.accumulator_buffer[3]); + SDL_GL_SetAttribute(SDL_GL_STEREO, + attributes_.is_stereo); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, + attributes_.multisample_buffers); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, + attributes_.multisample_samples); + SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, + attributes_.is_swap_control); + SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, + attributes_.is_hardware_only); +} + + +video::~video() +{ + SDL_FreeSurface(context_); + + if (current_ == this) current_ = 0; +} + + +class video::attributes video::attributes() const +{ + return attributes_; +} + + +void video::mode(const int mode[3]) +{ + if (mode != attributes_.mode || !context_) + { + if (context_) SDL_FreeSurface(context_); + + context_ = SDL_SetVideoMode(mode[0], mode[1], mode[2], + SDL_OPENGL | flags_); + + if (context_) + { + attributes_.mode[0] = mode[0]; + attributes_.mode[1] = mode[1]; + attributes_.mode[2] = mode[2]; + +#if !defined(linux) && !defined(__linux) && !defined(__linux__) + log_info("video context recreated"); + dispatcher::global().dispatch("video.newcontext"); +#endif + } + else + { + throw std::runtime_error("bad video mode attempted"); + } + } +} + + +void video::resize(int width, int height) +{ + int mode[] = {width, height, attributes_.mode[2]}; + video::mode(mode); +} + +bool video::iconify() +{ + return SDL_WM_IconifyWindow(); +} + + +void video::caption(const std::string& caption) +{ + SDL_WM_SetCaption(caption.c_str(), 0); +} + +std::string video::caption() const +{ + char* caption; + SDL_WM_GetCaption(&caption, 0); + return std::string(caption); +} + + +void video::fullscreen(bool full) +{ + if (full != fullscreen() || !context_) + { + if (context_) + { + flags_ ^= SDL_FULLSCREEN; + +#if defined(linux) || defined(__linux) || defined(__linux__) + if (SDL_WM_ToggleFullScreen(context_) == 0) +#endif + recreate_context(); + } + else + { + if (full) flags_ |= SDL_FULLSCREEN; + else flags_ &= ~SDL_FULLSCREEN; + } + } +} + +bool video::fullscreen() const +{ + return flags_ & SDL_FULLSCREEN; +} + +void video::toggle_fullscreen() +{ + fullscreen(!fullscreen()); +} + + +void video::resizable(bool is_resizable) +{ + if (is_resizable != resizable() || !context_) + { + if (context_) + { + flags_ ^= SDL_RESIZABLE; + recreate_context(); + } + else + { + if (is_resizable) flags_ |= SDL_RESIZABLE; + else flags_ &= ~SDL_RESIZABLE; + } + } +} + +bool video::resizable() const +{ + return flags_ & SDL_RESIZABLE; +} + +void video::toggle_resizable() +{ + resizable(!resizable()); +} + + +void video::cursor_visible(bool is_cursor_visible) +{ + SDL_ShowCursor(is_cursor_visible? SDL_ENABLE : SDL_DISABLE); +} + +bool video::cursor_visible() const +{ + return (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE); +} + +void video::toggle_cursor_visible() +{ + cursor_visible(!cursor_visible()); +} + + +bool video::cursor_captured() const +{ + return (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON); +} + +void video::cursor_captured(bool is_cursor_captured) +{ + SDL_WM_GrabInput(is_cursor_captured? SDL_GRAB_ON : SDL_GRAB_OFF); +} + +void video::toggle_cursor_captured() +{ + cursor_captured(!cursor_captured()); +} + + +void video::swap() +{ + SDL_GL_SwapBuffers(); +} + + +int video::width() const +{ + return context_->w; +} + +int video::height() const +{ + return context_->h; +} + + +void video::make_current() const +{ + current_ = const_cast(this); +} + + +video::attributes::attributes() +{ + init(); +} + +video::attributes::attributes(const settings& settings) +{ + init(); + + std::vector colors; + settings.get("colorbuffers", colors); + if (colors.size() > 0) color_buffer[0] = colors[0]; + if (colors.size() > 1) color_buffer[1] = colors[1]; + if (colors.size() > 2) color_buffer[2] = colors[2]; + if (colors.size() > 3) color_buffer[3] = colors[3]; + + settings.get("framebuffer", frame_buffer); + settings.get("doublebuffer", is_double_buffer); + settings.get("depthbuffer", depth_buffer); + settings.get("stencilbuffer", stencil_buffer); + + std::vector accum; + settings.get("accumbuffers", accum); + if (accum.size() > 0) accumulator_buffer[0] = accum[0]; + if (accum.size() > 1) accumulator_buffer[1] = accum[1]; + if (accum.size() > 2) accumulator_buffer[2] = accum[2]; + if (accum.size() > 3) accumulator_buffer[3] = accum[3]; + + settings.get("stereo", is_stereo); + settings.get("multiesamplebuffers", multisample_buffers); + settings.get("multiesamplesamples", multisample_samples); + settings.get("swapcontrol", is_swap_control); + settings.get("hardwareonly", is_hardware_only); + + settings.get("fullscreen", is_fullscreen); + settings.get("resizable", is_resizable); + settings.get("showcursor", is_cursor_visible); + settings.get("grab", is_cursor_captured); + + std::vector dimensions; + settings.get("videomode", dimensions); + if (dimensions.size() > 1) + { + mode[0] = dimensions[0]; + mode[1] = dimensions[1]; + } + else if (is_fullscreen && backend::is_initialized()) + { + SDL_Rect** modes = SDL_ListModes(NULL, + SDL_FULLSCREEN | SDL_HWSURFACE); + + if (modes == (SDL_Rect**)0) + { + log_error("no native video mode"); + } + else if (modes == (SDL_Rect**)-1) + { + log_warning("any resolution allowed; " + "choosing default 800x600"); + mode[0] = 800; + mode[1] = 600; + } + else + { + mode[0] = (*modes)->w; + mode[1] = (*modes)->h; + log_info << "choosing native resolution " + << mode[0] << "x" << mode[1] << std::endl; + } + } + if (dimensions.size() > 2) mode[2] = dimensions[2]; +} + +void video::attributes::init() +{ + // set some sane GL and window defaults (see SDL_video.c:217) + color_buffer[0] = 3; + color_buffer[1] = 3; + color_buffer[2] = 2; + color_buffer[3] = 0; + frame_buffer = 0; + is_double_buffer = true; + depth_buffer = 16; + stencil_buffer = 0; + accumulator_buffer[0] = 0; + accumulator_buffer[1] = 0; + accumulator_buffer[2] = 0; + accumulator_buffer[3] = 0; + is_stereo = false; + multisample_buffers = 0; + multisample_samples = 0; + is_swap_control = false; + is_hardware_only = false; + mode[0] = 640; + mode[1] = 480; + mode[2] = 0; + is_fullscreen = false; + is_resizable = false; + is_cursor_visible = true; + is_cursor_captured = false; +} + + +video* video::current_ = 0; // most recently instantiated instance + + +} // namespace moof +