diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index e8579accf..4cf748a52 100644 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -77,6 +77,13 @@ static void ENDGL() { #include "texcache.h" #include "utils/task.h" +enum OGLVertexAttributeID +{ + OGLVertexAttributeID_Position = 0, + OGLVertexAttributeID_TexCoord0 = 8, + OGLVertexAttributeID_Color = 3, +}; + static DS_ALIGN(16) u8 GPU_screen3D [256*192*4]; static bool gpuScreen3DHasNewData = false; @@ -422,7 +429,11 @@ static void createShaders() glAttachShader(shaderProgram, vertexShaderID); glAttachShader(shaderProgram, fragmentShaderID); - + + glBindAttribLocation(shaderProgram, OGLVertexAttributeID_Position, "inPosition"); + glBindAttribLocation(shaderProgram, OGLVertexAttributeID_TexCoord0, "inTexCoord0"); + glBindAttribLocation(shaderProgram, OGLVertexAttributeID_Color, "inColor"); + glLinkProgram(shaderProgram); PROGRAM_COMPCHECK(shaderProgram, vertexShaderID, fragmentShaderID); @@ -1311,40 +1322,63 @@ static void OGLRender() bool needVertexUpload = true; // Assign vertex attributes based on which OpenGL features we have. - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_VERTEX_ARRAY); - - if (isVBOSupported) + if (isShaderSupported && isVBOSupported) { - if (!isShaderSupported) - { - glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - glColorPointer(4, GL_FLOAT, 0, color4fBuffer); - } + glEnableVertexAttribArray(OGLVertexAttributeID_Position); + glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0); + glEnableVertexAttribArray(OGLVertexAttributeID_Color); glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboVertexID); glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(VERT) * gfx3d.vertlist->count, gfx3d.vertlist, GL_STREAM_DRAW_ARB); - glTexCoordPointer(2, GL_FLOAT, sizeof(VERT), (const GLvoid *)offsetof(VERT, texcoord)); - glVertexPointer(4, GL_FLOAT, sizeof(VERT), (const GLvoid *)offsetof(VERT, coord)); - - if (isShaderSupported) - { - glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VERT), (const GLvoid *)offsetof(VERT, color)); - } + glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_FLOAT, GL_FALSE, sizeof(VERT), (const GLvoid *)offsetof(VERT, coord)); + glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(VERT), (const GLvoid *)offsetof(VERT, texcoord)); + glVertexAttribPointer(OGLVertexAttributeID_Color, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VERT), (const GLvoid *)offsetof(VERT, color)); } else { - glTexCoordPointer(2, GL_FLOAT, sizeof(VERT), &gfx3d.vertlist->list[0].texcoord); - glVertexPointer(4, GL_FLOAT, sizeof(VERT), &gfx3d.vertlist->list[0].coord); - if (isShaderSupported) { - glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VERT), &gfx3d.vertlist->list[0].color); + glEnableVertexAttribArray(OGLVertexAttributeID_Position); + glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0); + glEnableVertexAttribArray(OGLVertexAttributeID_Color); + + if (isVBOSupported) + { + glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboVertexID); + glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(VERT) * gfx3d.vertlist->count, gfx3d.vertlist, GL_STREAM_DRAW_ARB); + glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_FLOAT, GL_FALSE, sizeof(VERT), (const GLvoid *)offsetof(VERT, coord)); + glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(VERT), (const GLvoid *)offsetof(VERT, texcoord)); + glVertexAttribPointer(OGLVertexAttributeID_Color, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VERT), (const GLvoid *)offsetof(VERT, color)); + } + else + { + glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_FLOAT, GL_FALSE, sizeof(VERT), &gfx3d.vertlist->list[0].coord); + glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(VERT), &gfx3d.vertlist->list[0].texcoord); + glVertexAttribPointer(OGLVertexAttributeID_Color, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VERT), &gfx3d.vertlist->list[0].color); + } } else { - glColorPointer(4, GL_FLOAT, 0, color4fBuffer); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + + if (isVBOSupported) + { + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + glColorPointer(4, GL_FLOAT, 0, color4fBuffer); + + glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboVertexID); + glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(VERT) * gfx3d.vertlist->count, gfx3d.vertlist, GL_STREAM_DRAW_ARB); + glVertexPointer(4, GL_FLOAT, sizeof(VERT), (const GLvoid *)offsetof(VERT, coord)); + glTexCoordPointer(2, GL_FLOAT, sizeof(VERT), (const GLvoid *)offsetof(VERT, texcoord)); + } + else + { + glVertexPointer(4, GL_FLOAT, sizeof(VERT), &gfx3d.vertlist->list[0].coord); + glTexCoordPointer(2, GL_FLOAT, sizeof(VERT), &gfx3d.vertlist->list[0].texcoord); + glColorPointer(4, GL_FLOAT, 0, color4fBuffer); + } } } @@ -1488,14 +1522,28 @@ static void OGLRender() } } - if (isVBOSupported) + if (isShaderSupported) { - glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + if (isVBOSupported) + { + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + } + + glDisableVertexAttribArray(OGLVertexAttributeID_Position); + glDisableVertexAttribArray(OGLVertexAttributeID_TexCoord0); + glDisableVertexAttribArray(OGLVertexAttributeID_Color); + } + else + { + if (isVBOSupported) + { + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + } + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); } - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); } //needs to happen before endgl because it could free some textureids for expired cache items diff --git a/desmume/src/shaders.h b/desmume/src/shaders.h index 060684610..53b35203c 100644 --- a/desmume/src/shaders.h +++ b/desmume/src/shaders.h @@ -19,27 +19,33 @@ /* Vertex shader */ const char *vertexShader = {"\ + attribute vec4 inPosition; \n\ + attribute vec2 inTexCoord0; \n\ + attribute vec3 inColor; \n\ + \n\ uniform float polyAlpha; \n\ uniform vec2 texScale; \n\ - varying vec4 pos; \n\ + \n\ + varying vec4 vtxPosition; \n\ + varying vec2 vtxTexCoord; \n\ varying vec4 vtxColor; \n\ + \n\ void main() \n\ { \n\ + // Keep the projection matrix as a placeholder in case we need to use one in the future. \n\ mat4 projectionMtx = mat4( vec4(1.0, 0.0, 0.0, 0.0), \n\ vec4(0.0, 1.0, 0.0, 0.0), \n\ vec4(0.0, 0.0, 1.0, 0.0), \n\ vec4(0.0, 0.0, 0.0, 1.0));\n\ \n\ - mat4 texScaleMtx = mat4( vec4(texScale.x, 0.0, 0.0, 0.0), \n\ - vec4( 0.0, texScale.y, 0.0, 0.0), \n\ - vec4( 0.0, 0.0, 1.0, 0.0), \n\ - vec4( 0.0, 0.0, 0.0, 1.0)); \n\ + mat2 texScaleMtx = mat2( vec2(texScale.x, 0.0), \n\ + vec2( 0.0, texScale.y)); \n\ \n\ - vtxColor = vec4(gl_Color.rgb * 4.0, polyAlpha); \n\ - gl_Position = projectionMtx * gl_Vertex; \n\ - gl_TexCoord[0] = texScaleMtx * gl_MultiTexCoord0; \n\ - gl_FrontColor = vtxColor; \n\ - pos = gl_Position; \n\ + vtxPosition = projectionMtx * inPosition; \n\ + vtxTexCoord = texScaleMtx * inTexCoord0; \n\ + vtxColor = vec4(inColor * 4.0, polyAlpha); \n\ + \n\ + gl_Position = vtxPosition; \n\ } \n\ "}; @@ -53,7 +59,8 @@ const char *fragmentShader = {"\ uniform bool enableAlphaTest; \n\ uniform float alphaTestRef; \n\ \n\ - varying vec4 pos; \n\ + varying vec4 vtxPosition; \n\ + varying vec2 vtxTexCoord; \n\ varying vec4 vtxColor; \n\ \n\ void main() \n\ @@ -63,7 +70,7 @@ const char *fragmentShader = {"\ \n\ if(hasTexture) \n\ { \n\ - texColor = texture2D(tex2d, gl_TexCoord[0].st); \n\ + texColor = texture2D(tex2d, vtxTexCoord); \n\ } \n\ \n\ flagColor = texColor; \n\ @@ -110,11 +117,11 @@ const char *fragmentShader = {"\ if (oglWBuffer == 1) \n\ { \n\ // TODO \n\ - gl_FragDepth = (pos.z / pos.w) * 0.5 + 0.5; \n\ + gl_FragDepth = (vtxPosition.z / vtxPosition.w) * 0.5 + 0.5; \n\ } \n\ else \n\ { \n\ - gl_FragDepth = (pos.z / pos.w) * 0.5 + 0.5; \n\ + gl_FragDepth = (vtxPosition.z / vtxPosition.w) * 0.5 + 0.5; \n\ } \n\ \n\ gl_FragColor = flagColor; \n\