Browse Source

love.graphics Video code is upwards-compatible with GL3.

--HG--
branch : minor
Alex Szpakowski 8 years ago
parent
commit
66749e874f
2 changed files with 48 additions and 19 deletions
  1. 16 3
      src/modules/graphics/opengl/OpenGL.cpp
  2. 32 16
      src/modules/graphics/opengl/Video.cpp

+ 16 - 3
src/modules/graphics/opengl/OpenGL.cpp

@@ -740,8 +740,16 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
 	switch (pixelformat)
 	{
 	case PIXELFORMAT_R8:
-		f.internalformat = GL_R8;
-		f.externalformat = GL_RED;
+		if (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_ARB_texture_rg || GLAD_EXT_texture_rg)
+		{
+			f.internalformat = GL_R8;
+			f.externalformat = GL_RED;
+		}
+		else
+		{
+			f.internalformat = GL_LUMINANCE8;
+			f.externalformat = GL_LUMINANCE;
+		}
 		f.type = GL_UNSIGNED_BYTE;
 		break;
 	case PIXELFORMAT_RG8:
@@ -1001,7 +1009,12 @@ bool OpenGL::isPixelFormatSupported(PixelFormat pixelformat, bool rendertarget,
 	{
 	case PIXELFORMAT_R8:
 	case PIXELFORMAT_RG8:
-		return GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_ARB_texture_rg || GLAD_EXT_texture_rg;
+		if (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_ARB_texture_rg || GLAD_EXT_texture_rg)
+			return true;
+		else if (pixelformat == PIXELFORMAT_R8 && !rendertarget && (GLAD_ES_VERSION_2_0 || GLAD_VERSION_1_1))
+			return true; // We'll use OpenGL's luminance format internally.
+		else
+			return false;
 	case PIXELFORMAT_RGBA8:
 		if (rendertarget)
 			return GLAD_VERSION_1_0 || GLAD_ES_VERSION_3_0 || GLAD_OES_rgb8_rgba8 || GLAD_ARM_rgba8;

+ 32 - 16
src/modules/graphics/opengl/Video.cpp

@@ -78,7 +78,7 @@ Video::~Video()
 
 bool Video::loadVolatile()
 {
-	glGenTextures(3, &textures[0]);
+	glGenTextures(3, textures);
 
 	// Create the textures using the initial frame data.
 	auto frame = (const love::video::VideoStream::Frame*) stream->getFrontBuffer();
@@ -90,6 +90,9 @@ bool Video::loadVolatile()
 
 	Texture::Wrap wrap; // Clamp wrap mode.
 
+	bool srgb = false;
+	OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(PIXELFORMAT_R8, false, srgb);
+
 	for (int i = 0; i < 3; i++)
 	{
 		gl.bindTextureToUnit(textures[i], 0, false);
@@ -97,8 +100,8 @@ bool Video::loadVolatile()
 		gl.setTextureFilter(filter);
 		gl.setTextureWrap(wrap);
 
-		glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, widths[i], heights[i], 0,
-		             GL_LUMINANCE, GL_UNSIGNED_BYTE, data[i]);
+		glTexImage2D(GL_TEXTURE_2D, 0, fmt.internalformat, widths[i], heights[i],
+		             0, fmt.externalformat, fmt.type, data[i]);
 	}
 
 	return true;
@@ -125,29 +128,39 @@ void Video::draw(Graphics *gfx, const Matrix4 &m)
 	gfx->flushStreamDraws();
 
 	Shader *shader = (Shader *) Shader::current;
-	bool defaultShader = (shader == Shader::defaultShader);
-	if (defaultShader)
+	bool usingdefaultshader = (shader == Shader::defaultShader);
+	if (usingdefaultshader)
 	{
-		// If we're still using the default shader, substitute the video version
+		// If we're using the default shader, substitute the video version.
 		Shader::defaultVideoShader->attach();
 		shader = (Shader *) Shader::defaultVideoShader;
 	}
 
 	shader->setVideoTextures(textures[0], textures[1], textures[2]);
 
-	Graphics::TempTransform transform(gfx, m);
+	Graphics::StreamDrawRequest req;
+	req.formats[0] = vertex::CommonFormat::XYf_STf_RGBAub;
+	req.indexMode = vertex::TriangleIndexMode::QUADS;
+	req.vertexCount = 4;
+
+	Graphics::StreamVertexData data = gfx->requestStreamDraw(req);
+	Vertex *verts = (Vertex *) data.stream[0];
 
-	gl.useVertexAttribArrays(ATTRIBFLAG_POS | ATTRIBFLAG_TEXCOORD);
+	Matrix4 t(gfx->getTransform(), m);
+	t.transform(verts, vertices, 4);
 
-	gl.bindBuffer(BUFFER_VERTEX, 0);
-	glVertexAttribPointer(ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), &vertices[0].x);
-	glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), &vertices[0].s);
+	Color c = toColor(gfx->getColor());
+
+	for (int i = 0; i < 4; i++)
+	{
+		verts[i].s = vertices[i].s;
+		verts[i].t = vertices[i].t;
+		verts[i].color = c;
+	}
 
-	gl.prepareDraw();
-	gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
+	gfx->flushStreamDraws();
 
-	// If we were using the default shader, reattach it
-	if (defaultShader)
+	if (usingdefaultshader)
 		Shader::defaultShader->attach();
 }
 
@@ -165,11 +178,14 @@ void Video::update()
 
 		const unsigned char *data[3] = {frame->yplane, frame->cbplane, frame->crplane};
 
+		bool srgb = false;
+		OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(PIXELFORMAT_R8, false, srgb);
+
 		for (int i = 0; i < 3; i++)
 		{
 			gl.bindTextureToUnit(textures[i], 0, false);
 			glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, widths[i], heights[i],
-			                GL_LUMINANCE, GL_UNSIGNED_BYTE, data[i]);
+			                fmt.externalformat, fmt.type, data[i]);
 		}
 	}
 }