1. spencercw
  2. gb_emulator


gb_emulator / gb_emulator / include / gb_emulator / gb_video_opengl_es2.h

/*  Copyright © 2012, 2013 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
    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_ES2_H_BCE8A200_5CB3_11E2_BF27_0002A5D5C51B
#define GB_VIDEO_OPENGL_ES2_H_BCE8A200_5CB3_11E2_BF27_0002A5D5C51B

#include <stdint.h>

#include <memory>
#include <vector>

#include <boost/filesystem/path.hpp>

#include <EGL/egl.h>
#include <GLES2/gl2.h>

#include <gb_emulator/gb_video.h>

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

	//! Destructor.

	//! 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_;

	// 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_;

	// OpenGL data
	EGLDisplay display_;
	EGLSurface surface_;
	EGLContext eglContext_;

	GLuint vertexShader_;
	GLuint fragmentShader_;
	GLuint program_;
	GLuint vertexBuffer_;
	GLuint texture_;

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

	// RGB pixel buffers
	std::unique_ptr<uint32_t[]> unscaledPixelBuffer_;
	std::unique_ptr<uint32_t[]> scaledPixelBuffer_;
	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 initialiseGL(GLsizei width, GLsizei height);
	void initialiseShaders();
	GLuint compileShader(GLenum type, const boost::filesystem::path &source);

	// 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
	GbVideoOpenGLES2(const GbVideoOpenGLES2 &);
	GbVideoOpenGLES2 & operator=(const GbVideoOpenGLES2 &);