OpenGL Renderer:
- Major rewrite of the OpenGL rendering code! Most important changes listed below. - Encapsulate 3D rendering code in C++ classes. - Add support for 3.2 Core Profile contexts, while preserving backwards compatibility with legacy contexts. - Initialize the renderer to choose the best OpenGL entry points available from the driver, automatically falling back to legacy entry points as needed. - Remove multithreading code. New and previous optimizations have obsoleted the need for it, so remove it to reduce code complexity. - Obsolete shaders.h and add the shader code directly into the .cpp files. Ports can safely remove the shaders.h file from their project/make files.
This commit is contained in:
parent
d310766240
commit
5b215efacc
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2007 shash
|
||||
Copyright (C) 2008-2009 DeSmuME team
|
||||
Copyright (C) 2008-2013 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -20,20 +20,339 @@
|
|||
#ifndef OGLRENDER_H
|
||||
#define OGLRENDER_H
|
||||
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include "render3D.h"
|
||||
#include "types.h"
|
||||
|
||||
// Define minimum required OpenGL version for GPU (Legacy Renderer)
|
||||
#define OGLRENDER_LEGACY_MINIMUM_GPU_VERSION_REQUIRED_MAJOR 1
|
||||
#define OGLRENDER_LEGACY_MINIMUM_GPU_VERSION_REQUIRED_MINOR 2
|
||||
#define OGLRENDER_LEGACY_MINIMUM_GPU_VERSION_REQUIRED_REVISION 0
|
||||
#ifndef OGLRENDER_3_2_H
|
||||
|
||||
// Define minimum required OpenGL version for GPU (Modern Renderer)
|
||||
#define OGLRENDER_MINIMUM_GPU_VERSION_REQUIRED_MAJOR 3
|
||||
#define OGLRENDER_MINIMUM_GPU_VERSION_REQUIRED_MINOR 0
|
||||
#define OGLRENDER_MINIMUM_GPU_VERSION_REQUIRED_REVISION 0
|
||||
#if defined(_WIN32) && !defined(WXPORT)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
|
||||
#define OGLEXT(procPtr, func) procPtr func = NULL;
|
||||
#define INITOGLEXT(procPtr, func) func = (procPtr)wglGetProcAddress(#func);
|
||||
#define EXTERNOGLEXT(procPtr, func) extern procPtr func;
|
||||
#elif defined(__APPLE__)
|
||||
#include <OpenGL/gl.h>
|
||||
#include <OpenGL/glext.h>
|
||||
|
||||
// Ignore dynamic linking on Apple OS
|
||||
#define OGLEXT(procPtr, func)
|
||||
#define INITOGLEXT(procPtr, func)
|
||||
#define EXTERNOGLEXT(procPtr, func)
|
||||
|
||||
// We're not exactly committing to OpenGL 3.2 Core Profile just yet, so redefine APPLE
|
||||
// extensions as a temporary measure.
|
||||
#if defined(GL_APPLE_vertex_array_object) && !defined(GL_ARB_vertex_array_object)
|
||||
#define glGenVertexArrays(n, ids) glGenVertexArraysAPPLE(n, ids)
|
||||
#define glBindVertexArray(id) glBindVertexArrayAPPLE(id)
|
||||
#define glDeleteVertexArrays(n, ids) glDeleteVertexArraysAPPLE(n, ids)
|
||||
#endif
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
#include <GL/glx.h>
|
||||
|
||||
/* This is a workaround needed to compile against nvidia GL headers */
|
||||
#ifndef GL_ALPHA_BLEND_EQUATION_ATI
|
||||
#undef GL_VERSION_1_3
|
||||
#endif
|
||||
|
||||
#define OGLEXT(procPtr, func) procPtr func = NULL;
|
||||
#define INITOGLEXT(procPtr, func) func = (procPtr)glXGetProcAddress((const GLubyte *) #func);
|
||||
#define EXTERNOGLEXT(procPtr, func) extern procPtr func;
|
||||
#endif
|
||||
|
||||
// Check minimum OpenGL header version
|
||||
#if !defined(GL_VERSION_2_1)
|
||||
#if defined(GL_VERSION_2_0)
|
||||
#warning Using OpenGL v2.0 headers with v2.1 overrides. Some features will be disabled.
|
||||
|
||||
#if !defined(GL_ARB_framebuffer_object)
|
||||
// Overrides for GL_EXT_framebuffer_blit
|
||||
#if !defined(GL_EXT_framebuffer_blit)
|
||||
#define GL_READ_FRAMEBUFFER_EXT GL_FRAMEBUFFER_EXT
|
||||
#define GL_DRAW_FRAMEBUFFER_EXT GL_FRAMEBUFFER_EXT
|
||||
#define glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter)
|
||||
#endif
|
||||
|
||||
// Overrides for GL_EXT_framebuffer_multisample
|
||||
#if !defined(GL_EXT_framebuffer_multisample)
|
||||
#define GL_MAX_SAMPLES_EXT 0
|
||||
#define glRenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height)
|
||||
#endif
|
||||
|
||||
// Overrides for GL_ARB_pixel_buffer_object
|
||||
#if !defined(GL_PIXEL_PACK_BUFFER) && defined(GL_PIXEL_PACK_BUFFER_ARB)
|
||||
#define GL_PIXEL_PACK_BUFFER GL_PIXEL_PACK_BUFFER_ARB
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#error OpenGL requires v2.1 headers or later.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Textures
|
||||
#if !defined(GLX_H)
|
||||
EXTERNOGLEXT(PFNGLACTIVETEXTUREPROC, glActiveTexture) // Core in v1.3
|
||||
EXTERNOGLEXT(PFNGLACTIVETEXTUREARBPROC, glActiveTextureARB)
|
||||
#endif
|
||||
|
||||
// Blending
|
||||
EXTERNOGLEXT(PFNGLBLENDFUNCSEPARATEPROC, glBlendFuncSeparate) // Core in v1.4
|
||||
EXTERNOGLEXT(PFNGLBLENDEQUATIONSEPARATEPROC, glBlendEquationSeparate) // Core in v2.0
|
||||
|
||||
EXTERNOGLEXT(PFNGLBLENDFUNCSEPARATEEXTPROC, glBlendFuncSeparateEXT)
|
||||
EXTERNOGLEXT(PFNGLBLENDEQUATIONSEPARATEEXTPROC, glBlendEquationSeparateEXT)
|
||||
|
||||
// Shaders
|
||||
EXTERNOGLEXT(PFNGLCREATESHADERPROC, glCreateShader) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLSHADERSOURCEPROC, glShaderSource) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLCOMPILESHADERPROC, glCompileShader) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLCREATEPROGRAMPROC, glCreateProgram) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLATTACHSHADERPROC, glAttachShader) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLDETACHSHADERPROC, glDetachShader) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLLINKPROGRAMPROC, glLinkProgram) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUSEPROGRAMPROC, glUseProgram) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLGETSHADERIVPROC, glGetShaderiv) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLGETSHADERINFOLOGPROC, glGetShaderInfoLog) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLDELETESHADERPROC, glDeleteShader) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLDELETEPROGRAMPROC, glDeleteProgram) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLGETPROGRAMIVPROC, glGetProgramiv) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLGETPROGRAMINFOLOGPROC, glGetProgramInfoLog) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLVALIDATEPROGRAMPROC, glValidateProgram) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLGETUNIFORMLOCATIONPROC, glGetUniformLocation) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUNIFORM1IPROC, glUniform1i) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUNIFORM1IVPROC, glUniform1iv) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUNIFORM1FPROC, glUniform1f) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUNIFORM2FPROC, glUniform2f) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLDRAWBUFFERSPROC, glDrawBuffers) // Core in v2.0
|
||||
|
||||
// Generic vertex attributes
|
||||
EXTERNOGLEXT(PFNGLBINDATTRIBLOCATIONPROC, glBindAttribLocation) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLDISABLEVERTEXATTRIBARRAYPROC, glDisableVertexAttribArray) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer) // Core in v2.0
|
||||
|
||||
// VAO
|
||||
EXTERNOGLEXT(PFNGLGENVERTEXARRAYSPROC, glGenVertexArrays)
|
||||
EXTERNOGLEXT(PFNGLDELETEVERTEXARRAYSPROC, glDeleteVertexArrays)
|
||||
EXTERNOGLEXT(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray)
|
||||
|
||||
// VBO and PBO
|
||||
EXTERNOGLEXT(PFNGLGENBUFFERSARBPROC, glGenBuffersARB)
|
||||
EXTERNOGLEXT(PFNGLDELETEBUFFERSARBPROC, glDeleteBuffersARB)
|
||||
EXTERNOGLEXT(PFNGLBINDBUFFERARBPROC, glBindBufferARB)
|
||||
EXTERNOGLEXT(PFNGLBUFFERDATAARBPROC, glBufferDataARB)
|
||||
EXTERNOGLEXT(PFNGLBUFFERSUBDATAARBPROC, glBufferSubDataARB)
|
||||
EXTERNOGLEXT(PFNGLMAPBUFFERARBPROC, glMapBufferARB)
|
||||
EXTERNOGLEXT(PFNGLUNMAPBUFFERARBPROC, glUnmapBufferARB)
|
||||
|
||||
EXTERNOGLEXT(PFNGLGENBUFFERSPROC, glGenBuffers) // Core in v1.5
|
||||
EXTERNOGLEXT(PFNGLDELETEBUFFERSPROC, glDeleteBuffers) // Core in v1.5
|
||||
EXTERNOGLEXT(PFNGLBINDBUFFERPROC, glBindBuffer) // Core in v1.5
|
||||
EXTERNOGLEXT(PFNGLBUFFERDATAPROC, glBufferData) // Core in v1.5
|
||||
EXTERNOGLEXT(PFNGLBUFFERSUBDATAPROC, glBufferSubData) // Core in v1.5
|
||||
EXTERNOGLEXT(PFNGLMAPBUFFERPROC, glMapBuffer) // Core in v1.5
|
||||
EXTERNOGLEXT(PFNGLUNMAPBUFFERPROC, glUnmapBuffer) // Core in v1.5
|
||||
|
||||
// FBO
|
||||
EXTERNOGLEXT(PFNGLGENFRAMEBUFFERSEXTPROC, glGenFramebuffersEXT)
|
||||
EXTERNOGLEXT(PFNGLBINDFRAMEBUFFEREXTPROC, glBindFramebufferEXT)
|
||||
EXTERNOGLEXT(PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC, glFramebufferRenderbufferEXT)
|
||||
EXTERNOGLEXT(PFNGLFRAMEBUFFERTEXTURE2DEXTPROC, glFramebufferTexture2DEXT)
|
||||
EXTERNOGLEXT(PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC, glCheckFramebufferStatusEXT)
|
||||
EXTERNOGLEXT(PFNGLDELETEFRAMEBUFFERSEXTPROC, glDeleteFramebuffersEXT)
|
||||
EXTERNOGLEXT(PFNGLBLITFRAMEBUFFEREXTPROC, glBlitFramebufferEXT)
|
||||
|
||||
// Multisampled FBO
|
||||
EXTERNOGLEXT(PFNGLGENRENDERBUFFERSEXTPROC, glGenRenderbuffersEXT)
|
||||
EXTERNOGLEXT(PFNGLBINDRENDERBUFFEREXTPROC, glBindRenderbufferEXT)
|
||||
EXTERNOGLEXT(PFNGLRENDERBUFFERSTORAGEEXTPROC, glRenderbufferStorageEXT)
|
||||
EXTERNOGLEXT(PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC, glRenderbufferStorageMultisampleEXT)
|
||||
EXTERNOGLEXT(PFNGLDELETERENDERBUFFERSEXTPROC, glDeleteRenderbuffersEXT)
|
||||
|
||||
#else // OGLRENDER_3_2_H
|
||||
|
||||
// Basic Functions
|
||||
EXTERNOGLEXT(PFNGLGETSTRINGIPROC, glGetStringi) // Core in v3.0
|
||||
|
||||
// Textures
|
||||
#if !defined(GLX_H)
|
||||
EXTERNOGLEXT(PFNGLACTIVETEXTUREPROC, glActiveTexture) // Core in v1.3
|
||||
#endif
|
||||
|
||||
// Blending
|
||||
EXTERNOGLEXT(PFNGLBLENDFUNCSEPARATEPROC, glBlendFuncSeparate) // Core in v1.4
|
||||
EXTERNOGLEXT(PFNGLBLENDEQUATIONSEPARATEPROC, glBlendEquationSeparate) // Core in v2.0
|
||||
|
||||
// Shaders
|
||||
EXTERNOGLEXT(PFNGLCREATESHADERPROC, glCreateShader) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLSHADERSOURCEPROC, glShaderSource) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLCOMPILESHADERPROC, glCompileShader) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLCREATEPROGRAMPROC, glCreateProgram) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLATTACHSHADERPROC, glAttachShader) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLDETACHSHADERPROC, glDetachShader) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLLINKPROGRAMPROC, glLinkProgram) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUSEPROGRAMPROC, glUseProgram) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLGETSHADERIVPROC, glGetShaderiv) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLGETSHADERINFOLOGPROC, glGetShaderInfoLog) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLDELETESHADERPROC, glDeleteShader) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLDELETEPROGRAMPROC, glDeleteProgram) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLGETPROGRAMIVPROC, glGetProgramiv) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLGETPROGRAMINFOLOGPROC, glGetProgramInfoLog) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLVALIDATEPROGRAMPROC, glValidateProgram) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLGETUNIFORMLOCATIONPROC, glGetUniformLocation) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUNIFORM1IPROC, glUniform1i) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUNIFORM1IVPROC, glUniform1iv) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUNIFORM1FPROC, glUniform1f) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLUNIFORM2FPROC, glUniform2f) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLDRAWBUFFERSPROC, glDrawBuffers) // Core in v2.0
|
||||
|
||||
// Generic vertex attributes
|
||||
EXTERNOGLEXT(PFNGLBINDATTRIBLOCATIONPROC, glBindAttribLocation) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLBINDFRAGDATALOCATIONPROC, glBindFragDataLocation) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLDISABLEVERTEXATTRIBARRAYPROC, glDisableVertexAttribArray) // Core in v2.0
|
||||
EXTERNOGLEXT(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer) // Core in v2.0
|
||||
|
||||
// VAO
|
||||
EXTERNOGLEXT(PFNGLGENVERTEXARRAYSPROC, glGenVertexArrays) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLDELETEVERTEXARRAYSPROC, glDeleteVertexArrays) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray) // Core in v3.0
|
||||
|
||||
// VBO and PBO
|
||||
EXTERNOGLEXT(PFNGLGENBUFFERSPROC, glGenBuffers) // Core in v1.5
|
||||
EXTERNOGLEXT(PFNGLDELETEBUFFERSPROC, glDeleteBuffers) // Core in v1.5
|
||||
EXTERNOGLEXT(PFNGLBINDBUFFERPROC, glBindBuffer) // Core in v1.5
|
||||
EXTERNOGLEXT(PFNGLBUFFERDATAPROC, glBufferData) // Core in v1.5
|
||||
EXTERNOGLEXT(PFNGLBUFFERSUBDATAPROC, glBufferSubData) // Core in v1.5
|
||||
EXTERNOGLEXT(PFNGLMAPBUFFERPROC, glMapBuffer) // Core in v1.5
|
||||
EXTERNOGLEXT(PFNGLUNMAPBUFFERPROC, glUnmapBuffer) // Core in v1.5
|
||||
|
||||
// FBO
|
||||
EXTERNOGLEXT(PFNGLGENFRAMEBUFFERSPROC, glGenFramebuffers) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLFRAMEBUFFERTEXTURE2DPROC, glFramebufferTexture2D) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLCHECKFRAMEBUFFERSTATUSPROC, glCheckFramebufferStatus) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLDELETEFRAMEBUFFERSPROC, glDeleteFramebuffers) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLBLITFRAMEBUFFERPROC, glBlitFramebuffer) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLDRAWBUFFERSPROC, glDrawBuffers) // Core in v2.0
|
||||
|
||||
// Multisampled FBO
|
||||
EXTERNOGLEXT(PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC, glRenderbufferStorageMultisample) // Core in v3.0
|
||||
EXTERNOGLEXT(PFNGLDELETERENDERBUFFERSPROC, glDeleteRenderbuffers) // Core in v3.0
|
||||
|
||||
#endif // OGLRENDER_3_2_H
|
||||
|
||||
// Define the minimum required OpenGL version for the driver to support
|
||||
#define OGLRENDER_MINIMUM_DRIVER_VERSION_REQUIRED_MAJOR 1
|
||||
#define OGLRENDER_MINIMUM_DRIVER_VERSION_REQUIRED_MINOR 2
|
||||
#define OGLRENDER_MINIMUM_DRIVER_VERSION_REQUIRED_REVISION 0
|
||||
|
||||
#define OGLRENDER_MAX_MULTISAMPLES 16
|
||||
#define OGLRENDER_VERT_INDEX_BUFFER_SIZE 8192
|
||||
#define OGLRENDER_VERT_INDEX_BUFFER_COUNT 131072
|
||||
|
||||
enum OGLVertexAttributeID
|
||||
{
|
||||
OGLVertexAttributeID_Position = 0,
|
||||
OGLVertexAttributeID_TexCoord0 = 8,
|
||||
OGLVertexAttributeID_Color = 3,
|
||||
};
|
||||
|
||||
enum OGLTextureUnitID
|
||||
{
|
||||
// Main textures will always be on texture unit 0.
|
||||
OGLTextureUnitID_ToonTable = 1,
|
||||
OGLTextureUnitID_ClearImage
|
||||
};
|
||||
|
||||
enum OGLErrorCode
|
||||
{
|
||||
OGLERROR_NOERR = RENDER3DERROR_NOERR,
|
||||
OGLERROR_FEATURE_UNSUPPORTED,
|
||||
OGLERROR_VBO_UNSUPPORTED,
|
||||
OGLERROR_PBO_UNSUPPORTED,
|
||||
OGLERROR_SHADER_UNSUPPORTED,
|
||||
OGLERROR_VAO_UNSUPPORTED,
|
||||
OGLERROR_FBO_UNSUPPORTED,
|
||||
OGLERROR_MULTISAMPLED_FBO_UNSUPPORTED,
|
||||
|
||||
OGLERROR_SHADER_CREATE_ERROR,
|
||||
OGLERROR_FBO_CREATE_ERROR
|
||||
};
|
||||
|
||||
struct OGLRenderRef
|
||||
{
|
||||
// OpenGL Feature Support
|
||||
GLint stateTexMirroredRepeat;
|
||||
|
||||
// VBO
|
||||
GLuint vboVertexID;
|
||||
GLuint iboIndexID;
|
||||
|
||||
// PBO
|
||||
GLuint pboRenderDataID[2];
|
||||
|
||||
// FBO
|
||||
GLuint texClearImageColorID;
|
||||
GLuint texClearImageDepthStencilID;
|
||||
GLuint fboClearImageID;
|
||||
|
||||
GLuint rboFinalOutputColorID;
|
||||
GLuint rboFinalOutputDepthStencilID;
|
||||
GLuint fboFinalOutputID;
|
||||
|
||||
// Multisampled FBO
|
||||
GLuint rboMultisampleColorID;
|
||||
GLuint rboMultisampleDepthStencilID;
|
||||
GLuint fboMultisampleRenderID;
|
||||
GLuint selectedRenderingFBO;
|
||||
|
||||
// Shader states
|
||||
GLuint vertexShaderID;
|
||||
GLuint fragmentShaderID;
|
||||
GLuint shaderProgram;
|
||||
|
||||
GLint uniformPolyID;
|
||||
GLint uniformPolyAlpha;
|
||||
GLint uniformTexScale;
|
||||
GLint uniformHasTexture;
|
||||
GLint uniformPolygonMode;
|
||||
GLint uniformToonShadingMode;
|
||||
GLint uniformWBuffer;
|
||||
GLint uniformEnableAlphaTest;
|
||||
GLint uniformAlphaTestRef;
|
||||
|
||||
GLuint texToonTableID;
|
||||
|
||||
// VAO
|
||||
GLuint vaoMainStatesID;
|
||||
|
||||
// Textures
|
||||
std::queue<GLuint> freeTextureIDs;
|
||||
|
||||
// Client-side Buffers
|
||||
GLfloat *color4fBuffer;
|
||||
DS_ALIGN(16) GLushort vertIndexBuffer[OGLRENDER_VERT_INDEX_BUFFER_COUNT];
|
||||
};
|
||||
|
||||
struct GFX3D_State;
|
||||
struct VERTLIST;
|
||||
struct POLYLIST;
|
||||
struct INDEXLIST;
|
||||
struct POLY;
|
||||
class TexCacheItem;
|
||||
class OpenGLRenderer;
|
||||
|
||||
extern GPU3DInterface gpu3Dgl;
|
||||
|
||||
|
@ -49,4 +368,240 @@ extern bool (*oglrender_beginOpenGL)();
|
|||
//This is called by OGLRender after it is done using opengl.
|
||||
extern void (*oglrender_endOpenGL)();
|
||||
|
||||
// These functions need to be assigned by ports that support using an
|
||||
// OpenGL 3.2 Core Profile context. The OGLRender_3_2.cpp file includes
|
||||
// the corresponding functions to assign to each function pointer.
|
||||
//
|
||||
// If any of these functions are unassigned, then one of the legacy OpenGL
|
||||
// renderers will be used instead.
|
||||
extern void (*OGLLoadEntryPoints_3_2_Func)();
|
||||
extern void (*OGLCreateRenderer_3_2_Func)(OpenGLRenderer **rendererPtr);
|
||||
|
||||
// Lookup Tables
|
||||
extern CACHE_ALIGN GLfloat material_8bit_to_float[256];
|
||||
extern CACHE_ALIGN GLuint dsDepthToD24S8_LUT[32768];
|
||||
extern const GLfloat divide5bitBy31_LUT[32];
|
||||
|
||||
FORCEINLINE u32 BGRA8888_32_To_RGBA6665_32Rev(const u32 srcPix);
|
||||
FORCEINLINE u32 BGRA8888_32Rev_To_RGBA6665_32Rev(const u32 srcPix);
|
||||
bool IsVersionSupported(unsigned int checkVersionMajor, unsigned int checkVersionMinor, unsigned int checkVersionRevision);
|
||||
|
||||
class OpenGLRenderer : public Render3D
|
||||
{
|
||||
private:
|
||||
// Driver's OpenGL Version
|
||||
unsigned int versionMajor;
|
||||
unsigned int versionMinor;
|
||||
unsigned int versionRevision;
|
||||
|
||||
protected:
|
||||
// OpenGL-specific References
|
||||
OGLRenderRef *ref;
|
||||
|
||||
// OpenGL Feature Support
|
||||
bool isVBOSupported;
|
||||
bool isPBOSupported;
|
||||
bool isFBOSupported;
|
||||
bool isMultisampledFBOSupported;
|
||||
bool isShaderSupported;
|
||||
bool isVAOSupported;
|
||||
|
||||
// Textures
|
||||
TexCacheItem *currTexture;
|
||||
|
||||
u16 currentToonTable16[32];
|
||||
bool toonTableNeedsUpdate;
|
||||
|
||||
DS_ALIGN(16) u32 GPU_screen3D[2][256 * 192 * sizeof(u32)];
|
||||
bool gpuScreen3DHasNewData[2];
|
||||
unsigned int doubleBufferIndex;
|
||||
u8 clearImageStencilValue;
|
||||
|
||||
// OpenGL-specific methods
|
||||
virtual Render3DError CreateVBOs() = 0;
|
||||
virtual void DestroyVBOs() = 0;
|
||||
virtual Render3DError CreatePBOs() = 0;
|
||||
virtual void DestroyPBOs() = 0;
|
||||
virtual Render3DError CreateFBOs() = 0;
|
||||
virtual void DestroyFBOs() = 0;
|
||||
virtual Render3DError CreateMultisampledFBO() = 0;
|
||||
virtual void DestroyMultisampledFBO() = 0;
|
||||
virtual Render3DError CreateShaders(const std::string *vertexShaderProgram, const std::string *fragmentShaderProgram) = 0;
|
||||
virtual void DestroyShaders() = 0;
|
||||
virtual Render3DError CreateVAOs() = 0;
|
||||
virtual void DestroyVAOs() = 0;
|
||||
virtual Render3DError InitTextures() = 0;
|
||||
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet) = 0;
|
||||
virtual Render3DError InitTables() = 0;
|
||||
|
||||
virtual Render3DError SetupShaderIO() = 0;
|
||||
virtual Render3DError CreateToonTable() = 0;
|
||||
virtual Render3DError DestroyToonTable() = 0;
|
||||
virtual Render3DError UploadToonTable(const GLushort *toonTableBuffer) = 0;
|
||||
virtual Render3DError CreateClearImage() = 0;
|
||||
virtual Render3DError DestroyClearImage() = 0;
|
||||
virtual Render3DError UploadClearImage(const GLushort *clearImageColorBuffer, const GLint *clearImageDepthBuffer) = 0;
|
||||
|
||||
virtual void GetExtensionSet(std::set<std::string> *oglExtensionSet) = 0;
|
||||
virtual Render3DError ExpandFreeTextures() = 0;
|
||||
virtual Render3DError DownsampleFBO() = 0;
|
||||
virtual Render3DError ReadBackPixels() = 0;
|
||||
|
||||
// Base rendering methods
|
||||
virtual Render3DError BeginRender(const GFX3D_State *renderState) = 0;
|
||||
virtual Render3DError PreRender(const GFX3D_State *renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList) = 0;
|
||||
virtual Render3DError DoRender(const GFX3D_State *renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList) = 0;
|
||||
virtual Render3DError PostRender() = 0;
|
||||
virtual Render3DError EndRender(const u64 frameCount) = 0;
|
||||
|
||||
virtual Render3DError UpdateClearImage(const u16 *__restrict colorBuffer, const u16 *__restrict depthBuffer, const u8 clearStencil, const u8 xScroll, const u8 yScroll) = 0;
|
||||
virtual Render3DError UpdateToonTable(const u16 *toonTableBuffer) = 0;
|
||||
|
||||
virtual Render3DError ClearUsingImage() const = 0;
|
||||
virtual Render3DError ClearUsingValues(const u8 r, const u8 g, const u8 b, const u8 a, const u32 clearDepth, const u8 clearStencil) const = 0;
|
||||
|
||||
virtual Render3DError SetupPolygon(const POLY *thePoly) = 0;
|
||||
virtual Render3DError SetupTexture(const POLY *thePoly, bool enableTexturing) = 0;
|
||||
virtual Render3DError SetupViewport(const POLY *thePoly) = 0;
|
||||
|
||||
public:
|
||||
OpenGLRenderer();
|
||||
virtual ~OpenGLRenderer() {};
|
||||
|
||||
virtual Render3DError InitExtensions() = 0;
|
||||
virtual Render3DError Reset() = 0;
|
||||
virtual Render3DError RenderFinish() = 0;
|
||||
|
||||
virtual Render3DError DeleteTexture(const TexCacheItem *item) = 0;
|
||||
|
||||
bool IsExtensionPresent(const std::set<std::string> *oglExtensionSet, const std::string extensionName) const;
|
||||
bool ValidateShaderCompile(GLuint theShader) const;
|
||||
bool ValidateShaderProgramLink(GLuint theProgram) const;
|
||||
void GetVersion(unsigned int *major, unsigned int *minor, unsigned int *revision) const;
|
||||
void SetVersion(unsigned int major, unsigned int minor, unsigned int revision);
|
||||
void ConvertFramebuffer(const u32 *__restrict srcBuffer, u32 *dstBuffer);
|
||||
};
|
||||
|
||||
class OpenGLRenderer_1_2 : public OpenGLRenderer
|
||||
{
|
||||
protected:
|
||||
// OpenGL-specific methods
|
||||
virtual Render3DError CreateVBOs();
|
||||
virtual void DestroyVBOs();
|
||||
virtual Render3DError CreatePBOs();
|
||||
virtual void DestroyPBOs();
|
||||
virtual Render3DError CreateFBOs();
|
||||
virtual void DestroyFBOs();
|
||||
virtual Render3DError CreateMultisampledFBO();
|
||||
virtual void DestroyMultisampledFBO();
|
||||
virtual Render3DError CreateShaders(const std::string *vertexShaderProgram, const std::string *fragmentShaderProgram);
|
||||
virtual void DestroyShaders();
|
||||
virtual Render3DError CreateVAOs();
|
||||
virtual void DestroyVAOs();
|
||||
virtual Render3DError InitTextures();
|
||||
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet);
|
||||
virtual Render3DError InitTables();
|
||||
|
||||
virtual Render3DError SetupShaderIO();
|
||||
virtual Render3DError CreateToonTable();
|
||||
virtual Render3DError DestroyToonTable();
|
||||
virtual Render3DError UploadToonTable(const GLushort *toonTableBuffer);
|
||||
virtual Render3DError CreateClearImage();
|
||||
virtual Render3DError DestroyClearImage();
|
||||
virtual Render3DError UploadClearImage(const GLushort *clearImageColorBuffer, const GLint *clearImageDepthBuffer);
|
||||
|
||||
virtual void GetExtensionSet(std::set<std::string> *oglExtensionSet);
|
||||
virtual Render3DError ExpandFreeTextures();
|
||||
virtual Render3DError DownsampleFBO();
|
||||
virtual Render3DError ReadBackPixels();
|
||||
|
||||
// Base rendering methods
|
||||
virtual Render3DError BeginRender(const GFX3D_State *renderState);
|
||||
virtual Render3DError PreRender(const GFX3D_State *renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList);
|
||||
virtual Render3DError DoRender(const GFX3D_State *renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList);
|
||||
virtual Render3DError PostRender();
|
||||
virtual Render3DError EndRender(const u64 frameCount);
|
||||
|
||||
virtual Render3DError UpdateClearImage(const u16 *__restrict colorBuffer, const u16 *__restrict depthBuffer, const u8 clearStencil, const u8 xScroll, const u8 yScroll);
|
||||
virtual Render3DError UpdateToonTable(const u16 *toonTableBuffer);
|
||||
|
||||
virtual Render3DError ClearUsingImage() const;
|
||||
virtual Render3DError ClearUsingValues(const u8 r, const u8 g, const u8 b, const u8 a, const u32 clearDepth, const u8 clearStencil) const;
|
||||
|
||||
virtual Render3DError SetupPolygon(const POLY *thePoly);
|
||||
virtual Render3DError SetupTexture(const POLY *thePoly, bool enableTexturing);
|
||||
virtual Render3DError SetupViewport(const POLY *thePoly);
|
||||
|
||||
public:
|
||||
OpenGLRenderer_1_2();
|
||||
~OpenGLRenderer_1_2();
|
||||
|
||||
virtual Render3DError InitExtensions();
|
||||
virtual Render3DError Reset();
|
||||
virtual Render3DError RenderFinish();
|
||||
|
||||
virtual Render3DError DeleteTexture(const TexCacheItem *item);
|
||||
};
|
||||
|
||||
class OpenGLRenderer_1_3 : public OpenGLRenderer_1_2
|
||||
{
|
||||
protected:
|
||||
virtual Render3DError CreateToonTable();
|
||||
virtual Render3DError DestroyToonTable();
|
||||
virtual Render3DError UploadToonTable(const GLushort *toonTableBuffer);
|
||||
virtual Render3DError CreateClearImage();
|
||||
virtual Render3DError DestroyClearImage();
|
||||
virtual Render3DError UploadClearImage(const GLushort *clearImageColorBuffer, const GLint *clearImageDepthBuffer);
|
||||
};
|
||||
|
||||
class OpenGLRenderer_1_4 : public OpenGLRenderer_1_3
|
||||
{
|
||||
protected:
|
||||
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet);
|
||||
};
|
||||
|
||||
class OpenGLRenderer_1_5 : public OpenGLRenderer_1_4
|
||||
{
|
||||
protected:
|
||||
virtual Render3DError CreateVBOs();
|
||||
virtual void DestroyVBOs();
|
||||
virtual Render3DError CreatePBOs();
|
||||
virtual void DestroyPBOs();
|
||||
virtual Render3DError CreateVAOs();
|
||||
|
||||
virtual Render3DError ReadBackPixels();
|
||||
|
||||
virtual Render3DError PreRender(const GFX3D_State *renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList);
|
||||
virtual Render3DError PostRender();
|
||||
|
||||
public:
|
||||
~OpenGLRenderer_1_5();
|
||||
|
||||
virtual Render3DError RenderFinish();
|
||||
};
|
||||
|
||||
class OpenGLRenderer_2_0 : public OpenGLRenderer_1_5
|
||||
{
|
||||
protected:
|
||||
virtual Render3DError InitExtensions();
|
||||
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet);
|
||||
|
||||
virtual Render3DError BeginRender(const GFX3D_State *renderState);
|
||||
virtual Render3DError PreRender(const GFX3D_State *renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList);
|
||||
virtual Render3DError DoRender(const GFX3D_State *renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList);
|
||||
virtual Render3DError PostRender();
|
||||
|
||||
virtual Render3DError SetupPolygon(const POLY *thePoly);
|
||||
virtual Render3DError SetupTexture(const POLY *thePoly, bool enableTexturing);
|
||||
};
|
||||
|
||||
class OpenGLRenderer_2_1 : public OpenGLRenderer_2_0
|
||||
{
|
||||
protected:
|
||||
virtual Render3DError ReadBackPixels();
|
||||
|
||||
public:
|
||||
virtual Render3DError RenderFinish();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,626 @@
|
|||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2007 shash
|
||||
Copyright (C) 2008-2013 DeSmuME team
|
||||
|
||||
This file 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 file 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 the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "OGLRender_3_2.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "gfx3d.h"
|
||||
#include "NDSSystem.h"
|
||||
#include "texcache.h"
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
// Basic Functions
|
||||
OGLEXT(PFNGLGETSTRINGIPROC, glGetStringi) // Core in v3.0
|
||||
|
||||
// Shaders
|
||||
OGLEXT(PFNGLBINDFRAGDATALOCATIONPROC, glBindFragDataLocation) // Core in v3.0
|
||||
|
||||
// FBO
|
||||
OGLEXT(PFNGLGENFRAMEBUFFERSPROC, glGenFramebuffers) // Core in v3.0
|
||||
OGLEXT(PFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer) // Core in v3.0
|
||||
OGLEXT(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer) // Core in v3.0
|
||||
OGLEXT(PFNGLFRAMEBUFFERTEXTURE2DPROC, glFramebufferTexture2D) // Core in v3.0
|
||||
OGLEXT(PFNGLCHECKFRAMEBUFFERSTATUSPROC, glCheckFramebufferStatus) // Core in v3.0
|
||||
OGLEXT(PFNGLDELETEFRAMEBUFFERSPROC, glDeleteFramebuffers) // Core in v3.0
|
||||
OGLEXT(PFNGLBLITFRAMEBUFFERPROC, glBlitFramebuffer) // Core in v3.0
|
||||
OGLEXT(PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers) // Core in v3.0
|
||||
OGLEXT(PFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer) // Core in v3.0
|
||||
OGLEXT(PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage) // Core in v3.0
|
||||
OGLEXT(PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC, glRenderbufferStorageMultisample) // Core in v3.0
|
||||
OGLEXT(PFNGLDELETERENDERBUFFERSPROC, glDeleteRenderbuffers) // Core in v3.0
|
||||
|
||||
void OGLLoadEntryPoints_3_2()
|
||||
{
|
||||
// Basic Functions
|
||||
INITOGLEXT(PFNGLGETSTRINGIPROC, glGetStringi)
|
||||
|
||||
// Shaders
|
||||
INITOGLEXT(PFNGLBINDFRAGDATALOCATIONPROC, glBindFragDataLocation)
|
||||
|
||||
// FBO
|
||||
INITOGLEXT(PFNGLGENFRAMEBUFFERSPROC, glGenFramebuffers) // Promote to core version
|
||||
INITOGLEXT(PFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer) // Promote to core version
|
||||
INITOGLEXT(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer) // Promote to core version
|
||||
INITOGLEXT(PFNGLFRAMEBUFFERTEXTURE2DPROC, glFramebufferTexture2D) // Promote to core version
|
||||
INITOGLEXT(PFNGLCHECKFRAMEBUFFERSTATUSPROC, glCheckFramebufferStatus) // Promote to core version
|
||||
INITOGLEXT(PFNGLDELETEFRAMEBUFFERSPROC, glDeleteFramebuffers) // Promote to core version
|
||||
INITOGLEXT(PFNGLBLITFRAMEBUFFERPROC, glBlitFramebuffer) // Promote to core version
|
||||
INITOGLEXT(PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers) // Promote to core version
|
||||
INITOGLEXT(PFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer) // Promote to core version
|
||||
INITOGLEXT(PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage) // Promote to core version
|
||||
INITOGLEXT(PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC, glRenderbufferStorageMultisample) // Promote to core version
|
||||
INITOGLEXT(PFNGLDELETERENDERBUFFERSPROC, glDeleteRenderbuffers) // Promote to core version
|
||||
}
|
||||
|
||||
// Vertex Shader GLSL 1.50
|
||||
static const char *vertexShader_150 = {"\
|
||||
#version 150 \n\
|
||||
\n\
|
||||
in vec4 inPosition; \n\
|
||||
in vec2 inTexCoord0; \n\
|
||||
in vec3 inColor; \n\
|
||||
\n\
|
||||
uniform float polyAlpha; \n\
|
||||
uniform vec2 texScale; \n\
|
||||
\n\
|
||||
out vec4 vtxPosition; \n\
|
||||
out vec2 vtxTexCoord; \n\
|
||||
out vec4 vtxColor; \n\
|
||||
\n\
|
||||
void main() \n\
|
||||
{ \n\
|
||||
mat2 texScaleMtx = mat2( vec2(texScale.x, 0.0), \n\
|
||||
vec2( 0.0, texScale.y)); \n\
|
||||
\n\
|
||||
vtxPosition = inPosition; \n\
|
||||
vtxTexCoord = texScaleMtx * inTexCoord0; \n\
|
||||
vtxColor = vec4(inColor * 4.0, polyAlpha); \n\
|
||||
\n\
|
||||
gl_Position = vtxPosition; \n\
|
||||
} \n\
|
||||
"};
|
||||
|
||||
// Fragment Shader GLSL 1.50
|
||||
static const char *fragmentShader_150 = {"\
|
||||
#version 150 \n\
|
||||
\n\
|
||||
in vec4 vtxPosition; \n\
|
||||
in vec2 vtxTexCoord; \n\
|
||||
in vec4 vtxColor; \n\
|
||||
\n\
|
||||
uniform sampler2D texMainRender; \n\
|
||||
uniform sampler1D texToonTable; \n\
|
||||
uniform int polyID; \n\
|
||||
uniform bool hasTexture; \n\
|
||||
uniform int polygonMode; \n\
|
||||
uniform int toonShadingMode; \n\
|
||||
uniform int oglWBuffer; \n\
|
||||
uniform bool enableAlphaTest; \n\
|
||||
uniform float alphaTestRef; \n\
|
||||
\n\
|
||||
out vec4 outFragColor; \n\
|
||||
\n\
|
||||
void main() \n\
|
||||
{ \n\
|
||||
vec4 texColor = vec4(1.0, 1.0, 1.0, 1.0); \n\
|
||||
vec4 flagColor; \n\
|
||||
float flagDepth; \n\
|
||||
\n\
|
||||
if(hasTexture) \n\
|
||||
{ \n\
|
||||
texColor = texture(texMainRender, vtxTexCoord); \n\
|
||||
} \n\
|
||||
\n\
|
||||
flagColor = texColor; \n\
|
||||
\n\
|
||||
if(polygonMode == 0) \n\
|
||||
{ \n\
|
||||
flagColor = vtxColor * texColor; \n\
|
||||
} \n\
|
||||
else if(polygonMode == 1) \n\
|
||||
{ \n\
|
||||
if (texColor.a == 0.0 || !hasTexture) \n\
|
||||
{ \n\
|
||||
flagColor.rgb = vtxColor.rgb; \n\
|
||||
} \n\
|
||||
else if (texColor.a == 1.0) \n\
|
||||
{ \n\
|
||||
flagColor.rgb = texColor.rgb; \n\
|
||||
} \n\
|
||||
else \n\
|
||||
{ \n\
|
||||
flagColor.rgb = texColor.rgb * (1.0-texColor.a) + vtxColor.rgb * texColor.a; \n\
|
||||
} \n\
|
||||
\n\
|
||||
flagColor.a = vtxColor.a; \n\
|
||||
} \n\
|
||||
else if(polygonMode == 2) \n\
|
||||
{ \n\
|
||||
vec3 toonColor = vec3(texture(texToonTable, vtxColor.r).rgb); \n\
|
||||
\n\
|
||||
if (toonShadingMode == 0) \n\
|
||||
{ \n\
|
||||
flagColor.rgb = texColor.rgb * toonColor.rgb; \n\
|
||||
} \n\
|
||||
else \n\
|
||||
{ \n\
|
||||
flagColor.rgb = texColor.rgb * vtxColor.rgb + toonColor.rgb; \n\
|
||||
} \n\
|
||||
\n\
|
||||
flagColor.a = texColor.a * vtxColor.a; \n\
|
||||
} \n\
|
||||
else if(polygonMode == 3) \n\
|
||||
{ \n\
|
||||
if (polyID != 0) \n\
|
||||
{ \n\
|
||||
flagColor = vtxColor; \n\
|
||||
} \n\
|
||||
} \n\
|
||||
\n\
|
||||
if (flagColor.a == 0.0 || (enableAlphaTest && flagColor.a < alphaTestRef)) \n\
|
||||
{ \n\
|
||||
discard; \n\
|
||||
} \n\
|
||||
\n\
|
||||
if (oglWBuffer == 1) \n\
|
||||
{ \n\
|
||||
// TODO \n\
|
||||
flagDepth = (vtxPosition.z / vtxPosition.w) * 0.5 + 0.5; \n\
|
||||
} \n\
|
||||
else \n\
|
||||
{ \n\
|
||||
flagDepth = (vtxPosition.z / vtxPosition.w) * 0.5 + 0.5; \n\
|
||||
} \n\
|
||||
\n\
|
||||
outFragColor = flagColor; \n\
|
||||
gl_FragDepth = flagDepth; \n\
|
||||
} \n\
|
||||
"};
|
||||
|
||||
void OGLCreateRenderer_3_2(OpenGLRenderer **rendererPtr)
|
||||
{
|
||||
if (IsVersionSupported(3, 2, 0))
|
||||
{
|
||||
*rendererPtr = new OpenGLRenderer_3_2;
|
||||
(*rendererPtr)->SetVersion(3, 2, 0);
|
||||
}
|
||||
}
|
||||
|
||||
OpenGLRenderer_3_2::~OpenGLRenderer_3_2()
|
||||
{
|
||||
glFinish();
|
||||
|
||||
DestroyVAOs();
|
||||
DestroyFBOs();
|
||||
DestroyMultisampledFBO();
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::InitExtensions()
|
||||
{
|
||||
Render3DError error = OGLERROR_NOERR;
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
// Load shader programs
|
||||
const std::string vertexShaderProgram = vertexShader_150;
|
||||
const std::string fragmentShaderProgram = fragmentShader_150;
|
||||
|
||||
// Get OpenGL extensions
|
||||
std::set<std::string> oglExtensionSet;
|
||||
this->GetExtensionSet(&oglExtensionSet);
|
||||
|
||||
// Initialize OpenGL
|
||||
this->InitTables();
|
||||
|
||||
this->isShaderSupported = true;
|
||||
error = this->CreateShaders(&vertexShaderProgram, &fragmentShaderProgram);
|
||||
if (error != OGLERROR_NOERR)
|
||||
{
|
||||
this->isShaderSupported = false;
|
||||
|
||||
if (error == OGLERROR_SHADER_CREATE_ERROR)
|
||||
{
|
||||
// Return on OGLERROR_SHADER_CREATE_ERROR, since a v2.0 driver should be able to
|
||||
// support shaders.
|
||||
return error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->CreateToonTable();
|
||||
}
|
||||
|
||||
this->isVBOSupported = true;
|
||||
this->CreateVBOs();
|
||||
|
||||
this->isPBOSupported = true;
|
||||
this->CreatePBOs();
|
||||
|
||||
this->isVAOSupported = true;
|
||||
this->CreateVAOs();
|
||||
|
||||
this->isFBOSupported = true;
|
||||
error = this->CreateFBOs();
|
||||
if (error != OGLERROR_NOERR)
|
||||
{
|
||||
OGLRef.fboFinalOutputID = 0;
|
||||
this->isFBOSupported = false;
|
||||
|
||||
if (error == OGLERROR_FBO_CREATE_ERROR)
|
||||
{
|
||||
// Return on OGLERROR_FBO_CREATE_ERROR, since a v3.0 driver should be able to
|
||||
// support FBOs.
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
this->isMultisampledFBOSupported = true;
|
||||
error = this->CreateMultisampledFBO();
|
||||
if (error != OGLERROR_NOERR)
|
||||
{
|
||||
OGLRef.selectedRenderingFBO = 0;
|
||||
this->isMultisampledFBOSupported = false;
|
||||
|
||||
if (error == OGLERROR_FBO_CREATE_ERROR)
|
||||
{
|
||||
// Return on OGLERROR_FBO_CREATE_ERROR, since a v3.0 driver should be able to
|
||||
// support FBOs.
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
this->InitTextures();
|
||||
this->InitFinalRenderStates(&oglExtensionSet); // This must be done last
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::CreateFBOs()
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
// Set up FBO render targets
|
||||
this->CreateClearImage();
|
||||
|
||||
glGenRenderbuffers(1, &OGLRef.rboFinalOutputColorID);
|
||||
glGenRenderbuffers(1, &OGLRef.rboFinalOutputDepthStencilID);
|
||||
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboFinalOutputColorID);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, 256, 192);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboFinalOutputDepthStencilID);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 256, 192);
|
||||
|
||||
// Set up FBOs
|
||||
glGenFramebuffers(1, &OGLRef.fboClearImageID);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboClearImageID);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, OGLRef.texClearImageColorID, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, OGLRef.texClearImageDepthStencilID, 0);
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
INFO("OpenGL: Failed to created FBOs. Some emulation features will be disabled.\n");
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
glDeleteFramebuffers(1, &OGLRef.fboClearImageID);
|
||||
this->DestroyClearImage();
|
||||
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboFinalOutputColorID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboFinalOutputDepthStencilID);
|
||||
|
||||
return OGLERROR_FBO_CREATE_ERROR;
|
||||
}
|
||||
|
||||
// Set up final output FBO
|
||||
glGenFramebuffers(1, &OGLRef.fboFinalOutputID);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboFinalOutputID);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, OGLRef.rboFinalOutputColorID);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, OGLRef.rboFinalOutputDepthStencilID);
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
INFO("OpenGL: Failed to created FBOs. Some emulation features will be disabled.\n");
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
glDeleteFramebuffers(1, &OGLRef.fboClearImageID);
|
||||
this->DestroyClearImage();
|
||||
|
||||
glDeleteFramebuffers(1, &OGLRef.fboFinalOutputID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboFinalOutputColorID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboFinalOutputDepthStencilID);
|
||||
|
||||
OGLRef.fboFinalOutputID = 0;
|
||||
return OGLERROR_FBO_CREATE_ERROR;
|
||||
}
|
||||
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
|
||||
INFO("OpenGL: Successfully created FBOs.\n");
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
void OpenGLRenderer_3_2::DestroyFBOs()
|
||||
{
|
||||
if (!this->isFBOSupported)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
glDeleteFramebuffers(1, &OGLRef.fboClearImageID);
|
||||
this->DestroyClearImage();
|
||||
|
||||
glDeleteFramebuffers(1, &OGLRef.fboFinalOutputID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboFinalOutputColorID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboFinalOutputDepthStencilID);
|
||||
|
||||
this->isFBOSupported = false;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::CreateMultisampledFBO()
|
||||
{
|
||||
// Check the maximum number of samples that the GPU supports and use that.
|
||||
// Since our target resolution is only 256x192 pixels, using the most samples
|
||||
// possible is the best thing to do.
|
||||
GLint maxSamples = 0;
|
||||
glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
|
||||
|
||||
if (maxSamples < 2)
|
||||
{
|
||||
INFO("OpenGL: GPU does not support at least 2x multisampled FBOs. Multisample antialiasing will be disabled.\n");
|
||||
return OGLERROR_FEATURE_UNSUPPORTED;
|
||||
}
|
||||
else if (maxSamples > OGLRENDER_MAX_MULTISAMPLES)
|
||||
{
|
||||
maxSamples = OGLRENDER_MAX_MULTISAMPLES;
|
||||
}
|
||||
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
// Set up FBO render targets
|
||||
glGenRenderbuffers(1, &OGLRef.rboMultisampleColorID);
|
||||
glGenRenderbuffers(1, &OGLRef.rboMultisampleDepthStencilID);
|
||||
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMultisampleColorID);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_RGBA, 256, 192);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboMultisampleDepthStencilID);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_DEPTH24_STENCIL8, 256, 192);
|
||||
|
||||
// Set up multisampled rendering FBO
|
||||
glGenFramebuffers(1, &OGLRef.fboMultisampleRenderID);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboMultisampleRenderID);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, OGLRef.rboMultisampleColorID);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, OGLRef.rboMultisampleDepthStencilID);
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glDeleteFramebuffers(1, &OGLRef.fboMultisampleRenderID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboMultisampleColorID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboMultisampleDepthStencilID);
|
||||
|
||||
INFO("OpenGL: Failed to create multisampled FBO. Multisample antialiasing will be disabled.\n");
|
||||
return OGLERROR_FBO_CREATE_ERROR;
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboFinalOutputID);
|
||||
INFO("OpenGL: Successfully created multisampled FBO.\n");
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
void OpenGLRenderer_3_2::DestroyMultisampledFBO()
|
||||
{
|
||||
if (!this->isMultisampledFBOSupported)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glDeleteFramebuffers(1, &OGLRef.fboMultisampleRenderID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboMultisampleColorID);
|
||||
glDeleteRenderbuffers(1, &OGLRef.rboMultisampleDepthStencilID);
|
||||
|
||||
this->isMultisampledFBOSupported = false;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::CreateVAOs()
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
glGenVertexArrays(1, &OGLRef.vaoMainStatesID);
|
||||
glBindVertexArray(OGLRef.vaoMainStatesID);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, OGLRef.vboVertexID);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OGLRef.iboIndexID);
|
||||
|
||||
glEnableVertexAttribArray(OGLVertexAttributeID_Position);
|
||||
glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
|
||||
glEnableVertexAttribArray(OGLVertexAttributeID_Color);
|
||||
|
||||
glVertexAttribPointer(OGLVertexAttributeID_Position, 4, GL_FLOAT, GL_FALSE, sizeof(VERT), (const GLvoid *)offsetof(VERT, coord));
|
||||
glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(VERT), (const GLvoid *)offsetof(VERT, texcoord));
|
||||
glVertexAttribPointer(OGLVertexAttributeID_Color, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VERT), (const GLvoid *)offsetof(VERT, color));
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
void OpenGLRenderer_3_2::DestroyVAOs()
|
||||
{
|
||||
if (!this->isVAOSupported)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
glBindVertexArray(0);
|
||||
glDeleteVertexArrays(1, &this->ref->vaoMainStatesID);
|
||||
|
||||
this->isVAOSupported = false;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::SetupShaderIO()
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
glBindAttribLocation(OGLRef.shaderProgram, OGLVertexAttributeID_Position, "inPosition");
|
||||
glBindAttribLocation(OGLRef.shaderProgram, OGLVertexAttributeID_TexCoord0, "inTexCoord0");
|
||||
glBindAttribLocation(OGLRef.shaderProgram, OGLVertexAttributeID_Color, "inColor");
|
||||
glBindFragDataLocation(OGLRef.shaderProgram, 0, "outFragColor");
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
void OpenGLRenderer_3_2::GetExtensionSet(std::set<std::string> *oglExtensionSet)
|
||||
{
|
||||
GLint extensionCount = 0;
|
||||
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &extensionCount);
|
||||
for (unsigned int i = 0; i < extensionCount; i++)
|
||||
{
|
||||
std::string extensionName = std::string((const char *)glGetStringi(GL_EXTENSIONS, i));
|
||||
oglExtensionSet->insert(extensionName);
|
||||
}
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::DownsampleFBO()
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
if (!this->isMultisampledFBOSupported || OGLRef.selectedRenderingFBO != OGLRef.fboMultisampleRenderID)
|
||||
{
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, OGLRef.selectedRenderingFBO);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, OGLRef.fboFinalOutputID);
|
||||
glBlitFramebuffer(0, 0, 256, 192, 0, 0, 256, 192, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboFinalOutputID);
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D_State *renderState)
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
glUniform1i(OGLRef.uniformEnableAlphaTest, renderState->enableAlphaTest ? GL_TRUE : GL_FALSE);
|
||||
glUniform1f(OGLRef.uniformAlphaTestRef, divide5bitBy31_LUT[renderState->alphaTestRef]);
|
||||
glUniform1i(OGLRef.uniformToonShadingMode, renderState->shading);
|
||||
glUniform1i(OGLRef.uniformWBuffer, renderState->wbuffer);
|
||||
|
||||
if(renderState->enableAlphaBlending)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
if (this->isMultisampledFBOSupported)
|
||||
{
|
||||
OGLRef.selectedRenderingFBO = CommonSettings.GFX3D_Renderer_Multisample ? OGLRef.fboMultisampleRenderID : OGLRef.fboFinalOutputID;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO);
|
||||
|
||||
const GLenum drawBufferList = {GL_COLOR_ATTACHMENT0};
|
||||
glDrawBuffers(1, &drawBufferList);
|
||||
}
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::PreRender(const GFX3D_State *renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList)
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
const unsigned int polyCount = polyList->count;
|
||||
unsigned int vertIndexCount = 0;
|
||||
|
||||
// Set up vertices
|
||||
for(unsigned int i = 0; i < polyCount; i++)
|
||||
{
|
||||
const POLY *poly = &polyList->list[indexList->list[i]];
|
||||
const unsigned int polyType = poly->type;
|
||||
|
||||
for(unsigned int j = 0; j < polyType; j++)
|
||||
{
|
||||
const GLushort vertIndex = poly->vertIndexes[j];
|
||||
|
||||
// While we're looping through our vertices, add each vertex index to
|
||||
// a buffer. For GFX3D_QUADS and GFX3D_QUAD_STRIP, we also add additional
|
||||
// vertices here to convert them to GL_TRIANGLES, which are much easier
|
||||
// to work with and won't be deprecated in future OpenGL versions.
|
||||
OGLRef.vertIndexBuffer[vertIndexCount++] = vertIndex;
|
||||
if (poly->vtxFormat == GFX3D_QUADS || poly->vtxFormat == GFX3D_QUAD_STRIP)
|
||||
{
|
||||
if (j == 2)
|
||||
{
|
||||
OGLRef.vertIndexBuffer[vertIndexCount++] = vertIndex;
|
||||
}
|
||||
else if (j == 3)
|
||||
{
|
||||
OGLRef.vertIndexBuffer[vertIndexCount++] = poly->vertIndexes[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Assign vertex attributes
|
||||
glBindVertexArray(OGLRef.vaoMainStatesID);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VERT) * vertList->count, vertList);
|
||||
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, vertIndexCount * sizeof(GLushort), OGLRef.vertIndexBuffer);
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::PostRender()
|
||||
{
|
||||
// Disable vertex attributes
|
||||
glBindVertexArray(0);
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_3_2::ClearUsingImage() const
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, OGLRef.fboClearImageID);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, OGLRef.selectedRenderingFBO);
|
||||
glBlitFramebuffer(0, 0, 256, 192, 0, 0, 256, 192, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO);
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2007 shash
|
||||
Copyright (C) 2008-2013 DeSmuME team
|
||||
|
||||
This file 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 file 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 the this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OGLRENDER_3_2_H
|
||||
#define OGLRENDER_3_2_H
|
||||
|
||||
#if defined(_WIN32) && !defined(WXPORT)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glcorearb.h>
|
||||
|
||||
#define OGLEXT(procPtr, func) procPtr func = NULL;
|
||||
#define INITOGLEXT(procPtr, func) func = (procPtr)wglGetProcAddress(#func);
|
||||
#define EXTERNOGLEXT(procPtr, func) extern procPtr func;
|
||||
#elif defined(__APPLE__)
|
||||
#include <OpenGL/gl3.h>
|
||||
#include <OpenGL/gl3ext.h>
|
||||
|
||||
// Ignore dynamic linking on Apple OS
|
||||
#define OGLEXT(procPtr, func)
|
||||
#define INITOGLEXT(procPtr, func)
|
||||
#define EXTERNOGLEXT(procPtr, func)
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glcorearb.h>
|
||||
#include <GL/glx.h>
|
||||
|
||||
#define OGLEXT(procPtr, func) procPtr func = NULL;
|
||||
#define INITOGLEXT(procPtr, func) func = (procPtr)glXGetProcAddress((const GLubyte *) #func);
|
||||
#define EXTERNOGLEXT(procPtr, func) extern procPtr func;
|
||||
#endif
|
||||
|
||||
// Check minimum OpenGL header version
|
||||
#if !defined(GL_VERSION_3_2)
|
||||
#error OpenGL requires v3.2 headers or later.
|
||||
#endif
|
||||
|
||||
#include "OGLRender.h"
|
||||
|
||||
void OGLLoadEntryPoints_3_2();
|
||||
void OGLCreateRenderer_3_2(OpenGLRenderer **rendererPtr);
|
||||
|
||||
class OpenGLRenderer_3_2 : public OpenGLRenderer_2_1
|
||||
{
|
||||
protected:
|
||||
virtual Render3DError InitExtensions();
|
||||
virtual Render3DError CreateFBOs();
|
||||
virtual void DestroyFBOs();
|
||||
virtual Render3DError CreateMultisampledFBO();
|
||||
virtual void DestroyMultisampledFBO();
|
||||
virtual Render3DError CreateVAOs();
|
||||
virtual void DestroyVAOs();
|
||||
|
||||
virtual Render3DError SetupShaderIO();
|
||||
|
||||
virtual void GetExtensionSet(std::set<std::string> *oglExtensionSet);
|
||||
virtual Render3DError DownsampleFBO();
|
||||
|
||||
virtual Render3DError BeginRender(const GFX3D_State *renderState);
|
||||
virtual Render3DError PreRender(const GFX3D_State *renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList);
|
||||
virtual Render3DError PostRender();
|
||||
|
||||
virtual Render3DError ClearUsingImage() const;
|
||||
|
||||
public:
|
||||
~OpenGLRenderer_3_2();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Copyright (C) 2006-2007 shash
|
||||
Copyright (C) 2008-2009 DeSmuME team
|
||||
Copyright (C) 2008-2013 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "render3D.h"
|
||||
#include "gfx3d.h"
|
||||
#include "MMU.h"
|
||||
#include "texcache.h"
|
||||
|
||||
int cur3DCore = GPU3D_NULL;
|
||||
|
@ -92,3 +93,146 @@ bool NDS_3D_ChangeCore(int newCore)
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Render3DError Render3D::BeginRender(const GFX3D_State *renderState)
|
||||
{
|
||||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError Render3D::PreRender(const GFX3D_State *renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList)
|
||||
{
|
||||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError Render3D::DoRender(const GFX3D_State *renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList)
|
||||
{
|
||||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError Render3D::PostRender()
|
||||
{
|
||||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError Render3D::EndRender(const u64 frameCount)
|
||||
{
|
||||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError Render3D::UpdateClearImage(const u16 *__restrict colorBuffer, const u16 *__restrict depthBuffer, const u8 clearStencil, const u8 xScroll, const u8 yScroll)
|
||||
{
|
||||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError Render3D::UpdateToonTable(const u16 *toonTableBuffer)
|
||||
{
|
||||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError Render3D::ClearFramebuffer(const GFX3D_State *renderState)
|
||||
{
|
||||
Render3DError error = RENDER3DERROR_NOERR;
|
||||
|
||||
struct GFX3D_ClearColor
|
||||
{
|
||||
u8 r;
|
||||
u8 g;
|
||||
u8 b;
|
||||
u8 a;
|
||||
} clearColor;
|
||||
|
||||
clearColor.r = renderState->clearColor & 0x1F;
|
||||
clearColor.g = (renderState->clearColor >> 5) & 0x1F;
|
||||
clearColor.b = (renderState->clearColor >> 10) & 0x1F;
|
||||
clearColor.a = (renderState->clearColor >> 16) & 0x1F;
|
||||
|
||||
const u8 clearStencil = (renderState->clearColor >> 24) & 0x3F;
|
||||
|
||||
if (renderState->enableClearImage)
|
||||
{
|
||||
const u16 *__restrict clearColorBuffer = (u16 *__restrict)MMU.texInfo.textureSlotAddr[2];
|
||||
const u16 *__restrict clearDepthBuffer = (u16 *__restrict)MMU.texInfo.textureSlotAddr[3];
|
||||
const u16 scrollBits = T1ReadWord(MMU.ARM9_REG, 0x356); //CLRIMAGE_OFFSET
|
||||
const u8 xScroll = scrollBits & 0xFF;
|
||||
const u8 yScroll = (scrollBits >> 8) & 0xFF;
|
||||
|
||||
error = this->UpdateClearImage(clearColorBuffer, clearDepthBuffer, clearStencil, xScroll, yScroll);
|
||||
if (error == RENDER3DERROR_NOERR)
|
||||
{
|
||||
error = this->ClearUsingImage();
|
||||
}
|
||||
else
|
||||
{
|
||||
error = this->ClearUsingValues(clearColor.r, clearColor.g, clearColor.b, clearColor.a, renderState->clearDepth, clearStencil);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error = this->ClearUsingValues(clearColor.r, clearColor.g, clearColor.b, clearColor.a, renderState->clearDepth, clearStencil);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
Render3DError Render3D::ClearUsingImage() const
|
||||
{
|
||||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError Render3D::ClearUsingValues(const u8 r, const u8 g, const u8 b, const u8 a, const u32 clearDepth, const u8 clearStencil) const
|
||||
{
|
||||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError Render3D::SetupPolygon(const POLY *thePoly)
|
||||
{
|
||||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError Render3D::SetupTexture(const POLY *thePoly, bool enableTexturing)
|
||||
{
|
||||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError Render3D::SetupViewport(const POLY *thePoly)
|
||||
{
|
||||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError Render3D::Reset()
|
||||
{
|
||||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError Render3D::Render(const GFX3D_State *renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList, const u64 frameCount)
|
||||
{
|
||||
Render3DError error = RENDER3DERROR_NOERR;
|
||||
|
||||
error = this->BeginRender(renderState);
|
||||
if (error != RENDER3DERROR_NOERR)
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
this->UpdateToonTable(renderState->u16ToonTable);
|
||||
this->ClearFramebuffer(renderState);
|
||||
|
||||
this->PreRender(renderState, vertList, polyList, indexList);
|
||||
this->DoRender(renderState, vertList, polyList, indexList);
|
||||
this->PostRender();
|
||||
|
||||
this->EndRender(frameCount);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
Render3DError Render3D::RenderFinish()
|
||||
{
|
||||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError Render3D::VramReconfigureSignal()
|
||||
{
|
||||
TexCache_Invalidate();
|
||||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Copyright (C) 2006-2007 shash
|
||||
Copyright (C) 2007-2012 DeSmuME team
|
||||
Copyright (C) 2007-2013 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -19,6 +19,7 @@
|
|||
#ifndef RENDER3D_H
|
||||
#define RENDER3D_H
|
||||
|
||||
#include "gfx3d.h"
|
||||
#include "types.h"
|
||||
|
||||
//not using this right now
|
||||
|
@ -73,5 +74,39 @@ void Default3D_VramReconfigureSignal();
|
|||
void NDS_3D_SetDriver (int core3DIndex);
|
||||
bool NDS_3D_ChangeCore(int newCore);
|
||||
|
||||
enum Render3DErrorCode
|
||||
{
|
||||
RENDER3DERROR_NOERR = 0
|
||||
};
|
||||
|
||||
typedef int Render3DError;
|
||||
|
||||
class Render3D
|
||||
{
|
||||
protected:
|
||||
virtual Render3DError BeginRender(const GFX3D_State *renderState);
|
||||
virtual Render3DError PreRender(const GFX3D_State *renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList);
|
||||
virtual Render3DError DoRender(const GFX3D_State *renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList);
|
||||
virtual Render3DError PostRender();
|
||||
virtual Render3DError EndRender(const u64 frameCount);
|
||||
|
||||
virtual Render3DError UpdateClearImage(const u16 *__restrict colorBuffer, const u16 *__restrict depthBuffer, const u8 clearStencil, const u8 xScroll, const u8 yScroll);
|
||||
virtual Render3DError UpdateToonTable(const u16 *toonTableBuffer);
|
||||
|
||||
virtual Render3DError ClearFramebuffer(const GFX3D_State *renderState);
|
||||
virtual Render3DError ClearUsingImage() const;
|
||||
virtual Render3DError ClearUsingValues(const u8 r, const u8 g, const u8 b, const u8 a, const u32 clearDepth, const u8 clearStencil) const;
|
||||
|
||||
virtual Render3DError SetupPolygon(const POLY *thePoly);
|
||||
virtual Render3DError SetupTexture(const POLY *thePoly, bool enableTexturing);
|
||||
virtual Render3DError SetupViewport(const POLY *thePoly);
|
||||
|
||||
public:
|
||||
virtual Render3DError Reset();
|
||||
virtual Render3DError Render(const GFX3D_State *renderState, const VERTLIST *vertList, const POLYLIST *polyList, const INDEXLIST *indexList, const u64 frameCount);
|
||||
virtual Render3DError RenderFinish();
|
||||
virtual Render3DError VramReconfigureSignal();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue