1. spencercw
  2. gb_emulator

Commits

spencercw  committed a7d8c54

Only use the BGRA pixel format in the OpenGL ES renderer if the hardware supports it.

  • Participants
  • Parent commits bfc0d0b
  • Branches android

Comments (0)

Files changed (3)

File gb_emulator/include/gb_emulator/gb_video_opengl_es2.h

View file
 	GLuint vertexBuffer_;
 	GLuint texture_;
 
+	std::vector<std::string> extensions_;
+	GLint pixelFormat_;
+
 	// The installation directory
 	boost::filesystem::path installDir_;
 

File gb_emulator/shaders/gles2/fragment_flip_shader.glsl

View file
+/*  Copyright © 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
+    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/>.  */
+
+precision mediump float;
+
+varying vec2 v_texCoord;
+uniform sampler2D s_texture;
+
+void main()
+{
+	vec4 colour = texture2D(s_texture, v_texCoord);
+	gl_FragColor = vec4(colour.z, colour.y, colour.x, 1.0);
+}

File gb_emulator/src/gb_video_opengl_es2.cpp

View file
 #include <string>
 #include <system_error>
 
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/split.hpp>
 #include <boost/filesystem/fstream.hpp>
 #include <boost/filesystem/operations.hpp>
 
 fragmentShader_(0),
 vertexBuffer_(0),
 texture_(0),
+pixelFormat_(0),
 installDir_(installDir),
 unscaledPixelBuffer_(new uint32_t[WIDTH * HEIGHT]),
 scaledPixelBuffer_(new uint32_t[SCALED_WIDTH * SCALED_HEIGHT]),
 
 	// Upload the texture into video memory
 	glBindTexture(GL_TEXTURE_2D, texture_);
-	glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, SCALED_WIDTH, SCALED_HEIGHT, GL_BGRA_EXT,
+	glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, SCALED_WIDTH, SCALED_HEIGHT, pixelFormat_,
 		GL_UNSIGNED_BYTE, scaledPixelBuffer_.get());
 
 	// Update the display
 	// Disable vsync
 	eglSwapInterval(display_, 0);
 
+	// Get supported extensions
+	const GLubyte *extensions = glGetString(GL_EXTENSIONS);
+	string extensionsStr = reinterpret_cast<const char *>(extensions);
+	boost::split(extensions_, extensionsStr, boost::is_any_of(" "));
+
+	// Use BGRA if available so we don't have to convert manually to RGBA
+	if (std::find(extensions_.begin(), extensions_.end(), "GL_EXT_texture_format_BGRA8888") !=
+		extensions_.end())
+	{
+		pixelFormat_ = GL_BGRA_EXT;
+	}
+	else
+	{
+		pixelFormat_ = GL_RGBA;
+	}
+
 	// Set the viewport
 	glViewport(0, 0, width, height);
 
 	// Create the texture
 	glGenTextures(1, &texture_);
 	glBindTexture(GL_TEXTURE_2D, texture_);
-	glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_BGRA_EXT,
+	glTexImage2D(GL_TEXTURE_2D, 0, pixelFormat_, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, pixelFormat_,
 		GL_UNSIGNED_BYTE, textureBuffer_.get());
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 	// Compile the shaders
 	vertexShader_ = compileShader(GL_VERTEX_SHADER,
 		installDir_ / "shaders/gles2/vertex_shader.glsl");
-	fragmentShader_ = compileShader(GL_FRAGMENT_SHADER,
-		installDir_ / "shaders/gles2/fragment_shader.glsl");
+
+	// We have to use an alternate fragment shader if we can't use BGRA to flip the colours manually
+	fs::path fragmentShaderPath;
+	if (pixelFormat_ == GL_BGRA_EXT)
+	{
+		fragmentShaderPath = installDir_ / "shaders/gles2/fragment_shader.glsl";
+	}
+	else
+	{
+		fragmentShaderPath = installDir_ / "shaders/gles2/fragment_flip_shader.glsl";
+	}
+	fragmentShader_ = compileShader(GL_FRAGMENT_SHADER, fragmentShaderPath);
 
 	// Link the shaders
 	program_ = glCreateProgram();