mirror of https://github.com/PCSX2/pcsx2.git
355 lines
9.7 KiB
C++
355 lines
9.7 KiB
C++
/* ZZ Open GL graphics plugin
|
|
* Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
|
|
* Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
#ifndef ZZGL_H_INCLUDED
|
|
#define ZZGL_H_INCLUDED
|
|
|
|
#include "PS2Etypes.h"
|
|
#include "PS2Edefs.h"
|
|
|
|
// Need this before gl.h
|
|
#ifdef _WIN32
|
|
|
|
#include "Utilities/RedtapeWindows.h"
|
|
|
|
#include <GL/gl.h>
|
|
#include <GL/glext.h>
|
|
#include "glprocs.h"
|
|
|
|
#else
|
|
|
|
// adding glew support instead of glXGetProcAddress (thanks to scaught)
|
|
#include <GL/glew.h>
|
|
#include <GL/gl.h>
|
|
#include <GL/glext.h>
|
|
#include <GL/glx.h>
|
|
|
|
#endif
|
|
|
|
#include "Mem.h"
|
|
|
|
extern u32 s_stencilfunc, s_stencilref, s_stencilmask;
|
|
extern GLenum s_srcrgb, s_dstrgb, s_srcalpha, s_dstalpha; // set by zgsBlendFuncSeparateEXT
|
|
extern GLenum s_rgbeq, s_alphaeq;
|
|
|
|
#ifndef GL_DEPTH24_STENCIL8_EXT // allows FBOs to support stencils
|
|
# define GL_DEPTH_STENCIL_EXT 0x84F9
|
|
# define GL_UNSIGNED_INT_24_8_EXT 0x84FA
|
|
# define GL_DEPTH24_STENCIL8_EXT 0x88F0
|
|
# define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1
|
|
#endif
|
|
|
|
#ifdef _WIN32
|
|
#define GL_LOADFN(name) { \
|
|
if( (*(void**)&name = (void*)wglGetProcAddress(#name)) == NULL ) { \
|
|
ZZLog::Error_Log("Failed to find %s, exiting.", #name); \
|
|
} \
|
|
}
|
|
#else
|
|
// let GLEW take care of it
|
|
#define GL_LOADFN(name)
|
|
#endif
|
|
|
|
static __forceinline void GL_STENCILFUNC(GLenum func, GLint ref, GLuint mask)
|
|
{
|
|
s_stencilfunc = func;
|
|
s_stencilref = ref;
|
|
s_stencilmask = mask;
|
|
glStencilFunc(func, ref, mask);
|
|
}
|
|
|
|
static __forceinline void GL_STENCILFUNC_SET()
|
|
{
|
|
glStencilFunc(s_stencilfunc, s_stencilref, s_stencilmask);
|
|
}
|
|
|
|
#ifdef GLSL4_API
|
|
#include "ZZoglShaders.h"
|
|
#endif
|
|
// sets the data stream
|
|
static __forceinline void SET_STREAM()
|
|
{
|
|
#ifndef GLSL4_API
|
|
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(VertexGPU), (void*)8);
|
|
glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, sizeof(VertexGPU), (void*)12);
|
|
glTexCoordPointer(3, GL_FLOAT, sizeof(VertexGPU), (void*)16);
|
|
glVertexPointer(4, GL_SHORT, sizeof(VertexGPU), (void*)0);
|
|
#else
|
|
vertex_array->set_internal_format();
|
|
#endif
|
|
}
|
|
|
|
//static __forceinline void SAFE_RELEASE_TEX(u32& x)
|
|
//{
|
|
// if (x != 0)
|
|
// {
|
|
// glDeleteTextures(1, &x);
|
|
// x = 0;
|
|
// }
|
|
//}
|
|
#define SAFE_RELEASE_TEX(x) { if( (x) != 0 ) { glDeleteTextures(1, &(x)); x = 0; } }
|
|
|
|
// inline for an extremely often used sequence
|
|
// This is turning off all gl functions. Safe to do updates.
|
|
inline void DisableAllgl()
|
|
{
|
|
glDisable(GL_SCISSOR_TEST);
|
|
glDisable(GL_BLEND);
|
|
glDisable(GL_ALPHA_TEST);
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDepthMask(0);
|
|
glDisable(GL_STENCIL_TEST);
|
|
glColorMask(1, 1, 1, 1);
|
|
}
|
|
|
|
//--------------------- Dummies
|
|
|
|
#ifdef _WIN32
|
|
extern void (__stdcall *zgsBlendEquationSeparateEXT)(GLenum, GLenum);
|
|
extern void (__stdcall *zgsBlendFuncSeparateEXT)(GLenum, GLenum, GLenum, GLenum);
|
|
#else
|
|
extern void (APIENTRY *zgsBlendEquationSeparateEXT)(GLenum, GLenum);
|
|
extern void (APIENTRY *zgsBlendFuncSeparateEXT)(GLenum, GLenum, GLenum, GLenum);
|
|
#endif
|
|
|
|
// GL prototypes
|
|
extern PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT;
|
|
extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT;
|
|
extern PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT;
|
|
extern PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT;
|
|
extern PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT;
|
|
extern PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glGetRenderbufferParameterivEXT;
|
|
extern PFNGLISFRAMEBUFFEREXTPROC glIsFramebufferEXT;
|
|
extern PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
|
|
extern PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
|
|
extern PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT;
|
|
extern PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
|
|
extern PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glFramebufferTexture1DEXT;
|
|
extern PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
|
|
extern PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT;
|
|
extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT;
|
|
extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT;
|
|
extern PFNGLDRAWBUFFERSPROC glDrawBuffers;
|
|
|
|
#ifdef GLSL4_API
|
|
#include "ZZoglShaders.h"
|
|
#endif
|
|
static __forceinline void DrawTriangleArray()
|
|
{
|
|
#ifdef GLSL4_API
|
|
ZZshSetupShader();
|
|
#endif
|
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
|
GL_REPORT_ERRORD();
|
|
}
|
|
|
|
static __forceinline void DrawBuffers(GLenum *buffer)
|
|
{
|
|
if (glDrawBuffers != NULL)
|
|
{
|
|
glDrawBuffers(1, buffer);
|
|
}
|
|
|
|
GL_REPORT_ERRORD();
|
|
}
|
|
|
|
|
|
namespace FB
|
|
{
|
|
extern u32 buf;
|
|
|
|
static __forceinline void Create()
|
|
{
|
|
assert(buf == 0);
|
|
glGenFramebuffersEXT(1, &buf);
|
|
if (buf == 0)
|
|
ZZLog::Error_Log("Failed to create the renderbuffer.");
|
|
}
|
|
|
|
static __forceinline void Delete()
|
|
{
|
|
if (buf != 0) {
|
|
glDeleteFramebuffersEXT(1, &buf);
|
|
buf = 0;
|
|
}
|
|
}
|
|
|
|
static __forceinline void Bind()
|
|
{
|
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, buf);
|
|
}
|
|
|
|
static __forceinline void Unbind()
|
|
{
|
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
|
}
|
|
|
|
static __forceinline GLenum State()
|
|
{
|
|
return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
|
}
|
|
|
|
static __forceinline void Attach2D(int attach, int id = 0)
|
|
{
|
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + attach, GL_TEXTURE_RECTANGLE_NV, id, 0);
|
|
GL_REPORT_ERRORD();
|
|
}
|
|
|
|
static __forceinline void Attach(GLenum rend, GLuint id = 0)
|
|
{
|
|
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, rend, GL_RENDERBUFFER_EXT, id);
|
|
}
|
|
};
|
|
|
|
static __forceinline void ResetRenderTarget(int index)
|
|
{
|
|
FB::Attach2D(index);
|
|
}
|
|
|
|
static __forceinline void TextureImage(GLenum tex_type, GLint iFormat, GLint width, GLint height, GLenum format, GLenum type, const GLvoid* pixels)
|
|
{
|
|
glTexImage2D(tex_type, 0, iFormat, width, height, 0, format, type, pixels);
|
|
}
|
|
|
|
static __forceinline void Texture2D(GLint iFormat, GLint width, GLint height, GLenum format, GLenum type, const GLvoid* pixels)
|
|
{
|
|
TextureImage(GL_TEXTURE_2D, iFormat, width, height, format, type, pixels);
|
|
}
|
|
|
|
static __forceinline void Texture2D(GLint iFormat, GLenum format, GLenum type, const GLvoid* pixels)
|
|
{
|
|
TextureImage(GL_TEXTURE_2D, iFormat, BLOCK_TEXWIDTH, BLOCK_TEXHEIGHT, format, type, pixels);
|
|
}
|
|
|
|
static __forceinline void TextureRect(GLint iFormat, GLint width, GLint height, GLenum format, GLenum type, const GLvoid* pixels)
|
|
{
|
|
TextureImage(GL_TEXTURE_RECTANGLE_NV, iFormat, width, height, format, type, pixels);
|
|
}
|
|
|
|
static __forceinline void TextureRect2(GLint iFormat, GLint width, GLint height, GLenum format, GLenum type, const GLvoid* pixels)
|
|
{
|
|
TextureImage(GL_TEXTURE_RECTANGLE, iFormat, width, height, format, type, pixels);
|
|
}
|
|
|
|
static __forceinline void Texture3D(GLint iFormat, GLint width, GLint height, GLint depth, GLenum format, GLenum type, const GLvoid* pixels)
|
|
{
|
|
glTexImage3D(GL_TEXTURE_3D, 0, iFormat, width, height, depth, 0, format, type, pixels);
|
|
}
|
|
|
|
static __forceinline void setTex2DFilters(GLint type)
|
|
{
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, type);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, type);
|
|
}
|
|
|
|
static __forceinline void setTex2DWrap(GLint type)
|
|
{
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, type);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, type);
|
|
}
|
|
|
|
static __forceinline void setTex3DFilters(GLint type)
|
|
{
|
|
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, type);
|
|
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, type);
|
|
}
|
|
|
|
static __forceinline void setTex3DWrap(GLint type)
|
|
{
|
|
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, type);
|
|
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, type);
|
|
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, type);
|
|
}
|
|
|
|
static __forceinline void setRectFilters(GLint type)
|
|
{
|
|
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, type);
|
|
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, type);
|
|
}
|
|
|
|
static __forceinline void setRectWrap(GLint type)
|
|
{
|
|
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, type);
|
|
glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, type);
|
|
}
|
|
|
|
static __forceinline void setRectWrap2(GLint type)
|
|
{
|
|
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, type);
|
|
glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, type);
|
|
}
|
|
|
|
static __forceinline void GL_BLEND_SET()
|
|
{
|
|
zgsBlendFuncSeparateEXT(s_srcrgb, s_dstrgb, s_srcalpha, s_dstalpha);
|
|
}
|
|
|
|
static __forceinline void GL_BLEND_RGB(GLenum src, GLenum dst)
|
|
{
|
|
s_srcrgb = src;
|
|
s_dstrgb = dst;
|
|
GL_BLEND_SET();
|
|
}
|
|
|
|
static __forceinline void GL_BLEND_ALPHA(GLenum src, GLenum dst)
|
|
{
|
|
s_srcalpha = src;
|
|
s_dstalpha = dst;
|
|
GL_BLEND_SET();
|
|
}
|
|
|
|
static __forceinline void GL_BLEND_ALL(GLenum srcrgb, GLenum dstrgb, GLenum srcalpha, GLenum dstalpha)
|
|
{
|
|
s_srcrgb = srcrgb;
|
|
s_dstrgb = dstrgb;
|
|
s_srcalpha = srcalpha;
|
|
s_dstalpha = dstalpha;
|
|
GL_BLEND_SET();
|
|
}
|
|
|
|
static __forceinline void GL_ZTEST(bool enable)
|
|
{
|
|
if (enable)
|
|
glEnable(GL_DEPTH_TEST);
|
|
else
|
|
glDisable(GL_DEPTH_TEST);
|
|
}
|
|
|
|
static __forceinline void GL_ALPHATEST(bool enable)
|
|
{
|
|
if (enable)
|
|
glEnable(GL_ALPHA_TEST);
|
|
else
|
|
glDisable(GL_ALPHA_TEST);
|
|
}
|
|
|
|
static __forceinline void GL_BLENDEQ_RGB(GLenum eq)
|
|
{
|
|
s_rgbeq = eq;
|
|
zgsBlendEquationSeparateEXT(s_rgbeq, s_alphaeq);
|
|
}
|
|
|
|
static __forceinline void GL_BLENDEQ_ALPHA(GLenum eq)
|
|
{
|
|
s_alphaeq = eq;
|
|
zgsBlendEquationSeparateEXT(s_rgbeq, s_alphaeq);
|
|
}
|
|
|
|
#endif // ZZGL_H_INCLUDED
|