summaryrefslogtreecommitdiff
path: root/source/3rd-party/SDL2/src/render/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'source/3rd-party/SDL2/src/render/opengl')
-rw-r--r--source/3rd-party/SDL2/src/render/opengl/SDL_glfuncs.h478
-rw-r--r--source/3rd-party/SDL2/src/render/opengl/SDL_render_gl.c1678
-rw-r--r--source/3rd-party/SDL2/src/render/opengl/SDL_shaders_gl.c524
-rw-r--r--source/3rd-party/SDL2/src/render/opengl/SDL_shaders_gl.h53
4 files changed, 2733 insertions, 0 deletions
diff --git a/source/3rd-party/SDL2/src/render/opengl/SDL_glfuncs.h b/source/3rd-party/SDL2/src/render/opengl/SDL_glfuncs.h
new file mode 100644
index 0000000..02be0e1
--- /dev/null
+++ b/source/3rd-party/SDL2/src/render/opengl/SDL_glfuncs.h
@@ -0,0 +1,478 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/* list of OpenGL functions sorted alphabetically
+ If you need to use a GL function from the SDL video subsystem,
+ change its entry from SDL_PROC_UNUSED to SDL_PROC and rebuild.
+*/
+#define SDL_PROC_UNUSED(ret,func,params)
+
+SDL_PROC_UNUSED(void, glAccum, (GLenum, GLfloat))
+SDL_PROC_UNUSED(void, glAlphaFunc, (GLenum, GLclampf))
+SDL_PROC_UNUSED(GLboolean, glAreTexturesResident,
+ (GLsizei, const GLuint *, GLboolean *))
+SDL_PROC_UNUSED(void, glArrayElement, (GLint))
+SDL_PROC(void, glBegin, (GLenum))
+SDL_PROC(void, glBindTexture, (GLenum, GLuint))
+SDL_PROC_UNUSED(void, glBitmap,
+ (GLsizei, GLsizei, GLfloat, GLfloat, GLfloat, GLfloat,
+ const GLubyte *))
+SDL_PROC(void, glBlendEquation, (GLenum))
+SDL_PROC_UNUSED(void, glBlendFunc, (GLenum, GLenum))
+SDL_PROC(void, glBlendFuncSeparate, (GLenum, GLenum, GLenum, GLenum))
+SDL_PROC_UNUSED(void, glCallList, (GLuint))
+SDL_PROC_UNUSED(void, glCallLists, (GLsizei, GLenum, const GLvoid *))
+SDL_PROC(void, glClear, (GLbitfield))
+SDL_PROC_UNUSED(void, glClearAccum, (GLfloat, GLfloat, GLfloat, GLfloat))
+SDL_PROC(void, glClearColor, (GLclampf, GLclampf, GLclampf, GLclampf))
+SDL_PROC_UNUSED(void, glClearDepth, (GLclampd))
+SDL_PROC_UNUSED(void, glClearIndex, (GLfloat))
+SDL_PROC_UNUSED(void, glClearStencil, (GLint))
+SDL_PROC_UNUSED(void, glClipPlane, (GLenum, const GLdouble *))
+SDL_PROC_UNUSED(void, glColor3b, (GLbyte, GLbyte, GLbyte))
+SDL_PROC_UNUSED(void, glColor3bv, (const GLbyte *))
+SDL_PROC_UNUSED(void, glColor3d, (GLdouble, GLdouble, GLdouble))
+SDL_PROC_UNUSED(void, glColor3dv, (const GLdouble *))
+SDL_PROC_UNUSED(void, glColor3f, (GLfloat, GLfloat, GLfloat))
+SDL_PROC(void, glColor3fv, (const GLfloat *))
+SDL_PROC_UNUSED(void, glColor3i, (GLint, GLint, GLint))
+SDL_PROC_UNUSED(void, glColor3iv, (const GLint *))
+SDL_PROC_UNUSED(void, glColor3s, (GLshort, GLshort, GLshort))
+SDL_PROC_UNUSED(void, glColor3sv, (const GLshort *))
+SDL_PROC_UNUSED(void, glColor3ub, (GLubyte, GLubyte, GLubyte))
+SDL_PROC_UNUSED(void, glColor3ubv, (const GLubyte *))
+SDL_PROC_UNUSED(void, glColor3ui, (GLuint, GLuint, GLuint))
+SDL_PROC_UNUSED(void, glColor3uiv, (const GLuint *))
+SDL_PROC_UNUSED(void, glColor3us, (GLushort, GLushort, GLushort))
+SDL_PROC_UNUSED(void, glColor3usv, (const GLushort *))
+SDL_PROC_UNUSED(void, glColor4b, (GLbyte, GLbyte, GLbyte, GLbyte))
+SDL_PROC_UNUSED(void, glColor4bv, (const GLbyte *))
+SDL_PROC_UNUSED(void, glColor4d, (GLdouble, GLdouble, GLdouble, GLdouble))
+SDL_PROC_UNUSED(void, glColor4dv, (const GLdouble *))
+SDL_PROC(void, glColor4f, (GLfloat, GLfloat, GLfloat, GLfloat))
+SDL_PROC_UNUSED(void, glColor4fv, (const GLfloat *))
+SDL_PROC_UNUSED(void, glColor4i, (GLint, GLint, GLint, GLint))
+SDL_PROC_UNUSED(void, glColor4iv, (const GLint *))
+SDL_PROC_UNUSED(void, glColor4s, (GLshort, GLshort, GLshort, GLshort))
+SDL_PROC_UNUSED(void, glColor4sv, (const GLshort *))
+SDL_PROC_UNUSED(void, glColor4ub,
+ (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha))
+SDL_PROC_UNUSED(void, glColor4ubv, (const GLubyte * v))
+SDL_PROC_UNUSED(void, glColor4ui,
+ (GLuint red, GLuint green, GLuint blue, GLuint alpha))
+SDL_PROC_UNUSED(void, glColor4uiv, (const GLuint * v))
+SDL_PROC_UNUSED(void, glColor4us,
+ (GLushort red, GLushort green, GLushort blue, GLushort alpha))
+SDL_PROC_UNUSED(void, glColor4usv, (const GLushort * v))
+SDL_PROC_UNUSED(void, glColorMask,
+ (GLboolean red, GLboolean green, GLboolean blue,
+ GLboolean alpha))
+SDL_PROC_UNUSED(void, glColorMaterial, (GLenum face, GLenum mode))
+SDL_PROC_UNUSED(void, glColorPointer,
+ (GLint size, GLenum type, GLsizei stride,
+ const GLvoid * pointer))
+SDL_PROC_UNUSED(void, glCopyPixels,
+ (GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum type))
+SDL_PROC_UNUSED(void, glCopyTexImage1D,
+ (GLenum target, GLint level, GLenum internalFormat, GLint x,
+ GLint y, GLsizei width, GLint border))
+SDL_PROC_UNUSED(void, glCopyTexImage2D,
+ (GLenum target, GLint level, GLenum internalFormat, GLint x,
+ GLint y, GLsizei width, GLsizei height, GLint border))
+SDL_PROC_UNUSED(void, glCopyTexSubImage1D,
+ (GLenum target, GLint level, GLint xoffset, GLint x, GLint y,
+ GLsizei width))
+SDL_PROC_UNUSED(void, glCopyTexSubImage2D,
+ (GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height))
+SDL_PROC_UNUSED(void, glCullFace, (GLenum mode))
+SDL_PROC_UNUSED(void, glDeleteLists, (GLuint list, GLsizei range))
+SDL_PROC(void, glDeleteTextures, (GLsizei n, const GLuint * textures))
+SDL_PROC(void, glDepthFunc, (GLenum func))
+SDL_PROC_UNUSED(void, glDepthMask, (GLboolean flag))
+SDL_PROC_UNUSED(void, glDepthRange, (GLclampd zNear, GLclampd zFar))
+SDL_PROC(void, glDisable, (GLenum cap))
+SDL_PROC_UNUSED(void, glDisableClientState, (GLenum array))
+SDL_PROC_UNUSED(void, glDrawArrays, (GLenum mode, GLint first, GLsizei count))
+SDL_PROC_UNUSED(void, glDrawBuffer, (GLenum mode))
+SDL_PROC_UNUSED(void, glDrawElements,
+ (GLenum mode, GLsizei count, GLenum type,
+ const GLvoid * indices))
+SDL_PROC(void, glDrawPixels,
+ (GLsizei width, GLsizei height, GLenum format, GLenum type,
+ const GLvoid * pixels))
+SDL_PROC_UNUSED(void, glEdgeFlag, (GLboolean flag))
+SDL_PROC_UNUSED(void, glEdgeFlagPointer,
+ (GLsizei stride, const GLvoid * pointer))
+SDL_PROC_UNUSED(void, glEdgeFlagv, (const GLboolean * flag))
+SDL_PROC(void, glEnable, (GLenum cap))
+SDL_PROC_UNUSED(void, glEnableClientState, (GLenum array))
+SDL_PROC(void, glEnd, (void))
+SDL_PROC_UNUSED(void, glEndList, (void))
+SDL_PROC_UNUSED(void, glEvalCoord1d, (GLdouble u))
+SDL_PROC_UNUSED(void, glEvalCoord1dv, (const GLdouble * u))
+SDL_PROC_UNUSED(void, glEvalCoord1f, (GLfloat u))
+SDL_PROC_UNUSED(void, glEvalCoord1fv, (const GLfloat * u))
+SDL_PROC_UNUSED(void, glEvalCoord2d, (GLdouble u, GLdouble v))
+SDL_PROC_UNUSED(void, glEvalCoord2dv, (const GLdouble * u))
+SDL_PROC_UNUSED(void, glEvalCoord2f, (GLfloat u, GLfloat v))
+SDL_PROC_UNUSED(void, glEvalCoord2fv, (const GLfloat * u))
+SDL_PROC_UNUSED(void, glEvalMesh1, (GLenum mode, GLint i1, GLint i2))
+SDL_PROC_UNUSED(void, glEvalMesh2,
+ (GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2))
+SDL_PROC_UNUSED(void, glEvalPoint1, (GLint i))
+SDL_PROC_UNUSED(void, glEvalPoint2, (GLint i, GLint j))
+SDL_PROC_UNUSED(void, glFeedbackBuffer,
+ (GLsizei size, GLenum type, GLfloat * buffer))
+SDL_PROC_UNUSED(void, glFinish, (void))
+SDL_PROC_UNUSED(void, glFlush, (void))
+SDL_PROC_UNUSED(void, glFogf, (GLenum pname, GLfloat param))
+SDL_PROC_UNUSED(void, glFogfv, (GLenum pname, const GLfloat * params))
+SDL_PROC_UNUSED(void, glFogi, (GLenum pname, GLint param))
+SDL_PROC_UNUSED(void, glFogiv, (GLenum pname, const GLint * params))
+SDL_PROC_UNUSED(void, glFrontFace, (GLenum mode))
+SDL_PROC_UNUSED(void, glFrustum,
+ (GLdouble left, GLdouble right, GLdouble bottom,
+ GLdouble top, GLdouble zNear, GLdouble zFar))
+SDL_PROC_UNUSED(GLuint, glGenLists, (GLsizei range))
+SDL_PROC(void, glGenTextures, (GLsizei n, GLuint * textures))
+SDL_PROC_UNUSED(void, glGetBooleanv, (GLenum pname, GLboolean * params))
+SDL_PROC_UNUSED(void, glGetClipPlane, (GLenum plane, GLdouble * equation))
+SDL_PROC_UNUSED(void, glGetDoublev, (GLenum pname, GLdouble * params))
+SDL_PROC(GLenum, glGetError, (void))
+SDL_PROC_UNUSED(void, glGetFloatv, (GLenum pname, GLfloat * params))
+SDL_PROC(void, glGetIntegerv, (GLenum pname, GLint * params))
+SDL_PROC_UNUSED(void, glGetLightfv,
+ (GLenum light, GLenum pname, GLfloat * params))
+SDL_PROC_UNUSED(void, glGetLightiv,
+ (GLenum light, GLenum pname, GLint * params))
+SDL_PROC_UNUSED(void, glGetMapdv, (GLenum target, GLenum query, GLdouble * v))
+SDL_PROC_UNUSED(void, glGetMapfv, (GLenum target, GLenum query, GLfloat * v))
+SDL_PROC_UNUSED(void, glGetMapiv, (GLenum target, GLenum query, GLint * v))
+SDL_PROC_UNUSED(void, glGetMaterialfv,
+ (GLenum face, GLenum pname, GLfloat * params))
+SDL_PROC_UNUSED(void, glGetMaterialiv,
+ (GLenum face, GLenum pname, GLint * params))
+SDL_PROC_UNUSED(void, glGetPixelMapfv, (GLenum map, GLfloat * values))
+SDL_PROC_UNUSED(void, glGetPixelMapuiv, (GLenum map, GLuint * values))
+SDL_PROC_UNUSED(void, glGetPixelMapusv, (GLenum map, GLushort * values))
+SDL_PROC(void, glGetPointerv, (GLenum pname, GLvoid * *params))
+SDL_PROC_UNUSED(void, glGetPolygonStipple, (GLubyte * mask))
+SDL_PROC(const GLubyte *, glGetString, (GLenum name))
+SDL_PROC_UNUSED(void, glGetTexEnvfv,
+ (GLenum target, GLenum pname, GLfloat * params))
+SDL_PROC_UNUSED(void, glGetTexEnviv,
+ (GLenum target, GLenum pname, GLint * params))
+SDL_PROC_UNUSED(void, glGetTexGendv,
+ (GLenum coord, GLenum pname, GLdouble * params))
+SDL_PROC_UNUSED(void, glGetTexGenfv,
+ (GLenum coord, GLenum pname, GLfloat * params))
+SDL_PROC_UNUSED(void, glGetTexGeniv,
+ (GLenum coord, GLenum pname, GLint * params))
+SDL_PROC_UNUSED(void, glGetTexImage,
+ (GLenum target, GLint level, GLenum format, GLenum type,
+ GLvoid * pixels))
+SDL_PROC_UNUSED(void, glGetTexLevelParameterfv,
+ (GLenum target, GLint level, GLenum pname, GLfloat * params))
+SDL_PROC_UNUSED(void, glGetTexLevelParameteriv,
+ (GLenum target, GLint level, GLenum pname, GLint * params))
+SDL_PROC_UNUSED(void, glGetTexParameterfv,
+ (GLenum target, GLenum pname, GLfloat * params))
+SDL_PROC_UNUSED(void, glGetTexParameteriv,
+ (GLenum target, GLenum pname, GLint * params))
+SDL_PROC_UNUSED(void, glHint, (GLenum target, GLenum mode))
+SDL_PROC_UNUSED(void, glIndexMask, (GLuint mask))
+SDL_PROC_UNUSED(void, glIndexPointer,
+ (GLenum type, GLsizei stride, const GLvoid * pointer))
+SDL_PROC_UNUSED(void, glIndexd, (GLdouble c))
+SDL_PROC_UNUSED(void, glIndexdv, (const GLdouble * c))
+SDL_PROC_UNUSED(void, glIndexf, (GLfloat c))
+SDL_PROC_UNUSED(void, glIndexfv, (const GLfloat * c))
+SDL_PROC_UNUSED(void, glIndexi, (GLint c))
+SDL_PROC_UNUSED(void, glIndexiv, (const GLint * c))
+SDL_PROC_UNUSED(void, glIndexs, (GLshort c))
+SDL_PROC_UNUSED(void, glIndexsv, (const GLshort * c))
+SDL_PROC_UNUSED(void, glIndexub, (GLubyte c))
+SDL_PROC_UNUSED(void, glIndexubv, (const GLubyte * c))
+SDL_PROC_UNUSED(void, glInitNames, (void))
+SDL_PROC_UNUSED(void, glInterleavedArrays,
+ (GLenum format, GLsizei stride, const GLvoid * pointer))
+SDL_PROC_UNUSED(GLboolean, glIsEnabled, (GLenum cap))
+SDL_PROC_UNUSED(GLboolean, glIsList, (GLuint list))
+SDL_PROC_UNUSED(GLboolean, glIsTexture, (GLuint texture))
+SDL_PROC_UNUSED(void, glLightModelf, (GLenum pname, GLfloat param))
+SDL_PROC_UNUSED(void, glLightModelfv, (GLenum pname, const GLfloat * params))
+SDL_PROC_UNUSED(void, glLightModeli, (GLenum pname, GLint param))
+SDL_PROC_UNUSED(void, glLightModeliv, (GLenum pname, const GLint * params))
+SDL_PROC_UNUSED(void, glLightf, (GLenum light, GLenum pname, GLfloat param))
+SDL_PROC_UNUSED(void, glLightfv,
+ (GLenum light, GLenum pname, const GLfloat * params))
+SDL_PROC_UNUSED(void, glLighti, (GLenum light, GLenum pname, GLint param))
+SDL_PROC_UNUSED(void, glLightiv,
+ (GLenum light, GLenum pname, const GLint * params))
+SDL_PROC_UNUSED(void, glLineStipple, (GLint factor, GLushort pattern))
+SDL_PROC(void, glLineWidth, (GLfloat width))
+SDL_PROC_UNUSED(void, glListBase, (GLuint base))
+SDL_PROC(void, glLoadIdentity, (void))
+SDL_PROC_UNUSED(void, glLoadMatrixd, (const GLdouble * m))
+SDL_PROC_UNUSED(void, glLoadMatrixf, (const GLfloat * m))
+SDL_PROC_UNUSED(void, glLoadName, (GLuint name))
+SDL_PROC_UNUSED(void, glLogicOp, (GLenum opcode))
+SDL_PROC_UNUSED(void, glMap1d,
+ (GLenum target, GLdouble u1, GLdouble u2, GLint stride,
+ GLint order, const GLdouble * points))
+SDL_PROC_UNUSED(void, glMap1f,
+ (GLenum target, GLfloat u1, GLfloat u2, GLint stride,
+ GLint order, const GLfloat * points))
+SDL_PROC_UNUSED(void, glMap2d,
+ (GLenum target, GLdouble u1, GLdouble u2, GLint ustride,
+ GLint uorder, GLdouble v1, GLdouble v2, GLint vstride,
+ GLint vorder, const GLdouble * points))
+SDL_PROC_UNUSED(void, glMap2f,
+ (GLenum target, GLfloat u1, GLfloat u2, GLint ustride,
+ GLint uorder, GLfloat v1, GLfloat v2, GLint vstride,
+ GLint vorder, const GLfloat * points))
+SDL_PROC_UNUSED(void, glMapGrid1d, (GLint un, GLdouble u1, GLdouble u2))
+SDL_PROC_UNUSED(void, glMapGrid1f, (GLint un, GLfloat u1, GLfloat u2))
+SDL_PROC_UNUSED(void, glMapGrid2d,
+ (GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1,
+ GLdouble v2))
+SDL_PROC_UNUSED(void, glMapGrid2f,
+ (GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1,
+ GLfloat v2))
+SDL_PROC_UNUSED(void, glMaterialf, (GLenum face, GLenum pname, GLfloat param))
+SDL_PROC_UNUSED(void, glMaterialfv,
+ (GLenum face, GLenum pname, const GLfloat * params))
+SDL_PROC_UNUSED(void, glMateriali, (GLenum face, GLenum pname, GLint param))
+SDL_PROC_UNUSED(void, glMaterialiv,
+ (GLenum face, GLenum pname, const GLint * params))
+SDL_PROC(void, glMatrixMode, (GLenum mode))
+SDL_PROC_UNUSED(void, glMultMatrixd, (const GLdouble * m))
+SDL_PROC_UNUSED(void, glMultMatrixf, (const GLfloat * m))
+SDL_PROC_UNUSED(void, glNewList, (GLuint list, GLenum mode))
+SDL_PROC_UNUSED(void, glNormal3b, (GLbyte nx, GLbyte ny, GLbyte nz))
+SDL_PROC_UNUSED(void, glNormal3bv, (const GLbyte * v))
+SDL_PROC_UNUSED(void, glNormal3d, (GLdouble nx, GLdouble ny, GLdouble nz))
+SDL_PROC_UNUSED(void, glNormal3dv, (const GLdouble * v))
+SDL_PROC_UNUSED(void, glNormal3f, (GLfloat nx, GLfloat ny, GLfloat nz))
+SDL_PROC_UNUSED(void, glNormal3fv, (const GLfloat * v))
+SDL_PROC_UNUSED(void, glNormal3i, (GLint nx, GLint ny, GLint nz))
+SDL_PROC_UNUSED(void, glNormal3iv, (const GLint * v))
+SDL_PROC_UNUSED(void, glNormal3s, (GLshort nx, GLshort ny, GLshort nz))
+SDL_PROC_UNUSED(void, glNormal3sv, (const GLshort * v))
+SDL_PROC_UNUSED(void, glNormalPointer,
+ (GLenum type, GLsizei stride, const GLvoid * pointer))
+SDL_PROC(void, glOrtho,
+ (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top,
+ GLdouble zNear, GLdouble zFar))
+SDL_PROC_UNUSED(void, glPassThrough, (GLfloat token))
+SDL_PROC_UNUSED(void, glPixelMapfv,
+ (GLenum map, GLsizei mapsize, const GLfloat * values))
+SDL_PROC_UNUSED(void, glPixelMapuiv,
+ (GLenum map, GLsizei mapsize, const GLuint * values))
+SDL_PROC_UNUSED(void, glPixelMapusv,
+ (GLenum map, GLsizei mapsize, const GLushort * values))
+SDL_PROC_UNUSED(void, glPixelStoref, (GLenum pname, GLfloat param))
+SDL_PROC(void, glPixelStorei, (GLenum pname, GLint param))
+SDL_PROC_UNUSED(void, glPixelTransferf, (GLenum pname, GLfloat param))
+SDL_PROC_UNUSED(void, glPixelTransferi, (GLenum pname, GLint param))
+SDL_PROC_UNUSED(void, glPixelZoom, (GLfloat xfactor, GLfloat yfactor))
+SDL_PROC(void, glPointSize, (GLfloat size))
+SDL_PROC_UNUSED(void, glPolygonMode, (GLenum face, GLenum mode))
+SDL_PROC_UNUSED(void, glPolygonOffset, (GLfloat factor, GLfloat units))
+SDL_PROC_UNUSED(void, glPolygonStipple, (const GLubyte * mask))
+SDL_PROC_UNUSED(void, glPopAttrib, (void))
+SDL_PROC_UNUSED(void, glPopClientAttrib, (void))
+SDL_PROC(void, glPopMatrix, (void))
+SDL_PROC_UNUSED(void, glPopName, (void))
+SDL_PROC_UNUSED(void, glPrioritizeTextures,
+ (GLsizei n, const GLuint * textures,
+ const GLclampf * priorities))
+SDL_PROC_UNUSED(void, glPushAttrib, (GLbitfield mask))
+SDL_PROC_UNUSED(void, glPushClientAttrib, (GLbitfield mask))
+SDL_PROC(void, glPushMatrix, (void))
+SDL_PROC_UNUSED(void, glPushName, (GLuint name))
+SDL_PROC_UNUSED(void, glRasterPos2d, (GLdouble x, GLdouble y))
+SDL_PROC_UNUSED(void, glRasterPos2dv, (const GLdouble * v))
+SDL_PROC_UNUSED(void, glRasterPos2f, (GLfloat x, GLfloat y))
+SDL_PROC_UNUSED(void, glRasterPos2fv, (const GLfloat * v))
+SDL_PROC(void, glRasterPos2i, (GLint x, GLint y))
+SDL_PROC_UNUSED(void, glRasterPos2iv, (const GLint * v))
+SDL_PROC_UNUSED(void, glRasterPos2s, (GLshort x, GLshort y))
+SDL_PROC_UNUSED(void, glRasterPos2sv, (const GLshort * v))
+SDL_PROC_UNUSED(void, glRasterPos3d, (GLdouble x, GLdouble y, GLdouble z))
+SDL_PROC_UNUSED(void, glRasterPos3dv, (const GLdouble * v))
+SDL_PROC_UNUSED(void, glRasterPos3f, (GLfloat x, GLfloat y, GLfloat z))
+SDL_PROC_UNUSED(void, glRasterPos3fv, (const GLfloat * v))
+SDL_PROC_UNUSED(void, glRasterPos3i, (GLint x, GLint y, GLint z))
+SDL_PROC_UNUSED(void, glRasterPos3iv, (const GLint * v))
+SDL_PROC_UNUSED(void, glRasterPos3s, (GLshort x, GLshort y, GLshort z))
+SDL_PROC_UNUSED(void, glRasterPos3sv, (const GLshort * v))
+SDL_PROC_UNUSED(void, glRasterPos4d,
+ (GLdouble x, GLdouble y, GLdouble z, GLdouble w))
+SDL_PROC_UNUSED(void, glRasterPos4dv, (const GLdouble * v))
+SDL_PROC_UNUSED(void, glRasterPos4f,
+ (GLfloat x, GLfloat y, GLfloat z, GLfloat w))
+SDL_PROC_UNUSED(void, glRasterPos4fv, (const GLfloat * v))
+SDL_PROC_UNUSED(void, glRasterPos4i, (GLint x, GLint y, GLint z, GLint w))
+SDL_PROC_UNUSED(void, glRasterPos4iv, (const GLint * v))
+SDL_PROC_UNUSED(void, glRasterPos4s,
+ (GLshort x, GLshort y, GLshort z, GLshort w))
+SDL_PROC_UNUSED(void, glRasterPos4sv, (const GLshort * v))
+SDL_PROC(void, glReadBuffer, (GLenum mode))
+SDL_PROC(void, glReadPixels,
+ (GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type, GLvoid * pixels))
+SDL_PROC_UNUSED(void, glRectd,
+ (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2))
+SDL_PROC_UNUSED(void, glRectdv, (const GLdouble * v1, const GLdouble * v2))
+SDL_PROC(void, glRectf,
+ (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2))
+SDL_PROC_UNUSED(void, glRectfv, (const GLfloat * v1, const GLfloat * v2))
+SDL_PROC_UNUSED(void, glRecti, (GLint x1, GLint y1, GLint x2, GLint y2))
+SDL_PROC_UNUSED(void, glRectiv, (const GLint * v1, const GLint * v2))
+SDL_PROC_UNUSED(void, glRects,
+ (GLshort x1, GLshort y1, GLshort x2, GLshort y2))
+SDL_PROC_UNUSED(void, glRectsv, (const GLshort * v1, const GLshort * v2))
+SDL_PROC_UNUSED(GLint, glRenderMode, (GLenum mode))
+SDL_PROC(void, glRotated,
+ (GLdouble angle, GLdouble x, GLdouble y, GLdouble z))
+SDL_PROC(void, glRotatef,
+ (GLfloat angle, GLfloat x, GLfloat y, GLfloat z))
+SDL_PROC_UNUSED(void, glScaled, (GLdouble x, GLdouble y, GLdouble z))
+SDL_PROC_UNUSED(void, glScalef, (GLfloat x, GLfloat y, GLfloat z))
+SDL_PROC(void, glScissor, (GLint x, GLint y, GLsizei width, GLsizei height))
+SDL_PROC_UNUSED(void, glSelectBuffer, (GLsizei size, GLuint * buffer))
+SDL_PROC(void, glShadeModel, (GLenum mode))
+SDL_PROC_UNUSED(void, glStencilFunc, (GLenum func, GLint ref, GLuint mask))
+SDL_PROC_UNUSED(void, glStencilMask, (GLuint mask))
+SDL_PROC_UNUSED(void, glStencilOp, (GLenum fail, GLenum zfail, GLenum zpass))
+SDL_PROC_UNUSED(void, glTexCoord1d, (GLdouble s))
+SDL_PROC_UNUSED(void, glTexCoord1dv, (const GLdouble * v))
+SDL_PROC_UNUSED(void, glTexCoord1f, (GLfloat s))
+SDL_PROC_UNUSED(void, glTexCoord1fv, (const GLfloat * v))
+SDL_PROC_UNUSED(void, glTexCoord1i, (GLint s))
+SDL_PROC_UNUSED(void, glTexCoord1iv, (const GLint * v))
+SDL_PROC_UNUSED(void, glTexCoord1s, (GLshort s))
+SDL_PROC_UNUSED(void, glTexCoord1sv, (const GLshort * v))
+SDL_PROC_UNUSED(void, glTexCoord2d, (GLdouble s, GLdouble t))
+SDL_PROC_UNUSED(void, glTexCoord2dv, (const GLdouble * v))
+SDL_PROC(void, glTexCoord2f, (GLfloat s, GLfloat t))
+SDL_PROC_UNUSED(void, glTexCoord2fv, (const GLfloat * v))
+SDL_PROC_UNUSED(void, glTexCoord2i, (GLint s, GLint t))
+SDL_PROC_UNUSED(void, glTexCoord2iv, (const GLint * v))
+SDL_PROC_UNUSED(void, glTexCoord2s, (GLshort s, GLshort t))
+SDL_PROC_UNUSED(void, glTexCoord2sv, (const GLshort * v))
+SDL_PROC_UNUSED(void, glTexCoord3d, (GLdouble s, GLdouble t, GLdouble r))
+SDL_PROC_UNUSED(void, glTexCoord3dv, (const GLdouble * v))
+SDL_PROC_UNUSED(void, glTexCoord3f, (GLfloat s, GLfloat t, GLfloat r))
+SDL_PROC_UNUSED(void, glTexCoord3fv, (const GLfloat * v))
+SDL_PROC_UNUSED(void, glTexCoord3i, (GLint s, GLint t, GLint r))
+SDL_PROC_UNUSED(void, glTexCoord3iv, (const GLint * v))
+SDL_PROC_UNUSED(void, glTexCoord3s, (GLshort s, GLshort t, GLshort r))
+SDL_PROC_UNUSED(void, glTexCoord3sv, (const GLshort * v))
+SDL_PROC_UNUSED(void, glTexCoord4d,
+ (GLdouble s, GLdouble t, GLdouble r, GLdouble q))
+SDL_PROC_UNUSED(void, glTexCoord4dv, (const GLdouble * v))
+SDL_PROC_UNUSED(void, glTexCoord4f,
+ (GLfloat s, GLfloat t, GLfloat r, GLfloat q))
+SDL_PROC_UNUSED(void, glTexCoord4fv, (const GLfloat * v))
+SDL_PROC_UNUSED(void, glTexCoord4i, (GLint s, GLint t, GLint r, GLint q))
+SDL_PROC_UNUSED(void, glTexCoord4iv, (const GLint * v))
+SDL_PROC_UNUSED(void, glTexCoord4s,
+ (GLshort s, GLshort t, GLshort r, GLshort q))
+SDL_PROC_UNUSED(void, glTexCoord4sv, (const GLshort * v))
+SDL_PROC_UNUSED(void, glTexCoordPointer,
+ (GLint size, GLenum type, GLsizei stride,
+ const GLvoid * pointer))
+SDL_PROC(void, glTexEnvf, (GLenum target, GLenum pname, GLfloat param))
+SDL_PROC_UNUSED(void, glTexEnvfv,
+ (GLenum target, GLenum pname, const GLfloat * params))
+SDL_PROC_UNUSED(void, glTexEnvi, (GLenum target, GLenum pname, GLint param))
+SDL_PROC_UNUSED(void, glTexEnviv,
+ (GLenum target, GLenum pname, const GLint * params))
+SDL_PROC_UNUSED(void, glTexGend, (GLenum coord, GLenum pname, GLdouble param))
+SDL_PROC_UNUSED(void, glTexGendv,
+ (GLenum coord, GLenum pname, const GLdouble * params))
+SDL_PROC_UNUSED(void, glTexGenf, (GLenum coord, GLenum pname, GLfloat param))
+SDL_PROC_UNUSED(void, glTexGenfv,
+ (GLenum coord, GLenum pname, const GLfloat * params))
+SDL_PROC_UNUSED(void, glTexGeni, (GLenum coord, GLenum pname, GLint param))
+SDL_PROC_UNUSED(void, glTexGeniv,
+ (GLenum coord, GLenum pname, const GLint * params))
+SDL_PROC_UNUSED(void, glTexImage1D,
+ (GLenum target, GLint level, GLint internalformat,
+ GLsizei width, GLint border, GLenum format, GLenum type,
+ const GLvoid * pixels))
+SDL_PROC(void, glTexImage2D,
+ (GLenum target, GLint level, GLint internalformat, GLsizei width,
+ GLsizei height, GLint border, GLenum format, GLenum type,
+ const GLvoid * pixels))
+SDL_PROC_UNUSED(void, glTexParameterf,
+ (GLenum target, GLenum pname, GLfloat param))
+SDL_PROC_UNUSED(void, glTexParameterfv,
+ (GLenum target, GLenum pname, const GLfloat * params))
+SDL_PROC(void, glTexParameteri, (GLenum target, GLenum pname, GLint param))
+SDL_PROC_UNUSED(void, glTexParameteriv,
+ (GLenum target, GLenum pname, const GLint * params))
+SDL_PROC_UNUSED(void, glTexSubImage1D,
+ (GLenum target, GLint level, GLint xoffset, GLsizei width,
+ GLenum format, GLenum type, const GLvoid * pixels))
+SDL_PROC(void, glTexSubImage2D,
+ (GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height, GLenum format, GLenum type,
+ const GLvoid * pixels))
+SDL_PROC_UNUSED(void, glTranslated, (GLdouble x, GLdouble y, GLdouble z))
+SDL_PROC(void, glTranslatef, (GLfloat x, GLfloat y, GLfloat z))
+SDL_PROC_UNUSED(void, glVertex2d, (GLdouble x, GLdouble y))
+SDL_PROC_UNUSED(void, glVertex2dv, (const GLdouble * v))
+SDL_PROC(void, glVertex2f, (GLfloat x, GLfloat y))
+SDL_PROC_UNUSED(void, glVertex2fv, (const GLfloat * v))
+SDL_PROC_UNUSED(void, glVertex2i, (GLint x, GLint y))
+SDL_PROC_UNUSED(void, glVertex2iv, (const GLint * v))
+SDL_PROC_UNUSED(void, glVertex2s, (GLshort x, GLshort y))
+SDL_PROC_UNUSED(void, glVertex2sv, (const GLshort * v))
+SDL_PROC_UNUSED(void, glVertex3d, (GLdouble x, GLdouble y, GLdouble z))
+SDL_PROC_UNUSED(void, glVertex3dv, (const GLdouble * v))
+SDL_PROC_UNUSED(void, glVertex3f, (GLfloat x, GLfloat y, GLfloat z))
+SDL_PROC(void, glVertex3fv, (const GLfloat * v))
+SDL_PROC_UNUSED(void, glVertex3i, (GLint x, GLint y, GLint z))
+SDL_PROC_UNUSED(void, glVertex3iv, (const GLint * v))
+SDL_PROC_UNUSED(void, glVertex3s, (GLshort x, GLshort y, GLshort z))
+SDL_PROC_UNUSED(void, glVertex3sv, (const GLshort * v))
+SDL_PROC_UNUSED(void, glVertex4d,
+ (GLdouble x, GLdouble y, GLdouble z, GLdouble w))
+SDL_PROC_UNUSED(void, glVertex4dv, (const GLdouble * v))
+SDL_PROC_UNUSED(void, glVertex4f,
+ (GLfloat x, GLfloat y, GLfloat z, GLfloat w))
+SDL_PROC_UNUSED(void, glVertex4fv, (const GLfloat * v))
+SDL_PROC_UNUSED(void, glVertex4i, (GLint x, GLint y, GLint z, GLint w))
+SDL_PROC_UNUSED(void, glVertex4iv, (const GLint * v))
+SDL_PROC_UNUSED(void, glVertex4s,
+ (GLshort x, GLshort y, GLshort z, GLshort w))
+SDL_PROC_UNUSED(void, glVertex4sv, (const GLshort * v))
+SDL_PROC_UNUSED(void, glVertexPointer,
+ (GLint size, GLenum type, GLsizei stride,
+ const GLvoid * pointer))
+SDL_PROC(void, glViewport, (GLint x, GLint y, GLsizei width, GLsizei height))
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/render/opengl/SDL_render_gl.c b/source/3rd-party/SDL2/src/render/opengl/SDL_render_gl.c
new file mode 100644
index 0000000..f3e8326
--- /dev/null
+++ b/source/3rd-party/SDL2/src/render/opengl/SDL_render_gl.c
@@ -0,0 +1,1678 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_RENDER_OGL && !SDL_RENDER_DISABLED
+
+#include "SDL_hints.h"
+#include "SDL_log.h"
+#include "SDL_assert.h"
+#include "SDL_opengl.h"
+#include "../SDL_sysrender.h"
+#include "SDL_shaders_gl.h"
+
+#ifdef __MACOSX__
+#include <OpenGL/OpenGL.h>
+#endif
+
+/* To prevent unnecessary window recreation,
+ * these should match the defaults selected in SDL_GL_ResetAttributes
+ */
+
+#define RENDERER_CONTEXT_MAJOR 2
+#define RENDERER_CONTEXT_MINOR 1
+
+/* OpenGL renderer implementation */
+
+/* Details on optimizing the texture path on Mac OS X:
+ http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_texturedata/opengl_texturedata.html
+*/
+
+/* Used to re-create the window with OpenGL capability */
+extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags);
+
+static const float inv255f = 1.0f / 255.0f;
+
+static SDL_Renderer *GL_CreateRenderer(SDL_Window * window, Uint32 flags);
+static void GL_WindowEvent(SDL_Renderer * renderer,
+ const SDL_WindowEvent *event);
+static int GL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h);
+static SDL_bool GL_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode);
+static int GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
+static int GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+ const SDL_Rect * rect, const void *pixels,
+ int pitch);
+static int GL_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
+ const SDL_Rect * rect,
+ const Uint8 *Yplane, int Ypitch,
+ const Uint8 *Uplane, int Upitch,
+ const Uint8 *Vplane, int Vpitch);
+static int GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+ const SDL_Rect * rect, void **pixels, int *pitch);
+static void GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
+static int GL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture);
+static int GL_UpdateViewport(SDL_Renderer * renderer);
+static int GL_UpdateClipRect(SDL_Renderer * renderer);
+static int GL_RenderClear(SDL_Renderer * renderer);
+static int GL_RenderDrawPoints(SDL_Renderer * renderer,
+ const SDL_FPoint * points, int count);
+static int GL_RenderDrawLines(SDL_Renderer * renderer,
+ const SDL_FPoint * points, int count);
+static int GL_RenderFillRects(SDL_Renderer * renderer,
+ const SDL_FRect * rects, int count);
+static int GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
+ const SDL_Rect * srcrect, const SDL_FRect * dstrect);
+static int GL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
+ const SDL_Rect * srcrect, const SDL_FRect * dstrect,
+ const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip);
+static int GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+ Uint32 pixel_format, void * pixels, int pitch);
+static void GL_RenderPresent(SDL_Renderer * renderer);
+static void GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture);
+static void GL_DestroyRenderer(SDL_Renderer * renderer);
+static int GL_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh);
+static int GL_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture);
+
+SDL_RenderDriver GL_RenderDriver = {
+ GL_CreateRenderer,
+ {
+ "opengl",
+ (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE),
+ 1,
+ {SDL_PIXELFORMAT_ARGB8888},
+ 0,
+ 0}
+};
+
+typedef struct GL_FBOList GL_FBOList;
+
+struct GL_FBOList
+{
+ Uint32 w, h;
+ GLuint FBO;
+ GL_FBOList *next;
+};
+
+typedef struct
+{
+ SDL_GLContext context;
+
+ SDL_bool debug_enabled;
+ SDL_bool GL_ARB_debug_output_supported;
+ int errors;
+ char **error_messages;
+ GLDEBUGPROCARB next_error_callback;
+ GLvoid *next_error_userparam;
+
+ SDL_bool GL_ARB_texture_non_power_of_two_supported;
+ SDL_bool GL_ARB_texture_rectangle_supported;
+ struct {
+ GL_Shader shader;
+ Uint32 color;
+ SDL_BlendMode blendMode;
+ } current;
+
+ SDL_bool GL_EXT_framebuffer_object_supported;
+ GL_FBOList *framebuffers;
+
+ /* OpenGL functions */
+#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
+#include "SDL_glfuncs.h"
+#undef SDL_PROC
+
+ /* Multitexture support */
+ SDL_bool GL_ARB_multitexture_supported;
+ PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
+ GLint num_texture_units;
+
+ PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT;
+ PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
+ PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
+ PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
+ PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
+
+ /* Shader support */
+ GL_ShaderContext *shaders;
+
+} GL_RenderData;
+
+typedef struct
+{
+ GLuint texture;
+ GLenum type;
+ GLfloat texw;
+ GLfloat texh;
+ GLenum format;
+ GLenum formattype;
+ void *pixels;
+ int pitch;
+ SDL_Rect locked_rect;
+
+ /* YUV texture support */
+ SDL_bool yuv;
+ SDL_bool nv12;
+ GLuint utexture;
+ GLuint vtexture;
+
+ GL_FBOList *fbo;
+} GL_TextureData;
+
+SDL_FORCE_INLINE const char*
+GL_TranslateError (GLenum error)
+{
+#define GL_ERROR_TRANSLATE(e) case e: return #e;
+ switch (error) {
+ GL_ERROR_TRANSLATE(GL_INVALID_ENUM)
+ GL_ERROR_TRANSLATE(GL_INVALID_VALUE)
+ GL_ERROR_TRANSLATE(GL_INVALID_OPERATION)
+ GL_ERROR_TRANSLATE(GL_OUT_OF_MEMORY)
+ GL_ERROR_TRANSLATE(GL_NO_ERROR)
+ GL_ERROR_TRANSLATE(GL_STACK_OVERFLOW)
+ GL_ERROR_TRANSLATE(GL_STACK_UNDERFLOW)
+ GL_ERROR_TRANSLATE(GL_TABLE_TOO_LARGE)
+ default:
+ return "UNKNOWN";
+}
+#undef GL_ERROR_TRANSLATE
+}
+
+SDL_FORCE_INLINE void
+GL_ClearErrors(SDL_Renderer *renderer)
+{
+ GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+
+ if (!data->debug_enabled)
+ {
+ return;
+ }
+ if (data->GL_ARB_debug_output_supported) {
+ if (data->errors) {
+ int i;
+ for (i = 0; i < data->errors; ++i) {
+ SDL_free(data->error_messages[i]);
+ }
+ SDL_free(data->error_messages);
+
+ data->errors = 0;
+ data->error_messages = NULL;
+ }
+ } else {
+ while (data->glGetError() != GL_NO_ERROR) {
+ continue;
+ }
+ }
+}
+
+SDL_FORCE_INLINE int
+GL_CheckAllErrors (const char *prefix, SDL_Renderer *renderer, const char *file, int line, const char *function)
+{
+ GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+ int ret = 0;
+
+ if (!data->debug_enabled)
+ {
+ return 0;
+ }
+ if (data->GL_ARB_debug_output_supported) {
+ if (data->errors) {
+ int i;
+ for (i = 0; i < data->errors; ++i) {
+ SDL_SetError("%s: %s (%d): %s %s", prefix, file, line, function, data->error_messages[i]);
+ ret = -1;
+ }
+ GL_ClearErrors(renderer);
+ }
+ } else {
+ /* check gl errors (can return multiple errors) */
+ for (;;) {
+ GLenum error = data->glGetError();
+ if (error != GL_NO_ERROR) {
+ if (prefix == NULL || prefix[0] == '\0') {
+ prefix = "generic";
+ }
+ SDL_SetError("%s: %s (%d): %s %s (0x%X)", prefix, file, line, function, GL_TranslateError(error), error);
+ ret = -1;
+ } else {
+ break;
+ }
+ }
+ }
+ return ret;
+}
+
+#if 0
+#define GL_CheckError(prefix, renderer)
+#else
+#define GL_CheckError(prefix, renderer) GL_CheckAllErrors(prefix, renderer, SDL_FILE, SDL_LINE, SDL_FUNCTION)
+#endif
+
+static int
+GL_LoadFunctions(GL_RenderData * data)
+{
+#ifdef __SDL_NOGETPROCADDR__
+#define SDL_PROC(ret,func,params) data->func=func;
+#else
+#define SDL_PROC(ret,func,params) \
+ do { \
+ data->func = SDL_GL_GetProcAddress(#func); \
+ if ( ! data->func ) { \
+ return SDL_SetError("Couldn't load GL function %s: %s", #func, SDL_GetError()); \
+ } \
+ } while ( 0 );
+#endif /* __SDL_NOGETPROCADDR__ */
+
+#include "SDL_glfuncs.h"
+#undef SDL_PROC
+ return 0;
+}
+
+static SDL_GLContext SDL_CurrentContext = NULL;
+
+static int
+GL_ActivateRenderer(SDL_Renderer * renderer)
+{
+ GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+
+ if (SDL_CurrentContext != data->context ||
+ SDL_GL_GetCurrentContext() != data->context) {
+ if (SDL_GL_MakeCurrent(renderer->window, data->context) < 0) {
+ return -1;
+ }
+ SDL_CurrentContext = data->context;
+
+ GL_UpdateViewport(renderer);
+ }
+
+ GL_ClearErrors(renderer);
+
+ return 0;
+}
+
+/* This is called if we need to invalidate all of the SDL OpenGL state */
+static void
+GL_ResetState(SDL_Renderer *renderer)
+{
+ GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+
+ if (SDL_GL_GetCurrentContext() == data->context) {
+ GL_UpdateViewport(renderer);
+ } else {
+ GL_ActivateRenderer(renderer);
+ }
+
+ data->current.shader = SHADER_NONE;
+ data->current.color = 0xffffffff;
+ data->current.blendMode = SDL_BLENDMODE_INVALID;
+
+ data->glDisable(GL_DEPTH_TEST);
+ data->glDisable(GL_CULL_FACE);
+ /* This ended up causing video discrepancies between OpenGL and Direct3D */
+ /* data->glEnable(GL_LINE_SMOOTH); */
+
+ data->glMatrixMode(GL_MODELVIEW);
+ data->glLoadIdentity();
+
+ GL_CheckError("", renderer);
+}
+
+static void APIENTRY
+GL_HandleDebugMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char *message, const void *userParam)
+{
+ SDL_Renderer *renderer = (SDL_Renderer *) userParam;
+ GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+
+ if (type == GL_DEBUG_TYPE_ERROR_ARB) {
+ /* Record this error */
+ int errors = data->errors + 1;
+ char **error_messages = SDL_realloc(data->error_messages, errors * sizeof(*data->error_messages));
+ if (error_messages) {
+ data->errors = errors;
+ data->error_messages = error_messages;
+ data->error_messages[data->errors-1] = SDL_strdup(message);
+ }
+ }
+
+ /* If there's another error callback, pass it along, otherwise log it */
+ if (data->next_error_callback) {
+ data->next_error_callback(source, type, id, severity, length, message, data->next_error_userparam);
+ } else {
+ if (type == GL_DEBUG_TYPE_ERROR_ARB) {
+ SDL_LogError(SDL_LOG_CATEGORY_RENDER, "%s", message);
+ } else {
+ SDL_LogDebug(SDL_LOG_CATEGORY_RENDER, "%s", message);
+ }
+ }
+}
+
+static GL_FBOList *
+GL_GetFBO(GL_RenderData *data, Uint32 w, Uint32 h)
+{
+ GL_FBOList *result = data->framebuffers;
+
+ while (result && ((result->w != w) || (result->h != h))) {
+ result = result->next;
+ }
+
+ if (!result) {
+ result = SDL_malloc(sizeof(GL_FBOList));
+ if (result) {
+ result->w = w;
+ result->h = h;
+ data->glGenFramebuffersEXT(1, &result->FBO);
+ result->next = data->framebuffers;
+ data->framebuffers = result;
+ }
+ }
+ return result;
+}
+
+SDL_Renderer *
+GL_CreateRenderer(SDL_Window * window, Uint32 flags)
+{
+ SDL_Renderer *renderer;
+ GL_RenderData *data;
+ GLint value;
+ Uint32 window_flags;
+ int profile_mask = 0, major = 0, minor = 0;
+ SDL_bool changed_window = SDL_FALSE;
+
+ SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &profile_mask);
+ SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major);
+ SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minor);
+
+ window_flags = SDL_GetWindowFlags(window);
+ if (!(window_flags & SDL_WINDOW_OPENGL) ||
+ profile_mask == SDL_GL_CONTEXT_PROFILE_ES || major != RENDERER_CONTEXT_MAJOR || minor != RENDERER_CONTEXT_MINOR) {
+
+ changed_window = SDL_TRUE;
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, RENDERER_CONTEXT_MAJOR);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, RENDERER_CONTEXT_MINOR);
+
+ if (SDL_RecreateWindow(window, window_flags | SDL_WINDOW_OPENGL) < 0) {
+ goto error;
+ }
+ }
+
+ renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
+ if (!renderer) {
+ SDL_OutOfMemory();
+ goto error;
+ }
+
+ data = (GL_RenderData *) SDL_calloc(1, sizeof(*data));
+ if (!data) {
+ GL_DestroyRenderer(renderer);
+ SDL_OutOfMemory();
+ goto error;
+ }
+
+ renderer->WindowEvent = GL_WindowEvent;
+ renderer->GetOutputSize = GL_GetOutputSize;
+ renderer->SupportsBlendMode = GL_SupportsBlendMode;
+ renderer->CreateTexture = GL_CreateTexture;
+ renderer->UpdateTexture = GL_UpdateTexture;
+ renderer->UpdateTextureYUV = GL_UpdateTextureYUV;
+ renderer->LockTexture = GL_LockTexture;
+ renderer->UnlockTexture = GL_UnlockTexture;
+ renderer->SetRenderTarget = GL_SetRenderTarget;
+ renderer->UpdateViewport = GL_UpdateViewport;
+ renderer->UpdateClipRect = GL_UpdateClipRect;
+ renderer->RenderClear = GL_RenderClear;
+ renderer->RenderDrawPoints = GL_RenderDrawPoints;
+ renderer->RenderDrawLines = GL_RenderDrawLines;
+ renderer->RenderFillRects = GL_RenderFillRects;
+ renderer->RenderCopy = GL_RenderCopy;
+ renderer->RenderCopyEx = GL_RenderCopyEx;
+ renderer->RenderReadPixels = GL_RenderReadPixels;
+ renderer->RenderPresent = GL_RenderPresent;
+ renderer->DestroyTexture = GL_DestroyTexture;
+ renderer->DestroyRenderer = GL_DestroyRenderer;
+ renderer->GL_BindTexture = GL_BindTexture;
+ renderer->GL_UnbindTexture = GL_UnbindTexture;
+ renderer->info = GL_RenderDriver.info;
+ renderer->info.flags = SDL_RENDERER_ACCELERATED;
+ renderer->driverdata = data;
+ renderer->window = window;
+
+ data->context = SDL_GL_CreateContext(window);
+ if (!data->context) {
+ GL_DestroyRenderer(renderer);
+ goto error;
+ }
+ if (SDL_GL_MakeCurrent(window, data->context) < 0) {
+ GL_DestroyRenderer(renderer);
+ goto error;
+ }
+
+ if (GL_LoadFunctions(data) < 0) {
+ GL_DestroyRenderer(renderer);
+ goto error;
+ }
+
+#ifdef __MACOSX__
+ /* Enable multi-threaded rendering */
+ /* Disabled until Ryan finishes his VBO/PBO code...
+ CGLEnable(CGLGetCurrentContext(), kCGLCEMPEngine);
+ */
+#endif
+
+ if (flags & SDL_RENDERER_PRESENTVSYNC) {
+ SDL_GL_SetSwapInterval(1);
+ } else {
+ SDL_GL_SetSwapInterval(0);
+ }
+ if (SDL_GL_GetSwapInterval() > 0) {
+ renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
+ }
+
+ /* Check for debug output support */
+ if (SDL_GL_GetAttribute(SDL_GL_CONTEXT_FLAGS, &value) == 0 &&
+ (value & SDL_GL_CONTEXT_DEBUG_FLAG)) {
+ data->debug_enabled = SDL_TRUE;
+ }
+ if (data->debug_enabled && SDL_GL_ExtensionSupported("GL_ARB_debug_output")) {
+ PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARBFunc = (PFNGLDEBUGMESSAGECALLBACKARBPROC) SDL_GL_GetProcAddress("glDebugMessageCallbackARB");
+
+ data->GL_ARB_debug_output_supported = SDL_TRUE;
+ data->glGetPointerv(GL_DEBUG_CALLBACK_FUNCTION_ARB, (GLvoid **)(char *)&data->next_error_callback);
+ data->glGetPointerv(GL_DEBUG_CALLBACK_USER_PARAM_ARB, &data->next_error_userparam);
+ glDebugMessageCallbackARBFunc(GL_HandleDebugMessage, renderer);
+
+ /* Make sure our callback is called when errors actually happen */
+ data->glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
+ }
+
+ if (SDL_GL_ExtensionSupported("GL_ARB_texture_non_power_of_two")) {
+ data->GL_ARB_texture_non_power_of_two_supported = SDL_TRUE;
+ } else if (SDL_GL_ExtensionSupported("GL_ARB_texture_rectangle") ||
+ SDL_GL_ExtensionSupported("GL_EXT_texture_rectangle")) {
+ data->GL_ARB_texture_rectangle_supported = SDL_TRUE;
+ }
+ if (data->GL_ARB_texture_rectangle_supported) {
+ data->glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &value);
+ renderer->info.max_texture_width = value;
+ renderer->info.max_texture_height = value;
+ } else {
+ data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
+ renderer->info.max_texture_width = value;
+ renderer->info.max_texture_height = value;
+ }
+
+ /* Check for multitexture support */
+ if (SDL_GL_ExtensionSupported("GL_ARB_multitexture")) {
+ data->glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) SDL_GL_GetProcAddress("glActiveTextureARB");
+ if (data->glActiveTextureARB) {
+ data->GL_ARB_multitexture_supported = SDL_TRUE;
+ data->glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &data->num_texture_units);
+ }
+ }
+
+ /* Check for shader support */
+ if (SDL_GetHintBoolean(SDL_HINT_RENDER_OPENGL_SHADERS, SDL_TRUE)) {
+ data->shaders = GL_CreateShaderContext();
+ }
+ SDL_LogInfo(SDL_LOG_CATEGORY_RENDER, "OpenGL shaders: %s",
+ data->shaders ? "ENABLED" : "DISABLED");
+
+ /* We support YV12 textures using 3 textures and a shader */
+ if (data->shaders && data->num_texture_units >= 3) {
+ renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_YV12;
+ renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_IYUV;
+ renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV12;
+ renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV21;
+ }
+
+#ifdef __MACOSX__
+ renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_UYVY;
+#endif
+
+ if (SDL_GL_ExtensionSupported("GL_EXT_framebuffer_object")) {
+ data->GL_EXT_framebuffer_object_supported = SDL_TRUE;
+ data->glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)
+ SDL_GL_GetProcAddress("glGenFramebuffersEXT");
+ data->glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)
+ SDL_GL_GetProcAddress("glDeleteFramebuffersEXT");
+ data->glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)
+ SDL_GL_GetProcAddress("glFramebufferTexture2DEXT");
+ data->glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)
+ SDL_GL_GetProcAddress("glBindFramebufferEXT");
+ data->glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)
+ SDL_GL_GetProcAddress("glCheckFramebufferStatusEXT");
+ renderer->info.flags |= SDL_RENDERER_TARGETTEXTURE;
+ }
+ data->framebuffers = NULL;
+
+ /* Set up parameters for rendering */
+ GL_ResetState(renderer);
+
+ return renderer;
+
+error:
+ if (changed_window) {
+ /* Uh oh, better try to put it back... */
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, profile_mask);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, major);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minor);
+ SDL_RecreateWindow(window, window_flags);
+ }
+ return NULL;
+}
+
+static void
+GL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
+{
+ if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED ||
+ event->event == SDL_WINDOWEVENT_SHOWN ||
+ event->event == SDL_WINDOWEVENT_HIDDEN) {
+ /* Rebind the context to the window area and update matrices */
+ SDL_CurrentContext = NULL;
+ }
+}
+
+static int
+GL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
+{
+ SDL_GL_GetDrawableSize(renderer->window, w, h);
+ return 0;
+}
+
+static GLenum GetBlendFunc(SDL_BlendFactor factor)
+{
+ switch (factor) {
+ case SDL_BLENDFACTOR_ZERO:
+ return GL_ZERO;
+ case SDL_BLENDFACTOR_ONE:
+ return GL_ONE;
+ case SDL_BLENDFACTOR_SRC_COLOR:
+ return GL_SRC_COLOR;
+ case SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR:
+ return GL_ONE_MINUS_SRC_COLOR;
+ case SDL_BLENDFACTOR_SRC_ALPHA:
+ return GL_SRC_ALPHA;
+ case SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA:
+ return GL_ONE_MINUS_SRC_ALPHA;
+ case SDL_BLENDFACTOR_DST_COLOR:
+ return GL_DST_COLOR;
+ case SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR:
+ return GL_ONE_MINUS_DST_COLOR;
+ case SDL_BLENDFACTOR_DST_ALPHA:
+ return GL_DST_ALPHA;
+ case SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA:
+ return GL_ONE_MINUS_DST_ALPHA;
+ default:
+ return GL_INVALID_ENUM;
+ }
+}
+
+static GLenum GetBlendEquation(SDL_BlendOperation operation)
+{
+ switch (operation) {
+ case SDL_BLENDOPERATION_ADD:
+ return GL_FUNC_ADD;
+ case SDL_BLENDOPERATION_SUBTRACT:
+ return GL_FUNC_SUBTRACT;
+ case SDL_BLENDOPERATION_REV_SUBTRACT:
+ return GL_FUNC_REVERSE_SUBTRACT;
+ default:
+ return GL_INVALID_ENUM;
+ }
+}
+
+static SDL_bool
+GL_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
+{
+ SDL_BlendFactor srcColorFactor = SDL_GetBlendModeSrcColorFactor(blendMode);
+ SDL_BlendFactor srcAlphaFactor = SDL_GetBlendModeSrcAlphaFactor(blendMode);
+ SDL_BlendOperation colorOperation = SDL_GetBlendModeColorOperation(blendMode);
+ SDL_BlendFactor dstColorFactor = SDL_GetBlendModeDstColorFactor(blendMode);
+ SDL_BlendFactor dstAlphaFactor = SDL_GetBlendModeDstAlphaFactor(blendMode);
+ SDL_BlendOperation alphaOperation = SDL_GetBlendModeAlphaOperation(blendMode);
+
+ if (GetBlendFunc(srcColorFactor) == GL_INVALID_ENUM ||
+ GetBlendFunc(srcAlphaFactor) == GL_INVALID_ENUM ||
+ GetBlendEquation(colorOperation) == GL_INVALID_ENUM ||
+ GetBlendFunc(dstColorFactor) == GL_INVALID_ENUM ||
+ GetBlendFunc(dstAlphaFactor) == GL_INVALID_ENUM ||
+ GetBlendEquation(alphaOperation) == GL_INVALID_ENUM) {
+ return SDL_FALSE;
+ }
+ if (colorOperation != alphaOperation) {
+ return SDL_FALSE;
+ }
+ return SDL_TRUE;
+}
+
+SDL_FORCE_INLINE int
+power_of_2(int input)
+{
+ int value = 1;
+
+ while (value < input) {
+ value <<= 1;
+ }
+ return value;
+}
+
+SDL_FORCE_INLINE SDL_bool
+convert_format(GL_RenderData *renderdata, Uint32 pixel_format,
+ GLint* internalFormat, GLenum* format, GLenum* type)
+{
+ switch (pixel_format) {
+ case SDL_PIXELFORMAT_ARGB8888:
+ *internalFormat = GL_RGBA8;
+ *format = GL_BGRA;
+ *type = GL_UNSIGNED_INT_8_8_8_8_REV;
+ break;
+ case SDL_PIXELFORMAT_YV12:
+ case SDL_PIXELFORMAT_IYUV:
+ case SDL_PIXELFORMAT_NV12:
+ case SDL_PIXELFORMAT_NV21:
+ *internalFormat = GL_LUMINANCE;
+ *format = GL_LUMINANCE;
+ *type = GL_UNSIGNED_BYTE;
+ break;
+#ifdef __MACOSX__
+ case SDL_PIXELFORMAT_UYVY:
+ *internalFormat = GL_RGB8;
+ *format = GL_YCBCR_422_APPLE;
+ *type = GL_UNSIGNED_SHORT_8_8_APPLE;
+ break;
+#endif
+ default:
+ return SDL_FALSE;
+ }
+ return SDL_TRUE;
+}
+
+static int
+GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+ GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
+ GL_TextureData *data;
+ GLint internalFormat;
+ GLenum format, type;
+ int texture_w, texture_h;
+ GLenum scaleMode;
+
+ GL_ActivateRenderer(renderer);
+
+ if (texture->access == SDL_TEXTUREACCESS_TARGET &&
+ !renderdata->GL_EXT_framebuffer_object_supported) {
+ return SDL_SetError("Render targets not supported by OpenGL");
+ }
+
+ if (!convert_format(renderdata, texture->format, &internalFormat,
+ &format, &type)) {
+ return SDL_SetError("Texture format %s not supported by OpenGL",
+ SDL_GetPixelFormatName(texture->format));
+ }
+
+ data = (GL_TextureData *) SDL_calloc(1, sizeof(*data));
+ if (!data) {
+ return SDL_OutOfMemory();
+ }
+
+ if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
+ size_t size;
+ data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
+ size = texture->h * data->pitch;
+ if (texture->format == SDL_PIXELFORMAT_YV12 ||
+ texture->format == SDL_PIXELFORMAT_IYUV) {
+ /* Need to add size for the U and V planes */
+ size += 2 * ((texture->h + 1) / 2) * ((data->pitch + 1) / 2);
+ }
+ if (texture->format == SDL_PIXELFORMAT_NV12 ||
+ texture->format == SDL_PIXELFORMAT_NV21) {
+ /* Need to add size for the U/V plane */
+ size += 2 * ((texture->h + 1) / 2) * ((data->pitch + 1) / 2);
+ }
+ data->pixels = SDL_calloc(1, size);
+ if (!data->pixels) {
+ SDL_free(data);
+ return SDL_OutOfMemory();
+ }
+ }
+
+ if (texture->access == SDL_TEXTUREACCESS_TARGET) {
+ data->fbo = GL_GetFBO(renderdata, texture->w, texture->h);
+ } else {
+ data->fbo = NULL;
+ }
+
+ GL_CheckError("", renderer);
+ renderdata->glGenTextures(1, &data->texture);
+ if (GL_CheckError("glGenTextures()", renderer) < 0) {
+ if (data->pixels) {
+ SDL_free(data->pixels);
+ }
+ SDL_free(data);
+ return -1;
+ }
+ texture->driverdata = data;
+
+ if (renderdata->GL_ARB_texture_non_power_of_two_supported) {
+ data->type = GL_TEXTURE_2D;
+ texture_w = texture->w;
+ texture_h = texture->h;
+ data->texw = 1.0f;
+ data->texh = 1.0f;
+ } else if (renderdata->GL_ARB_texture_rectangle_supported) {
+ data->type = GL_TEXTURE_RECTANGLE_ARB;
+ texture_w = texture->w;
+ texture_h = texture->h;
+ data->texw = (GLfloat) texture_w;
+ data->texh = (GLfloat) texture_h;
+ } else {
+ data->type = GL_TEXTURE_2D;
+ texture_w = power_of_2(texture->w);
+ texture_h = power_of_2(texture->h);
+ data->texw = (GLfloat) (texture->w) / texture_w;
+ data->texh = (GLfloat) texture->h / texture_h;
+ }
+
+ data->format = format;
+ data->formattype = type;
+ scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? GL_NEAREST : GL_LINEAR;
+ renderdata->glEnable(data->type);
+ renderdata->glBindTexture(data->type, data->texture);
+ renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER, scaleMode);
+ renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER, scaleMode);
+ /* According to the spec, CLAMP_TO_EDGE is the default for TEXTURE_RECTANGLE
+ and setting it causes an INVALID_ENUM error in the latest NVidia drivers.
+ */
+ if (data->type != GL_TEXTURE_RECTANGLE_ARB) {
+ renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
+ GL_CLAMP_TO_EDGE);
+ renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
+ GL_CLAMP_TO_EDGE);
+ }
+#ifdef __MACOSX__
+#ifndef GL_TEXTURE_STORAGE_HINT_APPLE
+#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC
+#endif
+#ifndef STORAGE_CACHED_APPLE
+#define STORAGE_CACHED_APPLE 0x85BE
+#endif
+#ifndef STORAGE_SHARED_APPLE
+#define STORAGE_SHARED_APPLE 0x85BF
+#endif
+ if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
+ renderdata->glTexParameteri(data->type, GL_TEXTURE_STORAGE_HINT_APPLE,
+ GL_STORAGE_SHARED_APPLE);
+ } else {
+ renderdata->glTexParameteri(data->type, GL_TEXTURE_STORAGE_HINT_APPLE,
+ GL_STORAGE_CACHED_APPLE);
+ }
+ if (texture->access == SDL_TEXTUREACCESS_STREAMING
+ && texture->format == SDL_PIXELFORMAT_ARGB8888
+ && (texture->w % 8) == 0) {
+ renderdata->glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
+ renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH,
+ (data->pitch / SDL_BYTESPERPIXEL(texture->format)));
+ renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
+ texture_h, 0, format, type, data->pixels);
+ renderdata->glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
+ }
+ else
+#endif
+ {
+ renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
+ texture_h, 0, format, type, NULL);
+ }
+ renderdata->glDisable(data->type);
+ if (GL_CheckError("glTexImage2D()", renderer) < 0) {
+ return -1;
+ }
+
+ if (texture->format == SDL_PIXELFORMAT_YV12 ||
+ texture->format == SDL_PIXELFORMAT_IYUV) {
+ data->yuv = SDL_TRUE;
+
+ renderdata->glGenTextures(1, &data->utexture);
+ renderdata->glGenTextures(1, &data->vtexture);
+ renderdata->glEnable(data->type);
+
+ renderdata->glBindTexture(data->type, data->utexture);
+ renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER,
+ scaleMode);
+ renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER,
+ scaleMode);
+ renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
+ GL_CLAMP_TO_EDGE);
+ renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
+ GL_CLAMP_TO_EDGE);
+ renderdata->glTexImage2D(data->type, 0, internalFormat, (texture_w+1)/2,
+ (texture_h+1)/2, 0, format, type, NULL);
+
+ renderdata->glBindTexture(data->type, data->vtexture);
+ renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER,
+ scaleMode);
+ renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER,
+ scaleMode);
+ renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
+ GL_CLAMP_TO_EDGE);
+ renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
+ GL_CLAMP_TO_EDGE);
+ renderdata->glTexImage2D(data->type, 0, internalFormat, (texture_w+1)/2,
+ (texture_h+1)/2, 0, format, type, NULL);
+
+ renderdata->glDisable(data->type);
+ }
+
+ if (texture->format == SDL_PIXELFORMAT_NV12 ||
+ texture->format == SDL_PIXELFORMAT_NV21) {
+ data->nv12 = SDL_TRUE;
+
+ renderdata->glGenTextures(1, &data->utexture);
+ renderdata->glEnable(data->type);
+
+ renderdata->glBindTexture(data->type, data->utexture);
+ renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER,
+ scaleMode);
+ renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER,
+ scaleMode);
+ renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S,
+ GL_CLAMP_TO_EDGE);
+ renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T,
+ GL_CLAMP_TO_EDGE);
+ renderdata->glTexImage2D(data->type, 0, GL_LUMINANCE_ALPHA, (texture_w+1)/2,
+ (texture_h+1)/2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL);
+ renderdata->glDisable(data->type);
+ }
+
+ return GL_CheckError("", renderer);
+}
+
+static int
+GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+ const SDL_Rect * rect, const void *pixels, int pitch)
+{
+ GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
+ GL_TextureData *data = (GL_TextureData *) texture->driverdata;
+ const int texturebpp = SDL_BYTESPERPIXEL(texture->format);
+
+ SDL_assert(texturebpp != 0); /* otherwise, division by zero later. */
+
+ GL_ActivateRenderer(renderer);
+
+ renderdata->glEnable(data->type);
+ renderdata->glBindTexture(data->type, data->texture);
+ renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, (pitch / texturebpp));
+ renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w,
+ rect->h, data->format, data->formattype,
+ pixels);
+ if (data->yuv) {
+ renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, ((pitch + 1) / 2));
+
+ /* Skip to the correct offset into the next texture */
+ pixels = (const void*)((const Uint8*)pixels + rect->h * pitch);
+ if (texture->format == SDL_PIXELFORMAT_YV12) {
+ renderdata->glBindTexture(data->type, data->vtexture);
+ } else {
+ renderdata->glBindTexture(data->type, data->utexture);
+ }
+ renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
+ (rect->w+1)/2, (rect->h+1)/2,
+ data->format, data->formattype, pixels);
+
+ /* Skip to the correct offset into the next texture */
+ pixels = (const void*)((const Uint8*)pixels + ((rect->h + 1) / 2) * ((pitch + 1) / 2));
+ if (texture->format == SDL_PIXELFORMAT_YV12) {
+ renderdata->glBindTexture(data->type, data->utexture);
+ } else {
+ renderdata->glBindTexture(data->type, data->vtexture);
+ }
+ renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
+ (rect->w+1)/2, (rect->h+1)/2,
+ data->format, data->formattype, pixels);
+ }
+
+ if (data->nv12) {
+ renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, ((pitch + 1) / 2));
+
+ /* Skip to the correct offset into the next texture */
+ pixels = (const void*)((const Uint8*)pixels + rect->h * pitch);
+ renderdata->glBindTexture(data->type, data->utexture);
+ renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
+ (rect->w + 1)/2, (rect->h + 1)/2,
+ GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, pixels);
+ }
+ renderdata->glDisable(data->type);
+
+ return GL_CheckError("glTexSubImage2D()", renderer);
+}
+
+static int
+GL_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
+ const SDL_Rect * rect,
+ const Uint8 *Yplane, int Ypitch,
+ const Uint8 *Uplane, int Upitch,
+ const Uint8 *Vplane, int Vpitch)
+{
+ GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
+ GL_TextureData *data = (GL_TextureData *) texture->driverdata;
+
+ GL_ActivateRenderer(renderer);
+
+ renderdata->glEnable(data->type);
+ renderdata->glBindTexture(data->type, data->texture);
+ renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, Ypitch);
+ renderdata->glTexSubImage2D(data->type, 0, rect->x, rect->y, rect->w,
+ rect->h, data->format, data->formattype,
+ Yplane);
+
+ renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, Upitch);
+ renderdata->glBindTexture(data->type, data->utexture);
+ renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
+ (rect->w + 1)/2, (rect->h + 1)/2,
+ data->format, data->formattype, Uplane);
+
+ renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, Vpitch);
+ renderdata->glBindTexture(data->type, data->vtexture);
+ renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2,
+ (rect->w + 1)/2, (rect->h + 1)/2,
+ data->format, data->formattype, Vplane);
+ renderdata->glDisable(data->type);
+
+ return GL_CheckError("glTexSubImage2D()", renderer);
+}
+
+static int
+GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
+ const SDL_Rect * rect, void **pixels, int *pitch)
+{
+ GL_TextureData *data = (GL_TextureData *) texture->driverdata;
+
+ data->locked_rect = *rect;
+ *pixels =
+ (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
+ rect->x * SDL_BYTESPERPIXEL(texture->format));
+ *pitch = data->pitch;
+ return 0;
+}
+
+static void
+GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+ GL_TextureData *data = (GL_TextureData *) texture->driverdata;
+ const SDL_Rect *rect;
+ void *pixels;
+
+ rect = &data->locked_rect;
+ pixels =
+ (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
+ rect->x * SDL_BYTESPERPIXEL(texture->format));
+ GL_UpdateTexture(renderer, texture, rect, pixels, data->pitch);
+}
+
+static int
+GL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+ GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+ GL_TextureData *texturedata;
+ GLenum status;
+
+ GL_ActivateRenderer(renderer);
+
+ if (!data->GL_EXT_framebuffer_object_supported) {
+ return SDL_SetError("Render targets not supported by OpenGL");
+ }
+
+ if (texture == NULL) {
+ data->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ return 0;
+ }
+
+ texturedata = (GL_TextureData *) texture->driverdata;
+ data->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, texturedata->fbo->FBO);
+ /* TODO: check if texture pixel format allows this operation */
+ data->glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, texturedata->type, texturedata->texture, 0);
+ /* Check FBO status */
+ status = data->glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+ if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ return SDL_SetError("glFramebufferTexture2DEXT() failed");
+ }
+ return 0;
+}
+
+static int
+GL_UpdateViewport(SDL_Renderer * renderer)
+{
+ GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+
+ if (SDL_CurrentContext != data->context) {
+ /* We'll update the viewport after we rebind the context */
+ return 0;
+ }
+
+ if (renderer->target) {
+ data->glViewport(renderer->viewport.x, renderer->viewport.y,
+ renderer->viewport.w, renderer->viewport.h);
+ } else {
+ int w, h;
+
+ SDL_GL_GetDrawableSize(renderer->window, &w, &h);
+ data->glViewport(renderer->viewport.x, (h - renderer->viewport.y - renderer->viewport.h),
+ renderer->viewport.w, renderer->viewport.h);
+ }
+
+ data->glMatrixMode(GL_PROJECTION);
+ data->glLoadIdentity();
+ if (renderer->viewport.w && renderer->viewport.h) {
+ if (renderer->target) {
+ data->glOrtho((GLdouble) 0,
+ (GLdouble) renderer->viewport.w,
+ (GLdouble) 0,
+ (GLdouble) renderer->viewport.h,
+ 0.0, 1.0);
+ } else {
+ data->glOrtho((GLdouble) 0,
+ (GLdouble) renderer->viewport.w,
+ (GLdouble) renderer->viewport.h,
+ (GLdouble) 0,
+ 0.0, 1.0);
+ }
+ }
+ data->glMatrixMode(GL_MODELVIEW);
+
+ return GL_CheckError("", renderer);
+}
+
+static int
+GL_UpdateClipRect(SDL_Renderer * renderer)
+{
+ GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+
+ if (renderer->clipping_enabled) {
+ const SDL_Rect *rect = &renderer->clip_rect;
+ data->glEnable(GL_SCISSOR_TEST);
+ if (renderer->target) {
+ data->glScissor(renderer->viewport.x + rect->x, renderer->viewport.y + rect->y, rect->w, rect->h);
+ } else {
+ int w, h;
+
+ SDL_GL_GetDrawableSize(renderer->window, &w, &h);
+ data->glScissor(renderer->viewport.x + rect->x, h - renderer->viewport.y - rect->y - rect->h, rect->w, rect->h);
+ }
+ } else {
+ data->glDisable(GL_SCISSOR_TEST);
+ }
+ return 0;
+}
+
+static void
+GL_SetShader(GL_RenderData * data, GL_Shader shader)
+{
+ if (data->shaders && shader != data->current.shader) {
+ GL_SelectShader(data->shaders, shader);
+ data->current.shader = shader;
+ }
+}
+
+static void
+GL_SetColor(GL_RenderData * data, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
+ Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
+
+ if (color != data->current.color) {
+ data->glColor4f((GLfloat) r * inv255f,
+ (GLfloat) g * inv255f,
+ (GLfloat) b * inv255f,
+ (GLfloat) a * inv255f);
+ data->current.color = color;
+ }
+}
+
+static void
+GL_SetBlendMode(GL_RenderData * data, SDL_BlendMode blendMode)
+{
+ if (blendMode != data->current.blendMode) {
+ if (blendMode == SDL_BLENDMODE_NONE) {
+ data->glDisable(GL_BLEND);
+ } else {
+ data->glEnable(GL_BLEND);
+ data->glBlendFuncSeparate(GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blendMode)),
+ GetBlendFunc(SDL_GetBlendModeDstColorFactor(blendMode)),
+ GetBlendFunc(SDL_GetBlendModeSrcAlphaFactor(blendMode)),
+ GetBlendFunc(SDL_GetBlendModeDstAlphaFactor(blendMode)));
+ data->glBlendEquation(GetBlendEquation(SDL_GetBlendModeColorOperation(blendMode)));
+ }
+ data->current.blendMode = blendMode;
+ }
+}
+
+static void
+GL_SetDrawingState(SDL_Renderer * renderer)
+{
+ GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+
+ GL_ActivateRenderer(renderer);
+
+ GL_SetColor(data, renderer->r,
+ renderer->g,
+ renderer->b,
+ renderer->a);
+
+ GL_SetBlendMode(data, renderer->blendMode);
+
+ GL_SetShader(data, SHADER_SOLID);
+}
+
+static int
+GL_RenderClear(SDL_Renderer * renderer)
+{
+ GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+
+ GL_ActivateRenderer(renderer);
+
+ data->glClearColor((GLfloat) renderer->r * inv255f,
+ (GLfloat) renderer->g * inv255f,
+ (GLfloat) renderer->b * inv255f,
+ (GLfloat) renderer->a * inv255f);
+
+ if (renderer->clipping_enabled) {
+ data->glDisable(GL_SCISSOR_TEST);
+ }
+
+ data->glClear(GL_COLOR_BUFFER_BIT);
+
+ if (renderer->clipping_enabled) {
+ data->glEnable(GL_SCISSOR_TEST);
+ }
+
+ return 0;
+}
+
+static int
+GL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points,
+ int count)
+{
+ GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+ int i;
+
+ GL_SetDrawingState(renderer);
+
+ data->glBegin(GL_POINTS);
+ for (i = 0; i < count; ++i) {
+ data->glVertex2f(0.5f + points[i].x, 0.5f + points[i].y);
+ }
+ data->glEnd();
+
+ return 0;
+}
+
+static int
+GL_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points,
+ int count)
+{
+ GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+ int i;
+
+ GL_SetDrawingState(renderer);
+
+ if (count > 2 &&
+ points[0].x == points[count-1].x && points[0].y == points[count-1].y) {
+ data->glBegin(GL_LINE_LOOP);
+ /* GL_LINE_LOOP takes care of the final segment */
+ --count;
+ for (i = 0; i < count; ++i) {
+ data->glVertex2f(0.5f + points[i].x, 0.5f + points[i].y);
+ }
+ data->glEnd();
+ } else {
+#if defined(__MACOSX__) || defined(__WIN32__)
+#else
+ int x1, y1, x2, y2;
+#endif
+
+ data->glBegin(GL_LINE_STRIP);
+ for (i = 0; i < count; ++i) {
+ data->glVertex2f(0.5f + points[i].x, 0.5f + points[i].y);
+ }
+ data->glEnd();
+
+ /* The line is half open, so we need one more point to complete it.
+ * http://www.opengl.org/documentation/specs/version1.1/glspec1.1/node47.html
+ * If we have to, we can use vertical line and horizontal line textures
+ * for vertical and horizontal lines, and then create custom textures
+ * for diagonal lines and software render those. It's terrible, but at
+ * least it would be pixel perfect.
+ */
+ data->glBegin(GL_POINTS);
+#if defined(__MACOSX__) || defined(__WIN32__)
+ /* Mac OS X and Windows seem to always leave the last point open */
+ data->glVertex2f(0.5f + points[count-1].x, 0.5f + points[count-1].y);
+#else
+ /* Linux seems to leave the right-most or bottom-most point open */
+ x1 = points[0].x;
+ y1 = points[0].y;
+ x2 = points[count-1].x;
+ y2 = points[count-1].y;
+
+ if (x1 > x2) {
+ data->glVertex2f(0.5f + x1, 0.5f + y1);
+ } else if (x2 > x1) {
+ data->glVertex2f(0.5f + x2, 0.5f + y2);
+ }
+ if (y1 > y2) {
+ data->glVertex2f(0.5f + x1, 0.5f + y1);
+ } else if (y2 > y1) {
+ data->glVertex2f(0.5f + x2, 0.5f + y2);
+ }
+#endif
+ data->glEnd();
+ }
+ return GL_CheckError("", renderer);
+}
+
+static int
+GL_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count)
+{
+ GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+ int i;
+
+ GL_SetDrawingState(renderer);
+
+ for (i = 0; i < count; ++i) {
+ const SDL_FRect *rect = &rects[i];
+
+ data->glRectf(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
+ }
+ return GL_CheckError("", renderer);
+}
+
+static int
+GL_SetupCopy(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+ GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+ GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
+
+ data->glEnable(texturedata->type);
+ if (texturedata->yuv) {
+ data->glActiveTextureARB(GL_TEXTURE2_ARB);
+ data->glBindTexture(texturedata->type, texturedata->vtexture);
+
+ data->glActiveTextureARB(GL_TEXTURE1_ARB);
+ data->glBindTexture(texturedata->type, texturedata->utexture);
+
+ data->glActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+ if (texturedata->nv12) {
+ data->glActiveTextureARB(GL_TEXTURE1_ARB);
+ data->glBindTexture(texturedata->type, texturedata->utexture);
+
+ data->glActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+ data->glBindTexture(texturedata->type, texturedata->texture);
+
+ if (texture->modMode) {
+ GL_SetColor(data, texture->r, texture->g, texture->b, texture->a);
+ } else {
+ GL_SetColor(data, 255, 255, 255, 255);
+ }
+
+ GL_SetBlendMode(data, texture->blendMode);
+
+ if (texturedata->yuv || texturedata->nv12) {
+ switch (SDL_GetYUVConversionModeForResolution(texture->w, texture->h)) {
+ case SDL_YUV_CONVERSION_JPEG:
+ if (texturedata->yuv) {
+ GL_SetShader(data, SHADER_YUV_JPEG);
+ } else if (texture->format == SDL_PIXELFORMAT_NV12) {
+ GL_SetShader(data, SHADER_NV12_JPEG);
+ } else {
+ GL_SetShader(data, SHADER_NV21_JPEG);
+ }
+ break;
+ case SDL_YUV_CONVERSION_BT601:
+ if (texturedata->yuv) {
+ GL_SetShader(data, SHADER_YUV_BT601);
+ } else if (texture->format == SDL_PIXELFORMAT_NV12) {
+ GL_SetShader(data, SHADER_NV12_BT601);
+ } else {
+ GL_SetShader(data, SHADER_NV21_BT601);
+ }
+ break;
+ case SDL_YUV_CONVERSION_BT709:
+ if (texturedata->yuv) {
+ GL_SetShader(data, SHADER_YUV_BT709);
+ } else if (texture->format == SDL_PIXELFORMAT_NV12) {
+ GL_SetShader(data, SHADER_NV12_BT709);
+ } else {
+ GL_SetShader(data, SHADER_NV21_BT709);
+ }
+ break;
+ default:
+ return SDL_SetError("Unsupported YUV conversion mode");
+ }
+ } else {
+ GL_SetShader(data, SHADER_RGB);
+ }
+ return 0;
+}
+
+static int
+GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
+ const SDL_Rect * srcrect, const SDL_FRect * dstrect)
+{
+ GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+ GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
+ GLfloat minx, miny, maxx, maxy;
+ GLfloat minu, maxu, minv, maxv;
+
+ GL_ActivateRenderer(renderer);
+
+ if (GL_SetupCopy(renderer, texture) < 0) {
+ return -1;
+ }
+
+ minx = dstrect->x;
+ miny = dstrect->y;
+ maxx = dstrect->x + dstrect->w;
+ maxy = dstrect->y + dstrect->h;
+
+ minu = (GLfloat) srcrect->x / texture->w;
+ minu *= texturedata->texw;
+ maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w;
+ maxu *= texturedata->texw;
+ minv = (GLfloat) srcrect->y / texture->h;
+ minv *= texturedata->texh;
+ maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
+ maxv *= texturedata->texh;
+
+ data->glBegin(GL_TRIANGLE_STRIP);
+ data->glTexCoord2f(minu, minv);
+ data->glVertex2f(minx, miny);
+ data->glTexCoord2f(maxu, minv);
+ data->glVertex2f(maxx, miny);
+ data->glTexCoord2f(minu, maxv);
+ data->glVertex2f(minx, maxy);
+ data->glTexCoord2f(maxu, maxv);
+ data->glVertex2f(maxx, maxy);
+ data->glEnd();
+
+ data->glDisable(texturedata->type);
+
+ return GL_CheckError("", renderer);
+}
+
+static int
+GL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
+ const SDL_Rect * srcrect, const SDL_FRect * dstrect,
+ const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
+{
+ GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+ GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
+ GLfloat minx, miny, maxx, maxy;
+ GLfloat centerx, centery;
+ GLfloat minu, maxu, minv, maxv;
+
+ GL_ActivateRenderer(renderer);
+
+ if (GL_SetupCopy(renderer, texture) < 0) {
+ return -1;
+ }
+
+ centerx = center->x;
+ centery = center->y;
+
+ if (flip & SDL_FLIP_HORIZONTAL) {
+ minx = dstrect->w - centerx;
+ maxx = -centerx;
+ }
+ else {
+ minx = -centerx;
+ maxx = dstrect->w - centerx;
+ }
+
+ if (flip & SDL_FLIP_VERTICAL) {
+ miny = dstrect->h - centery;
+ maxy = -centery;
+ }
+ else {
+ miny = -centery;
+ maxy = dstrect->h - centery;
+ }
+
+ minu = (GLfloat) srcrect->x / texture->w;
+ minu *= texturedata->texw;
+ maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w;
+ maxu *= texturedata->texw;
+ minv = (GLfloat) srcrect->y / texture->h;
+ minv *= texturedata->texh;
+ maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
+ maxv *= texturedata->texh;
+
+ /* Translate to flip, rotate, translate to position */
+ data->glPushMatrix();
+ data->glTranslatef((GLfloat)dstrect->x + centerx, (GLfloat)dstrect->y + centery, (GLfloat)0.0);
+ data->glRotated(angle, (GLdouble)0.0, (GLdouble)0.0, (GLdouble)1.0);
+
+ data->glBegin(GL_TRIANGLE_STRIP);
+ data->glTexCoord2f(minu, minv);
+ data->glVertex2f(minx, miny);
+ data->glTexCoord2f(maxu, minv);
+ data->glVertex2f(maxx, miny);
+ data->glTexCoord2f(minu, maxv);
+ data->glVertex2f(minx, maxy);
+ data->glTexCoord2f(maxu, maxv);
+ data->glVertex2f(maxx, maxy);
+ data->glEnd();
+ data->glPopMatrix();
+
+ data->glDisable(texturedata->type);
+
+ return GL_CheckError("", renderer);
+}
+
+static int
+GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+ Uint32 pixel_format, void * pixels, int pitch)
+{
+ GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+ Uint32 temp_format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_ARGB8888;
+ void *temp_pixels;
+ int temp_pitch;
+ GLint internalFormat;
+ GLenum format, type;
+ Uint8 *src, *dst, *tmp;
+ int w, h, length, rows;
+ int status;
+
+ GL_ActivateRenderer(renderer);
+
+ if (!convert_format(data, temp_format, &internalFormat, &format, &type)) {
+ return SDL_SetError("Texture format %s not supported by OpenGL",
+ SDL_GetPixelFormatName(temp_format));
+ }
+
+ if (!rect->w || !rect->h) {
+ return 0; /* nothing to do. */
+ }
+
+ temp_pitch = rect->w * SDL_BYTESPERPIXEL(temp_format);
+ temp_pixels = SDL_malloc(rect->h * temp_pitch);
+ if (!temp_pixels) {
+ return SDL_OutOfMemory();
+ }
+
+ SDL_GetRendererOutputSize(renderer, &w, &h);
+
+ data->glPixelStorei(GL_PACK_ALIGNMENT, 1);
+ data->glPixelStorei(GL_PACK_ROW_LENGTH,
+ (temp_pitch / SDL_BYTESPERPIXEL(temp_format)));
+
+ data->glReadPixels(rect->x, renderer->target ? rect->y : (h-rect->y)-rect->h,
+ rect->w, rect->h, format, type, temp_pixels);
+
+ if (GL_CheckError("glReadPixels()", renderer) < 0) {
+ SDL_free(temp_pixels);
+ return -1;
+ }
+
+ /* Flip the rows to be top-down if necessary */
+ if (!renderer->target) {
+ length = rect->w * SDL_BYTESPERPIXEL(temp_format);
+ src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch;
+ dst = (Uint8*)temp_pixels;
+ tmp = SDL_stack_alloc(Uint8, length);
+ rows = rect->h / 2;
+ while (rows--) {
+ SDL_memcpy(tmp, dst, length);
+ SDL_memcpy(dst, src, length);
+ SDL_memcpy(src, tmp, length);
+ dst += temp_pitch;
+ src -= temp_pitch;
+ }
+ SDL_stack_free(tmp);
+ }
+
+ status = SDL_ConvertPixels(rect->w, rect->h,
+ temp_format, temp_pixels, temp_pitch,
+ pixel_format, pixels, pitch);
+ SDL_free(temp_pixels);
+
+ return status;
+}
+
+static void
+GL_RenderPresent(SDL_Renderer * renderer)
+{
+ GL_ActivateRenderer(renderer);
+
+ SDL_GL_SwapWindow(renderer->window);
+}
+
+static void
+GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+ GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
+ GL_TextureData *data = (GL_TextureData *) texture->driverdata;
+
+ GL_ActivateRenderer(renderer);
+
+ if (!data) {
+ return;
+ }
+ if (data->texture) {
+ renderdata->glDeleteTextures(1, &data->texture);
+ }
+ if (data->yuv) {
+ renderdata->glDeleteTextures(1, &data->utexture);
+ renderdata->glDeleteTextures(1, &data->vtexture);
+ }
+ SDL_free(data->pixels);
+ SDL_free(data);
+ texture->driverdata = NULL;
+}
+
+static void
+GL_DestroyRenderer(SDL_Renderer * renderer)
+{
+ GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+
+ if (data) {
+ if (data->context != NULL) {
+ /* make sure we delete the right resources! */
+ GL_ActivateRenderer(renderer);
+ }
+
+ GL_ClearErrors(renderer);
+ if (data->GL_ARB_debug_output_supported) {
+ PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARBFunc = (PFNGLDEBUGMESSAGECALLBACKARBPROC) SDL_GL_GetProcAddress("glDebugMessageCallbackARB");
+
+ /* Uh oh, we don't have a safe way of removing ourselves from the callback chain, if it changed after we set our callback. */
+ /* For now, just always replace the callback with the original one */
+ glDebugMessageCallbackARBFunc(data->next_error_callback, data->next_error_userparam);
+ }
+ if (data->shaders) {
+ GL_DestroyShaderContext(data->shaders);
+ }
+ if (data->context) {
+ while (data->framebuffers) {
+ GL_FBOList *nextnode = data->framebuffers->next;
+ /* delete the framebuffer object */
+ data->glDeleteFramebuffersEXT(1, &data->framebuffers->FBO);
+ GL_CheckError("", renderer);
+ SDL_free(data->framebuffers);
+ data->framebuffers = nextnode;
+ }
+ SDL_GL_DeleteContext(data->context);
+ }
+ SDL_free(data);
+ }
+ SDL_free(renderer);
+}
+
+static int
+GL_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh)
+{
+ GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+ GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
+ GL_ActivateRenderer(renderer);
+
+ data->glEnable(texturedata->type);
+ if (texturedata->yuv) {
+ data->glActiveTextureARB(GL_TEXTURE2_ARB);
+ data->glBindTexture(texturedata->type, texturedata->vtexture);
+
+ data->glActiveTextureARB(GL_TEXTURE1_ARB);
+ data->glBindTexture(texturedata->type, texturedata->utexture);
+
+ data->glActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+ data->glBindTexture(texturedata->type, texturedata->texture);
+
+ if(texw) *texw = (float)texturedata->texw;
+ if(texh) *texh = (float)texturedata->texh;
+
+ return 0;
+}
+
+static int
+GL_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture)
+{
+ GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
+ GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata;
+ GL_ActivateRenderer(renderer);
+
+ if (texturedata->yuv) {
+ data->glActiveTextureARB(GL_TEXTURE2_ARB);
+ data->glDisable(texturedata->type);
+
+ data->glActiveTextureARB(GL_TEXTURE1_ARB);
+ data->glDisable(texturedata->type);
+
+ data->glActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+
+ data->glDisable(texturedata->type);
+
+ return 0;
+}
+
+#endif /* SDL_VIDEO_RENDER_OGL && !SDL_RENDER_DISABLED */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/render/opengl/SDL_shaders_gl.c b/source/3rd-party/SDL2/src/render/opengl/SDL_shaders_gl.c
new file mode 100644
index 0000000..251b54d
--- /dev/null
+++ b/source/3rd-party/SDL2/src/render/opengl/SDL_shaders_gl.c
@@ -0,0 +1,524 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_RENDER_OGL && !SDL_RENDER_DISABLED
+
+#include "SDL_stdinc.h"
+#include "SDL_log.h"
+#include "SDL_opengl.h"
+#include "SDL_video.h"
+#include "SDL_shaders_gl.h"
+
+/* OpenGL shader implementation */
+
+/* #define DEBUG_SHADERS */
+
+typedef struct
+{
+ GLhandleARB program;
+ GLhandleARB vert_shader;
+ GLhandleARB frag_shader;
+} GL_ShaderData;
+
+struct GL_ShaderContext
+{
+ GLenum (*glGetError)(void);
+
+ PFNGLATTACHOBJECTARBPROC glAttachObjectARB;
+ PFNGLCOMPILESHADERARBPROC glCompileShaderARB;
+ PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB;
+ PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
+ PFNGLDELETEOBJECTARBPROC glDeleteObjectARB;
+ PFNGLGETINFOLOGARBPROC glGetInfoLogARB;
+ PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
+ PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB;
+ PFNGLLINKPROGRAMARBPROC glLinkProgramARB;
+ PFNGLSHADERSOURCEARBPROC glShaderSourceARB;
+ PFNGLUNIFORM1IARBPROC glUniform1iARB;
+ PFNGLUNIFORM1FARBPROC glUniform1fARB;
+ PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB;
+
+ SDL_bool GL_ARB_texture_rectangle_supported;
+
+ GL_ShaderData shaders[NUM_SHADERS];
+};
+
+#define COLOR_VERTEX_SHADER \
+"varying vec4 v_color;\n" \
+"\n" \
+"void main()\n" \
+"{\n" \
+" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" \
+" v_color = gl_Color;\n" \
+"}" \
+
+#define TEXTURE_VERTEX_SHADER \
+"varying vec4 v_color;\n" \
+"varying vec2 v_texCoord;\n" \
+"\n" \
+"void main()\n" \
+"{\n" \
+" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" \
+" v_color = gl_Color;\n" \
+" v_texCoord = vec2(gl_MultiTexCoord0);\n" \
+"}" \
+
+#define JPEG_SHADER_CONSTANTS \
+"// YUV offset \n" \
+"const vec3 offset = vec3(0, -0.501960814, -0.501960814);\n" \
+"\n" \
+"// RGB coefficients \n" \
+"const vec3 Rcoeff = vec3(1, 0.000, 1.402);\n" \
+"const vec3 Gcoeff = vec3(1, -0.3441, -0.7141);\n" \
+"const vec3 Bcoeff = vec3(1, 1.772, 0.000);\n" \
+
+#define BT601_SHADER_CONSTANTS \
+"// YUV offset \n" \
+"const vec3 offset = vec3(-0.0627451017, -0.501960814, -0.501960814);\n" \
+"\n" \
+"// RGB coefficients \n" \
+"const vec3 Rcoeff = vec3(1.1644, 0.000, 1.596);\n" \
+"const vec3 Gcoeff = vec3(1.1644, -0.3918, -0.813);\n" \
+"const vec3 Bcoeff = vec3(1.1644, 2.0172, 0.000);\n" \
+
+#define BT709_SHADER_CONSTANTS \
+"// YUV offset \n" \
+"const vec3 offset = vec3(-0.0627451017, -0.501960814, -0.501960814);\n" \
+"\n" \
+"// RGB coefficients \n" \
+"const vec3 Rcoeff = vec3(1.1644, 0.000, 1.7927);\n" \
+"const vec3 Gcoeff = vec3(1.1644, -0.2132, -0.5329);\n" \
+"const vec3 Bcoeff = vec3(1.1644, 2.1124, 0.000);\n" \
+
+#define YUV_SHADER_PROLOGUE \
+"varying vec4 v_color;\n" \
+"varying vec2 v_texCoord;\n" \
+"uniform sampler2D tex0; // Y \n" \
+"uniform sampler2D tex1; // U \n" \
+"uniform sampler2D tex2; // V \n" \
+"\n" \
+
+#define YUV_SHADER_BODY \
+"\n" \
+"void main()\n" \
+"{\n" \
+" vec2 tcoord;\n" \
+" vec3 yuv, rgb;\n" \
+"\n" \
+" // Get the Y value \n" \
+" tcoord = v_texCoord;\n" \
+" yuv.x = texture2D(tex0, tcoord).r;\n" \
+"\n" \
+" // Get the U and V values \n" \
+" tcoord *= UVCoordScale;\n" \
+" yuv.y = texture2D(tex1, tcoord).r;\n" \
+" yuv.z = texture2D(tex2, tcoord).r;\n" \
+"\n" \
+" // Do the color transform \n" \
+" yuv += offset;\n" \
+" rgb.r = dot(yuv, Rcoeff);\n" \
+" rgb.g = dot(yuv, Gcoeff);\n" \
+" rgb.b = dot(yuv, Bcoeff);\n" \
+"\n" \
+" // That was easy. :) \n" \
+" gl_FragColor = vec4(rgb, 1.0) * v_color;\n" \
+"}" \
+
+#define NV12_SHADER_PROLOGUE \
+"varying vec4 v_color;\n" \
+"varying vec2 v_texCoord;\n" \
+"uniform sampler2D tex0; // Y \n" \
+"uniform sampler2D tex1; // U/V \n" \
+"\n" \
+
+#define NV12_SHADER_BODY \
+"\n" \
+"void main()\n" \
+"{\n" \
+" vec2 tcoord;\n" \
+" vec3 yuv, rgb;\n" \
+"\n" \
+" // Get the Y value \n" \
+" tcoord = v_texCoord;\n" \
+" yuv.x = texture2D(tex0, tcoord).r;\n" \
+"\n" \
+" // Get the U and V values \n" \
+" tcoord *= UVCoordScale;\n" \
+" yuv.yz = texture2D(tex1, tcoord).ra;\n" \
+"\n" \
+" // Do the color transform \n" \
+" yuv += offset;\n" \
+" rgb.r = dot(yuv, Rcoeff);\n" \
+" rgb.g = dot(yuv, Gcoeff);\n" \
+" rgb.b = dot(yuv, Bcoeff);\n" \
+"\n" \
+" // That was easy. :) \n" \
+" gl_FragColor = vec4(rgb, 1.0) * v_color;\n" \
+"}" \
+
+#define NV21_SHADER_PROLOGUE \
+"varying vec4 v_color;\n" \
+"varying vec2 v_texCoord;\n" \
+"uniform sampler2D tex0; // Y \n" \
+"uniform sampler2D tex1; // U/V \n" \
+"\n" \
+
+#define NV21_SHADER_BODY \
+"\n" \
+"void main()\n" \
+"{\n" \
+" vec2 tcoord;\n" \
+" vec3 yuv, rgb;\n" \
+"\n" \
+" // Get the Y value \n" \
+" tcoord = v_texCoord;\n" \
+" yuv.x = texture2D(tex0, tcoord).r;\n" \
+"\n" \
+" // Get the U and V values \n" \
+" tcoord *= UVCoordScale;\n" \
+" yuv.yz = texture2D(tex1, tcoord).ar;\n" \
+"\n" \
+" // Do the color transform \n" \
+" yuv += offset;\n" \
+" rgb.r = dot(yuv, Rcoeff);\n" \
+" rgb.g = dot(yuv, Gcoeff);\n" \
+" rgb.b = dot(yuv, Bcoeff);\n" \
+"\n" \
+" // That was easy. :) \n" \
+" gl_FragColor = vec4(rgb, 1.0) * v_color;\n" \
+"}" \
+
+/*
+ * NOTE: Always use sampler2D, etc here. We'll #define them to the
+ * texture_rectangle versions if we choose to use that extension.
+ */
+static const char *shader_source[NUM_SHADERS][2] =
+{
+ /* SHADER_NONE */
+ { NULL, NULL },
+
+ /* SHADER_SOLID */
+ {
+ /* vertex shader */
+ COLOR_VERTEX_SHADER,
+ /* fragment shader */
+"varying vec4 v_color;\n"
+"\n"
+"void main()\n"
+"{\n"
+" gl_FragColor = v_color;\n"
+"}"
+ },
+
+ /* SHADER_RGB */
+ {
+ /* vertex shader */
+ TEXTURE_VERTEX_SHADER,
+ /* fragment shader */
+"varying vec4 v_color;\n"
+"varying vec2 v_texCoord;\n"
+"uniform sampler2D tex0;\n"
+"\n"
+"void main()\n"
+"{\n"
+" gl_FragColor = texture2D(tex0, v_texCoord) * v_color;\n"
+"}"
+ },
+
+ /* SHADER_YUV_JPEG */
+ {
+ /* vertex shader */
+ TEXTURE_VERTEX_SHADER,
+ /* fragment shader */
+ YUV_SHADER_PROLOGUE
+ JPEG_SHADER_CONSTANTS
+ YUV_SHADER_BODY
+ },
+ /* SHADER_YUV_BT601 */
+ {
+ /* vertex shader */
+ TEXTURE_VERTEX_SHADER,
+ /* fragment shader */
+ YUV_SHADER_PROLOGUE
+ BT601_SHADER_CONSTANTS
+ YUV_SHADER_BODY
+ },
+ /* SHADER_YUV_BT709 */
+ {
+ /* vertex shader */
+ TEXTURE_VERTEX_SHADER,
+ /* fragment shader */
+ YUV_SHADER_PROLOGUE
+ BT709_SHADER_CONSTANTS
+ YUV_SHADER_BODY
+ },
+ /* SHADER_NV12_JPEG */
+ {
+ /* vertex shader */
+ TEXTURE_VERTEX_SHADER,
+ /* fragment shader */
+ NV12_SHADER_PROLOGUE
+ JPEG_SHADER_CONSTANTS
+ NV12_SHADER_BODY
+ },
+ /* SHADER_NV12_BT601 */
+ {
+ /* vertex shader */
+ TEXTURE_VERTEX_SHADER,
+ /* fragment shader */
+ NV12_SHADER_PROLOGUE
+ BT601_SHADER_CONSTANTS
+ NV12_SHADER_BODY
+ },
+ /* SHADER_NV12_BT709 */
+ {
+ /* vertex shader */
+ TEXTURE_VERTEX_SHADER,
+ /* fragment shader */
+ NV12_SHADER_PROLOGUE
+ BT709_SHADER_CONSTANTS
+ NV12_SHADER_BODY
+ },
+ /* SHADER_NV21_JPEG */
+ {
+ /* vertex shader */
+ TEXTURE_VERTEX_SHADER,
+ /* fragment shader */
+ NV21_SHADER_PROLOGUE
+ JPEG_SHADER_CONSTANTS
+ NV21_SHADER_BODY
+ },
+ /* SHADER_NV21_BT601 */
+ {
+ /* vertex shader */
+ TEXTURE_VERTEX_SHADER,
+ /* fragment shader */
+ NV21_SHADER_PROLOGUE
+ BT601_SHADER_CONSTANTS
+ NV21_SHADER_BODY
+ },
+ /* SHADER_NV21_BT709 */
+ {
+ /* vertex shader */
+ TEXTURE_VERTEX_SHADER,
+ /* fragment shader */
+ NV21_SHADER_PROLOGUE
+ BT709_SHADER_CONSTANTS
+ NV21_SHADER_BODY
+ },
+};
+
+static SDL_bool
+CompileShader(GL_ShaderContext *ctx, GLhandleARB shader, const char *defines, const char *source)
+{
+ GLint status;
+ const char *sources[2];
+
+ sources[0] = defines;
+ sources[1] = source;
+
+ ctx->glShaderSourceARB(shader, SDL_arraysize(sources), sources, NULL);
+ ctx->glCompileShaderARB(shader);
+ ctx->glGetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &status);
+ if (status == 0) {
+ GLint length;
+ char *info;
+
+ ctx->glGetObjectParameterivARB(shader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length);
+ info = SDL_stack_alloc(char, length+1);
+ ctx->glGetInfoLogARB(shader, length, NULL, info);
+ SDL_LogError(SDL_LOG_CATEGORY_RENDER,
+ "Failed to compile shader:\n%s%s\n%s", defines, source, info);
+#ifdef DEBUG_SHADERS
+ fprintf(stderr,
+ "Failed to compile shader:\n%s%s\n%s", defines, source, info);
+#endif
+ SDL_stack_free(info);
+
+ return SDL_FALSE;
+ } else {
+ return SDL_TRUE;
+ }
+}
+
+static SDL_bool
+CompileShaderProgram(GL_ShaderContext *ctx, int index, GL_ShaderData *data)
+{
+ const int num_tmus_bound = 4;
+ const char *vert_defines = "";
+ const char *frag_defines = "";
+ int i;
+ GLint location;
+
+ if (index == SHADER_NONE) {
+ return SDL_TRUE;
+ }
+
+ ctx->glGetError();
+
+ /* Make sure we use the correct sampler type for our texture type */
+ if (ctx->GL_ARB_texture_rectangle_supported) {
+ frag_defines =
+"#define sampler2D sampler2DRect\n"
+"#define texture2D texture2DRect\n"
+"#define UVCoordScale 0.5\n";
+ } else {
+ frag_defines =
+"#define UVCoordScale 1.0\n";
+ }
+
+ /* Create one program object to rule them all */
+ data->program = ctx->glCreateProgramObjectARB();
+
+ /* Create the vertex shader */
+ data->vert_shader = ctx->glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
+ if (!CompileShader(ctx, data->vert_shader, vert_defines, shader_source[index][0])) {
+ return SDL_FALSE;
+ }
+
+ /* Create the fragment shader */
+ data->frag_shader = ctx->glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
+ if (!CompileShader(ctx, data->frag_shader, frag_defines, shader_source[index][1])) {
+ return SDL_FALSE;
+ }
+
+ /* ... and in the darkness bind them */
+ ctx->glAttachObjectARB(data->program, data->vert_shader);
+ ctx->glAttachObjectARB(data->program, data->frag_shader);
+ ctx->glLinkProgramARB(data->program);
+
+ /* Set up some uniform variables */
+ ctx->glUseProgramObjectARB(data->program);
+ for (i = 0; i < num_tmus_bound; ++i) {
+ char tex_name[10];
+ SDL_snprintf(tex_name, SDL_arraysize(tex_name), "tex%d", i);
+ location = ctx->glGetUniformLocationARB(data->program, tex_name);
+ if (location >= 0) {
+ ctx->glUniform1iARB(location, i);
+ }
+ }
+ ctx->glUseProgramObjectARB(0);
+
+ return (ctx->glGetError() == GL_NO_ERROR);
+}
+
+static void
+DestroyShaderProgram(GL_ShaderContext *ctx, GL_ShaderData *data)
+{
+ ctx->glDeleteObjectARB(data->vert_shader);
+ ctx->glDeleteObjectARB(data->frag_shader);
+ ctx->glDeleteObjectARB(data->program);
+}
+
+GL_ShaderContext *
+GL_CreateShaderContext(void)
+{
+ GL_ShaderContext *ctx;
+ SDL_bool shaders_supported;
+ int i;
+
+ ctx = (GL_ShaderContext *)SDL_calloc(1, sizeof(*ctx));
+ if (!ctx) {
+ return NULL;
+ }
+
+ if (!SDL_GL_ExtensionSupported("GL_ARB_texture_non_power_of_two") &&
+ (SDL_GL_ExtensionSupported("GL_ARB_texture_rectangle") ||
+ SDL_GL_ExtensionSupported("GL_EXT_texture_rectangle"))) {
+ ctx->GL_ARB_texture_rectangle_supported = SDL_TRUE;
+ }
+
+ /* Check for shader support */
+ shaders_supported = SDL_FALSE;
+ if (SDL_GL_ExtensionSupported("GL_ARB_shader_objects") &&
+ SDL_GL_ExtensionSupported("GL_ARB_shading_language_100") &&
+ SDL_GL_ExtensionSupported("GL_ARB_vertex_shader") &&
+ SDL_GL_ExtensionSupported("GL_ARB_fragment_shader")) {
+ ctx->glGetError = (GLenum (*)(void)) SDL_GL_GetProcAddress("glGetError");
+ ctx->glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) SDL_GL_GetProcAddress("glAttachObjectARB");
+ ctx->glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) SDL_GL_GetProcAddress("glCompileShaderARB");
+ ctx->glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) SDL_GL_GetProcAddress("glCreateProgramObjectARB");
+ ctx->glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) SDL_GL_GetProcAddress("glCreateShaderObjectARB");
+ ctx->glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) SDL_GL_GetProcAddress("glDeleteObjectARB");
+ ctx->glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC) SDL_GL_GetProcAddress("glGetInfoLogARB");
+ ctx->glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) SDL_GL_GetProcAddress("glGetObjectParameterivARB");
+ ctx->glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) SDL_GL_GetProcAddress("glGetUniformLocationARB");
+ ctx->glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) SDL_GL_GetProcAddress("glLinkProgramARB");
+ ctx->glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) SDL_GL_GetProcAddress("glShaderSourceARB");
+ ctx->glUniform1iARB = (PFNGLUNIFORM1IARBPROC) SDL_GL_GetProcAddress("glUniform1iARB");
+ ctx->glUniform1fARB = (PFNGLUNIFORM1FARBPROC) SDL_GL_GetProcAddress("glUniform1fARB");
+ ctx->glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) SDL_GL_GetProcAddress("glUseProgramObjectARB");
+ if (ctx->glGetError &&
+ ctx->glAttachObjectARB &&
+ ctx->glCompileShaderARB &&
+ ctx->glCreateProgramObjectARB &&
+ ctx->glCreateShaderObjectARB &&
+ ctx->glDeleteObjectARB &&
+ ctx->glGetInfoLogARB &&
+ ctx->glGetObjectParameterivARB &&
+ ctx->glGetUniformLocationARB &&
+ ctx->glLinkProgramARB &&
+ ctx->glShaderSourceARB &&
+ ctx->glUniform1iARB &&
+ ctx->glUniform1fARB &&
+ ctx->glUseProgramObjectARB) {
+ shaders_supported = SDL_TRUE;
+ }
+ }
+
+ if (!shaders_supported) {
+ SDL_free(ctx);
+ return NULL;
+ }
+
+ /* Compile all the shaders */
+ for (i = 0; i < NUM_SHADERS; ++i) {
+ if (!CompileShaderProgram(ctx, i, &ctx->shaders[i])) {
+ GL_DestroyShaderContext(ctx);
+ return NULL;
+ }
+ }
+
+ /* We're done! */
+ return ctx;
+}
+
+void
+GL_SelectShader(GL_ShaderContext *ctx, GL_Shader shader)
+{
+ ctx->glUseProgramObjectARB(ctx->shaders[shader].program);
+}
+
+void
+GL_DestroyShaderContext(GL_ShaderContext *ctx)
+{
+ int i;
+
+ for (i = 0; i < NUM_SHADERS; ++i) {
+ DestroyShaderProgram(ctx, &ctx->shaders[i]);
+ }
+ SDL_free(ctx);
+}
+
+#endif /* SDL_VIDEO_RENDER_OGL && !SDL_RENDER_DISABLED */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/render/opengl/SDL_shaders_gl.h b/source/3rd-party/SDL2/src/render/opengl/SDL_shaders_gl.h
new file mode 100644
index 0000000..3697521
--- /dev/null
+++ b/source/3rd-party/SDL2/src/render/opengl/SDL_shaders_gl.h
@@ -0,0 +1,53 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_shaders_gl_h_
+#define SDL_shaders_gl_h_
+
+#include "../../SDL_internal.h"
+
+/* OpenGL shader implementation */
+
+typedef enum {
+ SHADER_NONE,
+ SHADER_SOLID,
+ SHADER_RGB,
+ SHADER_YUV_JPEG,
+ SHADER_YUV_BT601,
+ SHADER_YUV_BT709,
+ SHADER_NV12_JPEG,
+ SHADER_NV12_BT601,
+ SHADER_NV12_BT709,
+ SHADER_NV21_JPEG,
+ SHADER_NV21_BT601,
+ SHADER_NV21_BT709,
+ NUM_SHADERS
+} GL_Shader;
+
+typedef struct GL_ShaderContext GL_ShaderContext;
+
+extern GL_ShaderContext * GL_CreateShaderContext(void);
+extern void GL_SelectShader(GL_ShaderContext *ctx, GL_Shader shader);
+extern void GL_DestroyShaderContext(GL_ShaderContext *ctx);
+
+#endif /* SDL_shaders_gl_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */