Source

gb_emulator / gb_emulator / include / gb_emulator / gb_video_opengl.h

Full commit
/*  Copyright Š 2012 Chris Spencer <spencercw@gmail.com>

    This program 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.

    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifndef GB_VIDEO_OPENGL_H_31E5B920_17BE_11E2_B364_0002A5D5C51B
#define GB_VIDEO_OPENGL_H_31E5B920_17BE_11E2_B364_0002A5D5C51B

#include <stdint.h>

#include <memory>
#include <vector>

#include <boost/filesystem/path.hpp>

#include <Windows.h>
#include <GL/glew.h>
#include <GL/GL.h>

#include <gb_emulator/gb_video.h>

struct _CGcontext;
struct _CGprogram;

//! OpenGL video driver.
class GbVideoOpenGL:
	public GbVideo
{
public:
	//! Constructor.
	/*
	 * \param gb The emulator context.
	 * \param installDir The installation directory.
	 */
	GbVideoOpenGL(Gb &gb, const boost::filesystem::path &installDir);

	//! Destructor.
	~GbVideoOpenGL();

	//! Indicates whether OpenGL is available.
	/**
	 * The current implementation always returns true.
	 * \return Whether OpenGL is available.
	 */
	bool isAvailable()
	{
		return true;
	}

	//! Initialises OpenGL and opens the display.
	void initialise();

	//! Returns the window handle.
	HWND window() const
	{
		return window_;
	}

private:
	// Dimensions of the texture to which the video is rendered
	static const unsigned TEXTURE_WIDTH = 1024;
	static const unsigned TEXTURE_HEIGHT = 1024;

	// The window we are drawing into
	HWND window_;
	ATOM windowClass_;
	HDC deviceContext_;
	HGLRC renderContext_;

	// OpenGL data
	GLuint program_;
	GLuint vertexBuffer_;
	GLuint pixelBuffer_;
	GLuint texture_;

	// Cg data
	std::unique_ptr<_CGcontext, void (*)(_CGcontext *)> cgContext_;
	std::unique_ptr<_CGprogram, void (*)(_CGprogram *)> vertexShader_;
	std::unique_ptr<_CGprogram, void (*)(_CGprogram *)> fragmentShader_;

	// The installation directory
	boost::filesystem::path installDir_;

	// RGB pixel buffers
	std::unique_ptr<uint32_t[]> unscaledPixelBuffer_;
	std::unique_ptr<uint32_t[]> textureBuffer_;

	// Redraws the display
	void draw(uint16_t *pixelBuffer, bool gbc);

	// Called when the render window is resized
	void resize(GLsizei width, GLsizei height);

	// Initialisation functions
	void setupPixelFormat();
	void initialiseGL(GLsizei width, GLsizei height);
	void initialiseShaders();
	GLuint createShader(GLenum type, const char *code);
	GLuint createProgram(const std::vector<GLuint> &shaders);

	// Callbacks
	static void cgErrorCallback();

	// Window message procedure
	static LRESULT CALLBACK initialWindowProc(HWND window, unsigned message, WPARAM wParam,
		LPARAM lParam);
	static LRESULT CALLBACK windowProc(HWND window, unsigned message, WPARAM wParam, LPARAM lParam);
	LRESULT doWindowProc(HWND window, unsigned message, WPARAM wParam, LPARAM lParam);

	// Disabled operations
	GbVideoOpenGL(const GbVideoOpenGL &);
	GbVideoOpenGL & operator=(const GbVideoOpenGL &);
};

#endif