| 
									
										
										
										
											2013-04-17 23:29:41 -04:00
										 |  |  | // Copyright 2013 Dolphin Emulator Project
 | 
					
						
							|  |  |  | // Licensed under GPLv2
 | 
					
						
							|  |  |  | // Refer to the license.txt file included.
 | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | #include "Common/Common.h"
 | 
					
						
							|  |  |  | #include "Common/MemoryUtil.h"
 | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-01 23:21:03 -07:00
										 |  |  | #include "VideoBackends/OGL/GLInterfaceBase.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | #include "VideoBackends/Software/BPMemLoader.h"
 | 
					
						
							|  |  |  | #include "VideoBackends/Software/DebugUtil.h"
 | 
					
						
							|  |  |  | #include "VideoBackends/Software/HwRasterizer.h"
 | 
					
						
							|  |  |  | #include "VideoBackends/Software/NativeVertexFormat.h"
 | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | #include "VideoCommon/VideoCommon.h"
 | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define TEMP_SIZE (1024*1024*4)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace HwRasterizer | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-07-08 15:58:25 +02:00
										 |  |  | 	static float efbHalfWidth; | 
					
						
							|  |  |  | 	static float efbHalfHeight; | 
					
						
							|  |  |  | 	static bool hasTexture; | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 15:58:25 +02:00
										 |  |  | 	static u8 *temp; | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 	// Programs
 | 
					
						
							|  |  |  | 	static GLuint colProg, texProg, clearProg; | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-18 04:11:59 +00:00
										 |  |  | 	// Texture type
 | 
					
						
							|  |  |  | 	static GLenum texType; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 	// Color
 | 
					
						
							|  |  |  | 	static GLint col_apos = -1, col_atex = -1; | 
					
						
							|  |  |  | 	// Tex
 | 
					
						
							|  |  |  | 	static GLint tex_apos = -1, tex_atex = -1, tex_utex = -1; | 
					
						
							|  |  |  | 	// Clear shader
 | 
					
						
							|  |  |  | 	static GLint clear_apos = -1, clear_ucol = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 14:29:26 +02:00
										 |  |  | 	static void CreateShaders() | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		// Color Vertices
 | 
					
						
							|  |  |  | 		static const char *fragcolText = | 
					
						
							| 
									
										
										
										
											2014-03-29 13:10:43 -07:00
										 |  |  | 			"#ifdef GL_ES\n" | 
					
						
							| 
									
										
										
										
											2014-01-18 04:11:59 +00:00
										 |  |  | 			"precision highp float;\n" | 
					
						
							|  |  |  | 			"#endif\n" | 
					
						
							|  |  |  | 			"varying vec4 TexCoordOut;\n" | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 			"void main() {\n" | 
					
						
							|  |  |  | 			"	gl_FragColor = TexCoordOut;\n" | 
					
						
							|  |  |  | 			"}\n"; | 
					
						
							|  |  |  | 		// Texture Vertices
 | 
					
						
							|  |  |  | 		static const char *fragtexText = | 
					
						
							| 
									
										
										
										
											2014-03-29 13:10:43 -07:00
										 |  |  | 			"#ifdef GL_ES\n" | 
					
						
							| 
									
										
										
										
											2014-01-18 04:11:59 +00:00
										 |  |  | 			"precision highp float;\n" | 
					
						
							|  |  |  | 			"#define texture2DRect texture2D\n" | 
					
						
							|  |  |  | 			"#define sampler2DRect sampler2D\n" | 
					
						
							|  |  |  | 			"#endif\n" | 
					
						
							|  |  |  | 			"varying vec4 TexCoordOut;\n" | 
					
						
							|  |  |  | 			"uniform sampler2DRect Texture;\n" | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 			"void main() {\n" | 
					
						
							| 
									
										
										
										
											2014-01-18 04:11:59 +00:00
										 |  |  | 			"	gl_FragColor = texture2DRect(Texture, TexCoordOut.xy);\n" | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 			"}\n"; | 
					
						
							|  |  |  | 		// Clear shader
 | 
					
						
							| 
									
										
										
										
											2013-01-29 23:24:51 -06:00
										 |  |  | 		static const char *fragclearText = | 
					
						
							| 
									
										
										
										
											2014-03-29 13:10:43 -07:00
										 |  |  | 			"#ifdef GL_ES\n" | 
					
						
							| 
									
										
										
										
											2014-01-18 04:11:59 +00:00
										 |  |  | 			"precision highp float;\n" | 
					
						
							|  |  |  | 			"#endif\n" | 
					
						
							|  |  |  | 			"uniform vec4 Color;\n" | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 			"void main() {\n" | 
					
						
							|  |  |  | 			"	gl_FragColor = Color;\n" | 
					
						
							|  |  |  | 			"}\n"; | 
					
						
							|  |  |  | 		// Generic passthrough vertice shaders
 | 
					
						
							|  |  |  | 		static const char *vertShaderText = | 
					
						
							|  |  |  | 			"attribute vec4 pos;\n" | 
					
						
							|  |  |  | 			"attribute vec4 TexCoordIn;\n " | 
					
						
							|  |  |  | 			"varying vec4 TexCoordOut;\n " | 
					
						
							|  |  |  | 			"void main() {\n" | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 			"	gl_Position = pos;\n" | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 			"	TexCoordOut = TexCoordIn;\n" | 
					
						
							|  |  |  | 			"}\n"; | 
					
						
							| 
									
										
										
										
											2013-01-29 23:24:51 -06:00
										 |  |  | 		static const char *vertclearText = | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 			"attribute vec4 pos;\n" | 
					
						
							|  |  |  | 			"void main() {\n" | 
					
						
							|  |  |  | 			"	gl_Position = pos;\n" | 
					
						
							|  |  |  | 			"}\n"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Color Program
 | 
					
						
							|  |  |  | 		colProg = OpenGL_CompileProgram(vertShaderText, fragcolText); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Texture Program
 | 
					
						
							|  |  |  | 		texProg = OpenGL_CompileProgram(vertShaderText, fragtexText); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Clear Program
 | 
					
						
							|  |  |  | 		clearProg = OpenGL_CompileProgram(vertclearText, fragclearText); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Color attributes
 | 
					
						
							|  |  |  | 		col_apos = glGetAttribLocation(colProg, "pos"); | 
					
						
							| 
									
										
										
										
											2013-01-29 23:24:51 -06:00
										 |  |  | 		col_atex = glGetAttribLocation(colProg, "TexCoordIn"); | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 		// Texture attributes
 | 
					
						
							|  |  |  | 		tex_apos = glGetAttribLocation(texProg, "pos"); | 
					
						
							| 
									
										
										
										
											2013-01-29 23:24:51 -06:00
										 |  |  | 		tex_atex = glGetAttribLocation(texProg, "TexCoordIn"); | 
					
						
							|  |  |  | 		tex_utex = glGetUniformLocation(texProg, "Texture"); | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 		// Clear attributes
 | 
					
						
							|  |  |  | 		clear_apos = glGetAttribLocation(clearProg, "pos"); | 
					
						
							|  |  |  | 		clear_ucol = glGetUniformLocation(clearProg, "Color"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 	void Init() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		efbHalfWidth = EFB_WIDTH / 2.0f; | 
					
						
							|  |  |  | 		efbHalfHeight = 480 / 2.0f; | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 		temp = (u8*)AllocateMemoryPages(TEMP_SIZE); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 	void Shutdown() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		glDeleteProgram(colProg); | 
					
						
							|  |  |  | 		glDeleteProgram(texProg); | 
					
						
							|  |  |  | 		glDeleteProgram(clearProg); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	void Prepare() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		//legacy multitexturing: select texture channel only.
 | 
					
						
							|  |  |  | 		glActiveTexture(GL_TEXTURE0); | 
					
						
							|  |  |  | 		glPixelStorei(GL_UNPACK_ALIGNMENT, 4);  // 4-byte pixel alignment
 | 
					
						
							| 
									
										
										
										
											2014-01-18 04:11:59 +00:00
										 |  |  | 		if (GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGL) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			glShadeModel(GL_SMOOTH); | 
					
						
							|  |  |  | 			glDisable(GL_BLEND); | 
					
						
							|  |  |  | 			glClearDepth(1.0f); | 
					
						
							|  |  |  | 			glEnable(GL_SCISSOR_TEST); | 
					
						
							|  |  |  | 			glDisable(GL_LIGHTING); | 
					
						
							|  |  |  | 			glMatrixMode(GL_PROJECTION); | 
					
						
							|  |  |  | 			glLoadIdentity(); | 
					
						
							|  |  |  | 			glMatrixMode(GL_MODELVIEW); | 
					
						
							|  |  |  | 			glLoadIdentity(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			glClientActiveTexture(GL_TEXTURE0); | 
					
						
							|  |  |  | 			glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); | 
					
						
							|  |  |  | 			glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | 
					
						
							|  |  |  | 			glEnable(GL_TEXTURE_RECTANGLE_ARB); | 
					
						
							|  |  |  | 			glStencilFunc(GL_ALWAYS, 0, 0); | 
					
						
							|  |  |  | 			glDisable(GL_STENCIL_TEST); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 		// used by hw rasterizer if it enables blending and depth test
 | 
					
						
							|  |  |  | 		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | 
					
						
							|  |  |  | 		glDepthFunc(GL_LEQUAL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		glClearColor(0.0f, 0.0f, 0.0f, 0.0f); | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 		CreateShaders(); | 
					
						
							| 
									
										
										
										
											2014-01-18 04:11:59 +00:00
										 |  |  | 		if (GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGL) | 
					
						
							|  |  |  | 			texType = GL_TEXTURE_RECTANGLE; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			texType = GL_TEXTURE_2D; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 		GL_REPORT_ERRORD(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	static float width, height; | 
					
						
							| 
									
										
										
										
											2014-07-08 14:29:26 +02:00
										 |  |  | 	static void LoadTexture() | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		FourTexUnits &texUnit = bpmem.tex[0]; | 
					
						
							|  |  |  | 		u32 imageAddr = texUnit.texImage3[0].image_base; | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 		// Texture Rectangle uses pixel coordinates
 | 
					
						
							|  |  |  | 		// While GLES uses texture coordinates
 | 
					
						
							| 
									
										
										
										
											2014-01-18 04:11:59 +00:00
										 |  |  | 		if (GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGL) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2014-02-16 16:59:26 +01:00
										 |  |  | 			width = (float)texUnit.texImage0[0].width; | 
					
						
							|  |  |  | 			height = (float)texUnit.texImage0[0].height; | 
					
						
							| 
									
										
										
										
											2014-01-18 04:11:59 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			width = 1; | 
					
						
							|  |  |  | 			height = 1; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 		TexCacheEntry &cacheEntry = textures[imageAddr]; | 
					
						
							|  |  |  | 		cacheEntry.Update(); | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-18 04:11:59 +00:00
										 |  |  | 		glBindTexture(texType, cacheEntry.texture); | 
					
						
							|  |  |  | 		glTexParameteri(texType, GL_TEXTURE_MAG_FILTER, texUnit.texMode0[0].mag_filter ? GL_LINEAR : GL_NEAREST); | 
					
						
							|  |  |  | 		glTexParameteri(texType, GL_TEXTURE_MIN_FILTER, (texUnit.texMode0[0].min_filter >= 4) ? GL_LINEAR : GL_NEAREST); | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 		GL_REPORT_ERRORD(); | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 	void BeginTriangles() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		// disabling depth test sometimes allows more things to be visible
 | 
					
						
							|  |  |  | 		glEnable(GL_DEPTH_TEST); | 
					
						
							|  |  |  | 		glEnable(GL_BLEND); | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 		hasTexture = bpmem.tevorders[0].enable0; | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 		if (hasTexture) | 
					
						
							| 
									
										
										
										
											2013-01-29 23:24:51 -06:00
										 |  |  | 			LoadTexture(); | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 	void EndTriangles() | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2014-01-18 04:11:59 +00:00
										 |  |  | 		glBindTexture(texType, 0); | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 		glDisable(GL_DEPTH_TEST); | 
					
						
							|  |  |  | 		glDisable(GL_BLEND); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 14:29:26 +02:00
										 |  |  | 	static void DrawColorVertex(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2) | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 		float x0 = (v0->screenPosition.x / efbHalfWidth) - 1.0f; | 
					
						
							|  |  |  | 		float y0 = 1.0f - (v0->screenPosition.y / efbHalfHeight); | 
					
						
							|  |  |  | 		float z0 = v0->screenPosition.z / (float)0x00ffffff; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		float x1 = (v1->screenPosition.x / efbHalfWidth) - 1.0f; | 
					
						
							|  |  |  | 		float y1 = 1.0f - (v1->screenPosition.y / efbHalfHeight); | 
					
						
							|  |  |  | 		float z1 = v1->screenPosition.z / (float)0x00ffffff; | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 		float x2 = (v2->screenPosition.x / efbHalfWidth) - 1.0f; | 
					
						
							|  |  |  | 		float y2 = 1.0f - (v2->screenPosition.y / efbHalfHeight); | 
					
						
							|  |  |  | 		float z2 = v2->screenPosition.z / (float)0x00ffffff; | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 		float r0 = v0->color[0][OutputVertexData::RED_C] / 255.0f; | 
					
						
							| 
									
										
										
										
											2013-01-29 23:24:51 -06:00
										 |  |  | 		float g0 = v0->color[0][OutputVertexData::GRN_C] / 255.0f; | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 		float b0 = v0->color[0][OutputVertexData::BLU_C] / 255.0f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		float r1 = v1->color[0][OutputVertexData::RED_C] / 255.0f; | 
					
						
							| 
									
										
										
										
											2013-01-29 23:24:51 -06:00
										 |  |  | 		float g1 = v1->color[0][OutputVertexData::GRN_C] / 255.0f; | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 		float b1 = v1->color[0][OutputVertexData::BLU_C] / 255.0f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		float r2 = v2->color[0][OutputVertexData::RED_C] / 255.0f; | 
					
						
							| 
									
										
										
										
											2013-01-29 23:24:51 -06:00
										 |  |  | 		float g2 = v2->color[0][OutputVertexData::GRN_C] / 255.0f; | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 		float b2 = v2->color[0][OutputVertexData::BLU_C] / 255.0f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		static const GLfloat verts[3][3] = { | 
					
						
							|  |  |  | 			{ x0, y0, z0 }, | 
					
						
							|  |  |  | 			{ x1, y1, z1 }, | 
					
						
							|  |  |  | 			{ x2, y2, z2 } | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		static const GLfloat col[3][4] = { | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 			{ r0, g0, b0, 1.0f }, | 
					
						
							|  |  |  | 			{ r1, g1, b1, 1.0f }, | 
					
						
							|  |  |  | 			{ r2, g2, b2, 1.0f } | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			glUseProgram(colProg); | 
					
						
							|  |  |  | 			glEnableVertexAttribArray(col_apos); | 
					
						
							|  |  |  | 			glEnableVertexAttribArray(col_atex); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			glVertexAttribPointer(col_apos, 3, GL_FLOAT, GL_FALSE, 0, verts); | 
					
						
							|  |  |  | 			glVertexAttribPointer(col_atex, 4, GL_FLOAT, GL_FALSE, 0, col); | 
					
						
							|  |  |  | 				glDrawArrays(GL_TRIANGLES, 0, 3); | 
					
						
							|  |  |  | 			glDisableVertexAttribArray(col_atex); | 
					
						
							|  |  |  | 			glDisableVertexAttribArray(col_apos); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		GL_REPORT_ERRORD(); | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 14:29:26 +02:00
										 |  |  | 	static void DrawTextureVertex(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2) | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 		float x0 = (v0->screenPosition.x / efbHalfWidth) - 1.0f; | 
					
						
							|  |  |  | 		float y0 = 1.0f - (v0->screenPosition.y / efbHalfHeight); | 
					
						
							|  |  |  | 		float z0 = v0->screenPosition.z; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		float x1 = (v1->screenPosition.x / efbHalfWidth) - 1.0f; | 
					
						
							|  |  |  | 		float y1 = 1.0f - (v1->screenPosition.y / efbHalfHeight); | 
					
						
							|  |  |  | 		float z1 = v1->screenPosition.z; | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 		float x2 = (v2->screenPosition.x / efbHalfWidth) - 1.0f; | 
					
						
							|  |  |  | 		float y2 = 1.0f - (v2->screenPosition.y / efbHalfHeight); | 
					
						
							|  |  |  | 		float z2 = v2->screenPosition.z; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		float s0 = v0->texCoords[0].x / width; | 
					
						
							|  |  |  | 		float t0 = v0->texCoords[0].y / height; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		float s1 = v1->texCoords[0].x / width; | 
					
						
							|  |  |  | 		float t1 = v1->texCoords[0].y / height; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		float s2 = v2->texCoords[0].x / width; | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 		float t2 = v2->texCoords[0].y / height; | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		static const GLfloat verts[3][3] = { | 
					
						
							|  |  |  | 			{ x0, y0, z0 }, | 
					
						
							|  |  |  | 			{ x1, y1, z1 }, | 
					
						
							|  |  |  | 			{ x2, y2, z2 } | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		static const GLfloat tex[3][2] = { | 
					
						
							|  |  |  | 			{ s0, t0 }, | 
					
						
							|  |  |  | 			{ s1, t1 }, | 
					
						
							|  |  |  | 			{ s2, t2 } | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			glUseProgram(texProg); | 
					
						
							|  |  |  | 			glEnableVertexAttribArray(tex_apos); | 
					
						
							|  |  |  | 			glEnableVertexAttribArray(tex_atex); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			glVertexAttribPointer(tex_apos, 3, GL_FLOAT, GL_FALSE, 0, verts); | 
					
						
							|  |  |  | 			glVertexAttribPointer(tex_atex, 2, GL_FLOAT, GL_FALSE, 0, tex); | 
					
						
							|  |  |  | 				glUniform1i(tex_utex, 0); | 
					
						
							|  |  |  | 				glDrawArrays(GL_TRIANGLES, 0, 3); | 
					
						
							|  |  |  | 			glDisableVertexAttribArray(tex_atex); | 
					
						
							|  |  |  | 			glDisableVertexAttribArray(tex_apos); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		GL_REPORT_ERRORD(); | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 	void DrawTriangleFrontFace(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 		if (hasTexture) | 
					
						
							|  |  |  | 			DrawTextureVertex(v0, v1, v2); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			DrawColorVertex(v0, v1, v2); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 	void Clear() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		u8 r = (bpmem.clearcolorAR & 0x00ff); | 
					
						
							|  |  |  | 		u8 g = (bpmem.clearcolorGB & 0xff00) >> 8; | 
					
						
							|  |  |  | 		u8 b = (bpmem.clearcolorGB & 0x00ff); | 
					
						
							|  |  |  | 		u8 a = (bpmem.clearcolorAR & 0xff00) >> 8; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		GLfloat left   = (GLfloat)bpmem.copyTexSrcXY.x / efbHalfWidth - 1.0f; | 
					
						
							|  |  |  | 		GLfloat top    = 1.0f - (GLfloat)bpmem.copyTexSrcXY.y / efbHalfHeight; | 
					
						
							|  |  |  | 		GLfloat right  = (GLfloat)(left + bpmem.copyTexSrcWH.x + 1) / efbHalfWidth - 1.0f; | 
					
						
							|  |  |  | 		GLfloat bottom = 1.0f - (GLfloat)(top + bpmem.copyTexSrcWH.y + 1) / efbHalfHeight; | 
					
						
							|  |  |  | 		GLfloat depth = (GLfloat)bpmem.clearZValue / (GLfloat)0x00ffffff; | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 		static const GLfloat verts[4][3] = { | 
					
						
							|  |  |  | 			{ left, top, depth }, | 
					
						
							|  |  |  | 			{ right, top, depth }, | 
					
						
							|  |  |  | 			{ right, bottom, depth }, | 
					
						
							|  |  |  | 			{ left, bottom, depth } | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			glUseProgram(clearProg); | 
					
						
							|  |  |  | 			glVertexAttribPointer(clear_apos, 3, GL_FLOAT, GL_FALSE, 0, verts); | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 			glUniform4f(clear_ucol, r, g, b, a); | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 			glEnableVertexAttribArray(col_apos); | 
					
						
							|  |  |  | 				glDrawArrays(GL_TRIANGLE_FAN, 0, 4); | 
					
						
							|  |  |  | 			glDisableVertexAttribArray(col_apos); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		GL_REPORT_ERRORD(); | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 	TexCacheEntry::TexCacheEntry() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		Create(); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 	void TexCacheEntry::Create() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		FourTexUnits &texUnit = bpmem.tex[0]; | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 		texImage0.hex = texUnit.texImage0[0].hex; | 
					
						
							|  |  |  | 		texImage1.hex = texUnit.texImage1[0].hex; | 
					
						
							|  |  |  | 		texImage2.hex = texUnit.texImage2[0].hex; | 
					
						
							|  |  |  | 		texImage3.hex = texUnit.texImage3[0].hex; | 
					
						
							|  |  |  | 		texTlut.hex = texUnit.texTlut[0].hex; | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-29 23:24:51 -06:00
										 |  |  | 		int image_width = texImage0.width; | 
					
						
							|  |  |  | 		int image_height = texImage0.height; | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-16 15:59:59 +13:00
										 |  |  | 		DebugUtil::GetTextureRGBA(temp, 0, 0, image_width, image_height); | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 		glGenTextures(1, (GLuint *)&texture); | 
					
						
							| 
									
										
										
										
											2014-01-18 04:11:59 +00:00
										 |  |  | 		glBindTexture(texType, texture); | 
					
						
							|  |  |  | 		glTexImage2D(texType, 0, GL_RGBA, (GLsizei)image_width, (GLsizei)image_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, temp); | 
					
						
							| 
									
										
										
										
											2013-11-16 15:59:59 +13:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-17 14:54:20 -06:00
										 |  |  | 		GL_REPORT_ERRORD(); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 	void TexCacheEntry::Destroy() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (texture == 0) | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		glDeleteTextures(1, &texture); | 
					
						
							|  |  |  | 		texture = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 	void TexCacheEntry::Update() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		FourTexUnits &texUnit = bpmem.tex[0]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// extra checks cause textures to be reloaded much more
 | 
					
						
							|  |  |  | 		if (texUnit.texImage0[0].hex != texImage0.hex || | 
					
						
							| 
									
										
										
										
											2013-04-13 23:54:02 -04:00
										 |  |  | 		//	texUnit.texImage1[0].hex != texImage1.hex ||
 | 
					
						
							|  |  |  | 		//	texUnit.texImage2[0].hex != texImage2.hex ||
 | 
					
						
							|  |  |  | 			texUnit.texImage3[0].hex != texImage3.hex || | 
					
						
							|  |  |  | 			texUnit.texTlut[0].hex   != texTlut.hex) | 
					
						
							| 
									
										
										
										
											2012-12-26 10:33:45 -06:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			Destroy(); | 
					
						
							|  |  |  | 			Create(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-06-09 01:37:08 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 |