1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
|
// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2
// Refer to the license.txt file included.
#include "Globals.h"
#include "VideoConfig.h"
#include "IniFile.h"
#include "Core.h"
#include "Host.h"
#include "VideoBackend.h"
#include "ConfigManager.h"
#include "Render.h"
#include "VertexShaderManager.h"
#include "GLUtil.h"
GLWindow GLWin;
cInterfaceBase *GLInterface;
namespace OGL
{
// Draw messages on top of the screen
unsigned int VideoBackend::PeekMessages()
{
return GLInterface->PeekMessages();
}
// Show the current FPS
void VideoBackend::UpdateFPSDisplay(const char *text)
{
char temp[100];
snprintf(temp, sizeof temp, "%s | OpenGL | %s", scm_rev_str, text);
return GLInterface->UpdateFPSDisplay(temp);
}
}
void InitInterface()
{
#if defined(USE_EGL) && USE_EGL
GLInterface = new cInterfaceEGL;
#elif defined(__APPLE__)
GLInterface = new cInterfaceAGL;
#elif defined(_WIN32)
GLInterface = new cInterfaceWGL;
#elif defined(HAVE_X11) && HAVE_X11
GLInterface = new cInterfaceGLX;
#endif
}
GLuint OpenGL_CompileProgram ( const char* vertexShader, const char* fragmentShader )
{
// generate objects
GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
GLuint programID = glCreateProgram();
// compile vertex shader
glShaderSource(vertexShaderID, 1, &vertexShader, NULL);
glCompileShader(vertexShaderID);
#if defined(_DEBUG) || defined(DEBUGFAST) || defined(DEBUG_GLSL)
GLint Result = GL_FALSE;
char stringBuffer[1024];
GLsizei stringBufferUsage = 0;
glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderInfoLog(vertexShaderID, 1024, &stringBufferUsage, stringBuffer);
if(Result && stringBufferUsage) {
ERROR_LOG(VIDEO, "GLSL vertex shader warnings:\n%s%s", stringBuffer, vertexShader);
} else if(!Result) {
ERROR_LOG(VIDEO, "GLSL vertex shader error:\n%s%s", stringBuffer, vertexShader);
} else {
DEBUG_LOG(VIDEO, "GLSL vertex shader compiled:\n%s", vertexShader);
}
bool shader_errors = !Result;
#endif
// compile fragment shader
glShaderSource(fragmentShaderID, 1, &fragmentShader, NULL);
glCompileShader(fragmentShaderID);
#if defined(_DEBUG) || defined(DEBUGFAST) || defined(DEBUG_GLSL)
glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderInfoLog(fragmentShaderID, 1024, &stringBufferUsage, stringBuffer);
if(Result && stringBufferUsage) {
ERROR_LOG(VIDEO, "GLSL fragment shader warnings:\n%s%s", stringBuffer, fragmentShader);
} else if(!Result) {
ERROR_LOG(VIDEO, "GLSL fragment shader error:\n%s%s", stringBuffer, fragmentShader);
} else {
DEBUG_LOG(VIDEO, "GLSL fragment shader compiled:\n%s", fragmentShader);
}
shader_errors |= !Result;
#endif
// link them
glAttachShader(programID, vertexShaderID);
glAttachShader(programID, fragmentShaderID);
glLinkProgram(programID);
#if defined(_DEBUG) || defined(DEBUGFAST) || defined(DEBUG_GLSL)
glGetProgramiv(programID, GL_LINK_STATUS, &Result);
glGetProgramInfoLog(programID, 1024, &stringBufferUsage, stringBuffer);
if(Result && stringBufferUsage) {
ERROR_LOG(VIDEO, "GLSL linker warnings:\n%s%s%s", stringBuffer, vertexShader, fragmentShader);
} else if(!Result && !shader_errors) {
ERROR_LOG(VIDEO, "GLSL linker error:\n%s%s%s", stringBuffer, vertexShader, fragmentShader);
}
#endif
// cleanup
glDeleteShader(vertexShaderID);
glDeleteShader(fragmentShaderID);
return programID;
}
GLuint OpenGL_ReportGLError(const char *function, const char *file, int line)
{
GLint err = glGetError();
if (err != GL_NO_ERROR)
{
ERROR_LOG(VIDEO, "%s:%d: (%s) OpenGL error 0x%x\n",
file, line, function, err);
}
return err;
}
void OpenGL_ReportARBProgramError()
{
#ifndef USE_GLES
const GLubyte* pstr = glGetString(GL_PROGRAM_ERROR_STRING_ARB);
if (pstr != NULL && pstr[0] != 0)
{
GLint loc = 0;
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &loc);
ERROR_LOG(VIDEO, "Program error at %d: ", loc);
ERROR_LOG(VIDEO, "%s", (char*)pstr);
ERROR_LOG(VIDEO, "\n");
}
#endif
}
bool OpenGL_ReportFBOError(const char *function, const char *file, int line)
{
#ifndef USE_GLES
unsigned int fbo_status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (fbo_status != GL_FRAMEBUFFER_COMPLETE)
{
const char *error = "unknown error";
switch (fbo_status)
{
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
error = "INCOMPLETE_ATTACHMENT";
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
error = "INCOMPLETE_MISSING_ATTACHMENT";
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
error = "INCOMPLETE_DRAW_BUFFER";
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
error = "INCOMPLETE_READ_BUFFER";
break;
case GL_FRAMEBUFFER_UNSUPPORTED:
error = "UNSUPPORTED";
break;
}
ERROR_LOG(VIDEO, "%s:%d: (%s) OpenGL FBO error - %s\n",
file, line, function, error);
return false;
}
#endif
return true;
}
|