mirror of https://github.com/snes9xgit/snes9x.git
GTK+: Modernize OpenGL code.
Requires OpenGL 2.0 or above. Everything is core-compatible now.
This commit is contained in:
parent
b84a8fbd5b
commit
09498e72e0
|
@ -11,6 +11,36 @@
|
||||||
#include "gtk_shader_parameters.h"
|
#include "gtk_shader_parameters.h"
|
||||||
#include "shaders/shader_helpers.h"
|
#include "shaders/shader_helpers.h"
|
||||||
|
|
||||||
|
static const char *stock_vertex_shader =
|
||||||
|
"#version 130\n"
|
||||||
|
|
||||||
|
"in vec2 in_position;\n"
|
||||||
|
"in vec2 in_texcoord;\n"
|
||||||
|
"out vec2 texcoord;\n"
|
||||||
|
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
" gl_Position = vec4 (in_position, 0.0, 1.0);\n"
|
||||||
|
" texcoord = in_texcoord;\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
|
||||||
|
static const char *stock_fragment_shader =
|
||||||
|
"#version 130\n"
|
||||||
|
|
||||||
|
"uniform sampler2D texmap;\n"
|
||||||
|
"out vec4 fragcolor;\n"
|
||||||
|
"in vec2 texcoord;\n"
|
||||||
|
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
" fragcolor = texture2D(texmap, texcoord);\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
|
||||||
|
static GLfloat coords[] = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f,
|
||||||
|
0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, };
|
||||||
|
|
||||||
static void S9xViewportCallback (int src_width, int src_height,
|
static void S9xViewportCallback (int src_width, int src_height,
|
||||||
int viewport_x, int viewport_y,
|
int viewport_x, int viewport_y,
|
||||||
int viewport_width, int viewport_height,
|
int viewport_width, int viewport_height,
|
||||||
|
@ -37,7 +67,7 @@ void S9xOpenGLDisplayDriver::update (int width, int height, int yoffset)
|
||||||
{
|
{
|
||||||
uint8 *final_buffer = NULL;
|
uint8 *final_buffer = NULL;
|
||||||
int final_pitch;
|
int final_pitch;
|
||||||
void *pboMemory = NULL;
|
void *pbo_map = NULL;
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
|
|
||||||
GtkAllocation allocation;
|
GtkAllocation allocation;
|
||||||
|
@ -56,6 +86,7 @@ void S9xOpenGLDisplayDriver::update (int width, int height, int yoffset)
|
||||||
allocation.height *= gdk_scale_factor;
|
allocation.height *= gdk_scale_factor;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
glActiveTexture (GL_TEXTURE0);
|
||||||
glBindTexture (GL_TEXTURE_2D, texmap);
|
glBindTexture (GL_TEXTURE_2D, texmap);
|
||||||
GLint filter = Settings.BilinearFilter ? GL_LINEAR : GL_NEAREST;
|
GLint filter = Settings.BilinearFilter ? GL_LINEAR : GL_NEAREST;
|
||||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
|
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
|
||||||
|
@ -65,7 +96,6 @@ void S9xOpenGLDisplayDriver::update (int width, int height, int yoffset)
|
||||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clamp);
|
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clamp);
|
||||||
|
|
||||||
glClear (GL_COLOR_BUFFER_BIT);
|
glClear (GL_COLOR_BUFFER_BIT);
|
||||||
glEnable (GL_TEXTURE_2D);
|
|
||||||
|
|
||||||
if (config->scale_method > 0)
|
if (config->scale_method > 0)
|
||||||
{
|
{
|
||||||
|
@ -95,8 +125,10 @@ void S9xOpenGLDisplayDriver::update (int width, int height, int yoffset)
|
||||||
final_buffer += (final_pitch * yoffset);
|
final_buffer += (final_pitch * yoffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
x = width; y = height;
|
x = width;
|
||||||
w = allocation.width; h = allocation.height;
|
y = height;
|
||||||
|
w = allocation.width;
|
||||||
|
h = allocation.height;
|
||||||
S9xApplyAspect (x, y, w, h);
|
S9xApplyAspect (x, y, w, h);
|
||||||
|
|
||||||
glViewport (x, allocation.height - y - h, w, h);
|
glViewport (x, allocation.height - y - h, w, h);
|
||||||
|
@ -114,11 +146,11 @@ void S9xOpenGLDisplayDriver::update (int width, int height, int yoffset)
|
||||||
width * height * 2,
|
width * height * 2,
|
||||||
NULL,
|
NULL,
|
||||||
GL_STREAM_DRAW);
|
GL_STREAM_DRAW);
|
||||||
pboMemory = glMapBuffer (GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
|
pbo_map = glMapBuffer (GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
|
||||||
|
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
memcpy ((uint8 *) pboMemory + (width * y * 2),
|
memcpy ((uint8 *) pbo_map + (width * y * 2),
|
||||||
final_buffer + (y * final_pitch),
|
final_buffer + (y * final_pitch),
|
||||||
width * image_bpp);
|
width * image_bpp);
|
||||||
}
|
}
|
||||||
|
@ -145,12 +177,12 @@ void S9xOpenGLDisplayDriver::update (int width, int height, int yoffset)
|
||||||
width * height * 4,
|
width * height * 4,
|
||||||
NULL,
|
NULL,
|
||||||
GL_STREAM_DRAW);
|
GL_STREAM_DRAW);
|
||||||
pboMemory = glMapBuffer (GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
|
pbo_map = glMapBuffer (GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
|
||||||
|
|
||||||
/* Pixel swizzling in software */
|
/* Pixel swizzling in software */
|
||||||
S9xSetEndianess (ENDIAN_NORMAL);
|
S9xSetEndianess (ENDIAN_NORMAL);
|
||||||
S9xConvert (final_buffer,
|
S9xConvert (final_buffer,
|
||||||
pboMemory,
|
pbo_map,
|
||||||
final_pitch,
|
final_pitch,
|
||||||
width * 4,
|
width * 4,
|
||||||
width,
|
width,
|
||||||
|
@ -187,11 +219,6 @@ void S9xOpenGLDisplayDriver::update (int width, int height, int yoffset)
|
||||||
final_buffer);
|
final_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
texcoords[1] = (float) (height) / texture_height;
|
|
||||||
texcoords[2] = (float) (width) / texture_width;
|
|
||||||
texcoords[3] = texcoords[1];
|
|
||||||
texcoords[4] = texcoords[2];
|
|
||||||
|
|
||||||
if (using_glsl_shaders)
|
if (using_glsl_shaders)
|
||||||
{
|
{
|
||||||
glsl_shader->render (texmap, width, height, x, allocation.height - y - h, w, h, S9xViewportCallback);
|
glsl_shader->render (texmap, width, height, x, allocation.height - y - h, w, h, S9xViewportCallback);
|
||||||
|
@ -199,7 +226,15 @@ void S9xOpenGLDisplayDriver::update (int width, int height, int yoffset)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
glDrawArrays (GL_QUADS, 0, 4);
|
glUseProgram (stock_program);
|
||||||
|
glBindBuffer (GL_ARRAY_BUFFER, coord_buffer);
|
||||||
|
glEnableVertexAttribArray (0);
|
||||||
|
glVertexAttribPointer (0, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET (0));
|
||||||
|
glEnableVertexAttribArray (1);
|
||||||
|
glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET (32));
|
||||||
|
glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
glDisableVertexAttribArray (1);
|
||||||
|
glDisableVertexAttribArray (0);
|
||||||
|
|
||||||
swap_buffers ();
|
swap_buffers ();
|
||||||
}
|
}
|
||||||
|
@ -332,26 +367,41 @@ int S9xOpenGLDisplayDriver::opengl_defaults ()
|
||||||
npot = true;
|
npot = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
glEnableClientState (GL_VERTEX_ARRAY);
|
stock_program = glCreateProgram ();
|
||||||
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
|
|
||||||
|
|
||||||
vertices[0] = 0.0f;
|
GLuint vertex_shader = glCreateShader (GL_VERTEX_SHADER);
|
||||||
vertices[1] = 0.0f;
|
glShaderSource (vertex_shader, 1, (const GLchar **) &stock_vertex_shader, NULL);
|
||||||
vertices[2] = 1.0f;
|
glCompileShader (vertex_shader);
|
||||||
vertices[3] = 0.0f;
|
glAttachShader (stock_program, vertex_shader);
|
||||||
vertices[4] = 1.0f;
|
|
||||||
vertices[5] = 1.0f;
|
|
||||||
vertices[6] = 0.0f;
|
|
||||||
vertices[7] = 1.0f;
|
|
||||||
|
|
||||||
glVertexPointer (2, GL_FLOAT, 0, vertices);
|
GLuint fragment_shader = glCreateShader (GL_FRAGMENT_SHADER);
|
||||||
|
glShaderSource (fragment_shader, 1, (const GLchar **) &stock_fragment_shader, NULL);
|
||||||
|
glCompileShader (fragment_shader);
|
||||||
|
glAttachShader (stock_program, fragment_shader);
|
||||||
|
|
||||||
texcoords[0] = 0.0f;
|
glBindAttribLocation (stock_program, 0, "in_position");
|
||||||
texcoords[5] = 0.0f;
|
glBindAttribLocation (stock_program, 1, "in_texcoord");
|
||||||
texcoords[6] = 0.0f;
|
|
||||||
texcoords[7] = 0.0f;
|
|
||||||
|
|
||||||
glTexCoordPointer (2, GL_FLOAT, 0, texcoords);
|
glLinkProgram (stock_program);
|
||||||
|
glUseProgram (stock_program);
|
||||||
|
|
||||||
|
glDeleteShader (vertex_shader);
|
||||||
|
glDeleteShader (fragment_shader);
|
||||||
|
|
||||||
|
GLint texture_uniform = glGetUniformLocation (stock_program, "texmap");
|
||||||
|
glUniform1i (texture_uniform, 0);
|
||||||
|
|
||||||
|
if (core)
|
||||||
|
{
|
||||||
|
GLuint vao;
|
||||||
|
glGenVertexArrays (1, &vao);
|
||||||
|
glBindVertexArray (vao);
|
||||||
|
}
|
||||||
|
|
||||||
|
glGenBuffers (1, &coord_buffer);
|
||||||
|
glBindBuffer (GL_ARRAY_BUFFER, coord_buffer);
|
||||||
|
glBufferData (GL_ARRAY_BUFFER, sizeof (GLfloat) * 16, coords, GL_STATIC_DRAW);
|
||||||
|
glBindBuffer (GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
if (config->use_pbos)
|
if (config->use_pbos)
|
||||||
{
|
{
|
||||||
|
@ -393,25 +443,7 @@ int S9xOpenGLDisplayDriver::opengl_defaults ()
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
glEnable (GL_DITHER);
|
|
||||||
|
|
||||||
glDisable (GL_POLYGON_SMOOTH);
|
|
||||||
glShadeModel (GL_FLAT);
|
|
||||||
glPolygonMode (GL_FRONT, GL_FILL);
|
|
||||||
|
|
||||||
glEnable (GL_CULL_FACE);
|
|
||||||
glCullFace (GL_BACK);
|
|
||||||
|
|
||||||
glClearColor (0.0, 0.0, 0.0, 0.0);
|
glClearColor (0.0, 0.0, 0.0, 0.0);
|
||||||
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
|
||||||
|
|
||||||
glDisable (GL_BLEND);
|
|
||||||
glDisable (GL_DEPTH_TEST);
|
|
||||||
glDisable (GL_TEXTURE_2D);
|
|
||||||
|
|
||||||
glMatrixMode (GL_PROJECTION);
|
|
||||||
glLoadIdentity ();
|
|
||||||
glOrtho (0.0, 1.0, 0.0, 1.0, -1, 1);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -456,12 +488,22 @@ int S9xOpenGLDisplayDriver::create_context ()
|
||||||
|
|
||||||
context->make_current ();
|
context->make_current ();
|
||||||
|
|
||||||
if (epoxy_gl_version () < 20)
|
int version = epoxy_gl_version ();
|
||||||
|
if (version < 20)
|
||||||
{
|
{
|
||||||
printf ("OpenGL version is only %d. Need 20.\n", epoxy_gl_version ());
|
printf ("OpenGL version is only %d.%d. Need 2.0.\n"
|
||||||
return 0;
|
"Trying to run anyway.",
|
||||||
|
version / 10,
|
||||||
|
version % 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int profile_mask = 0;
|
||||||
|
glGetIntegerv (GL_CONTEXT_PROFILE_MASK, &profile_mask);
|
||||||
|
if (profile_mask & GL_CONTEXT_CORE_PROFILE_BIT)
|
||||||
|
core = true;
|
||||||
|
else
|
||||||
|
core = false;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,13 +42,14 @@ class S9xOpenGLDisplayDriver : public S9xDisplayDriver
|
||||||
int create_context ();
|
int create_context ();
|
||||||
void resize ();
|
void resize ();
|
||||||
|
|
||||||
|
GLuint stock_program;
|
||||||
|
GLuint coord_buffer;
|
||||||
GLint texture_width;
|
GLint texture_width;
|
||||||
GLint texture_height;
|
GLint texture_height;
|
||||||
GLfloat vertices[8];
|
|
||||||
GLfloat texcoords[8];
|
|
||||||
GLuint texmap;
|
GLuint texmap;
|
||||||
GLuint pbo;
|
GLuint pbo;
|
||||||
|
|
||||||
|
bool core;
|
||||||
bool npot;
|
bool npot;
|
||||||
bool using_pbos;
|
bool using_pbos;
|
||||||
bool initialized;
|
bool initialized;
|
||||||
|
|
|
@ -91,7 +91,9 @@ bool GTKGLXContext::attach (GtkWidget *widget)
|
||||||
bool GTKGLXContext::create_context ()
|
bool GTKGLXContext::create_context ()
|
||||||
{
|
{
|
||||||
int context_attribs[] = {
|
int context_attribs[] = {
|
||||||
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
|
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||||
|
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||||
|
GLX_CONTEXT_MINOR_VERSION_ARB, 3,
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -142,13 +144,9 @@ void GTKGLXContext::make_current ()
|
||||||
|
|
||||||
void GTKGLXContext::swap_interval (int frames)
|
void GTKGLXContext::swap_interval (int frames)
|
||||||
{
|
{
|
||||||
const char *extensions = (const char *) glGetString (GL_EXTENSIONS);
|
if (epoxy_has_glx_extension (display, screen, "GLX_EXT_swap_control"))
|
||||||
if (!extensions)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (strstr (extensions, "EXT_swap_control"))
|
|
||||||
glXSwapIntervalEXT (display, xid, frames);
|
glXSwapIntervalEXT (display, xid, frames);
|
||||||
else if (strstr (extensions, "SGI_swap_control"))
|
else if (epoxy_has_glx_extension (display, screen, "GLX_SGI_swap_control"))
|
||||||
glXSwapIntervalSGI (frames);
|
glXSwapIntervalSGI (frames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,14 @@ bool WaylandEGLContext::create_context ()
|
||||||
EGL_NONE
|
EGL_NONE
|
||||||
};
|
};
|
||||||
|
|
||||||
EGLint context_attribs[] = {
|
EGLint core_context_attribs[] = {
|
||||||
|
EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
|
||||||
|
EGL_CONTEXT_MAJOR_VERSION, 3,
|
||||||
|
EGL_CONTEXT_MINOR_VERSION, 3,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
EGLint compatibility_context_attribs[] = {
|
||||||
EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT,
|
EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT,
|
||||||
EGL_NONE
|
EGL_NONE
|
||||||
};
|
};
|
||||||
|
@ -144,11 +151,15 @@ bool WaylandEGLContext::create_context ()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
egl_context = eglCreateContext (egl_display, egl_config, EGL_NO_CONTEXT, context_attribs);
|
egl_context = eglCreateContext (egl_display, egl_config, EGL_NO_CONTEXT, core_context_attribs);
|
||||||
if (!egl_context)
|
if (!egl_context)
|
||||||
{
|
{
|
||||||
printf ("Couldn't create context.\n");
|
egl_context = eglCreateContext (egl_display, egl_config, EGL_NO_CONTEXT, compatibility_context_attribs);
|
||||||
return false;
|
if (!egl_context)
|
||||||
|
{
|
||||||
|
printf ("Couldn't create context.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_surface_set_buffer_scale (child, scale);
|
wl_surface_set_buffer_scale (child, scale);
|
||||||
|
|
Loading…
Reference in New Issue