mirror of https://github.com/OpenTTD/OpenTTD
Add: [OpenGL] Support for 8bpp blitters.
parent
320072c8dc
commit
e8fc050b6e
|
@ -263,7 +263,7 @@ static bool SwitchNewGRFBlitter()
|
||||||
* between multiple 32bpp blitters, which perform differently with 8bpp sprites.
|
* between multiple 32bpp blitters, which perform differently with 8bpp sprites.
|
||||||
*/
|
*/
|
||||||
uint depth_wanted_by_base = BaseGraphics::GetUsedSet()->blitter == BLT_32BPP ? 32 : 8;
|
uint depth_wanted_by_base = BaseGraphics::GetUsedSet()->blitter == BLT_32BPP ? 32 : 8;
|
||||||
uint depth_wanted_by_grf = _support8bpp == S8BPP_NONE ? 32 : 8;
|
uint depth_wanted_by_grf = _support8bpp != S8BPP_NONE || VideoDriver::GetInstance()->HasEfficient8Bpp() ? 8 : 32;
|
||||||
for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) {
|
for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) {
|
||||||
if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND || HasBit(c->flags, GCF_INIT_ONLY)) continue;
|
if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND || HasBit(c->flags, GCF_INIT_ONLY)) continue;
|
||||||
if (c->palette & GRFP_BLT_32BPP) depth_wanted_by_grf = 32;
|
if (c->palette & GRFP_BLT_32BPP) depth_wanted_by_grf = 32;
|
||||||
|
|
|
@ -51,3 +51,28 @@ static const char *_frag_shader_direct_150[] = {
|
||||||
" colour = texture(colour_tex, colour_tex_uv);",
|
" colour = texture(colour_tex, colour_tex_uv);",
|
||||||
"}",
|
"}",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Fragment shader that performs a palette lookup to read the colour from an 8bpp texture. */
|
||||||
|
static const char *_frag_shader_palette[] = {
|
||||||
|
"#version 110\n",
|
||||||
|
"uniform sampler2D colour_tex;",
|
||||||
|
"uniform sampler1D palette;",
|
||||||
|
"varying vec2 colour_tex_uv;",
|
||||||
|
"void main() {",
|
||||||
|
" float idx = texture2D(colour_tex, colour_tex_uv).r;",
|
||||||
|
" gl_FragData[0] = texture1D(palette, idx);",
|
||||||
|
"}",
|
||||||
|
};
|
||||||
|
|
||||||
|
/** GLSL 1.50 fragment shader that performs a palette lookup to read the colour from an 8bpp texture. */
|
||||||
|
static const char *_frag_shader_palette_150[] = {
|
||||||
|
"#version 150\n",
|
||||||
|
"uniform sampler2D colour_tex;",
|
||||||
|
"uniform sampler1D palette;",
|
||||||
|
"in vec2 colour_tex_uv;",
|
||||||
|
"out vec4 colour;",
|
||||||
|
"void main() {",
|
||||||
|
" float idx = texture(colour_tex, colour_tex_uv).r;",
|
||||||
|
" colour = texture(palette, idx);",
|
||||||
|
"}",
|
||||||
|
};
|
||||||
|
|
|
@ -23,10 +23,12 @@
|
||||||
#include "../3rdparty/opengl/glext.h"
|
#include "../3rdparty/opengl/glext.h"
|
||||||
|
|
||||||
#include "opengl.h"
|
#include "opengl.h"
|
||||||
#include "../core/mem_func.hpp"
|
|
||||||
#include "../core/geometry_func.hpp"
|
#include "../core/geometry_func.hpp"
|
||||||
|
#include "../core/mem_func.hpp"
|
||||||
|
#include "../core/math_func.hpp"
|
||||||
#include "../gfx_func.h"
|
#include "../gfx_func.h"
|
||||||
#include "../debug.h"
|
#include "../debug.h"
|
||||||
|
#include "../blitter/factory.hpp"
|
||||||
|
|
||||||
#include "../table/opengl_shader.h"
|
#include "../table/opengl_shader.h"
|
||||||
|
|
||||||
|
@ -37,6 +39,8 @@
|
||||||
static PFNGLDEBUGMESSAGECONTROLPROC _glDebugMessageControl;
|
static PFNGLDEBUGMESSAGECONTROLPROC _glDebugMessageControl;
|
||||||
static PFNGLDEBUGMESSAGECALLBACKPROC _glDebugMessageCallback;
|
static PFNGLDEBUGMESSAGECALLBACKPROC _glDebugMessageCallback;
|
||||||
|
|
||||||
|
static PFNGLACTIVETEXTUREPROC _glActiveTexture;
|
||||||
|
|
||||||
static PFNGLGENBUFFERSPROC _glGenBuffers;
|
static PFNGLGENBUFFERSPROC _glGenBuffers;
|
||||||
static PFNGLDELETEBUFFERSPROC _glDeleteBuffers;
|
static PFNGLDELETEBUFFERSPROC _glDeleteBuffers;
|
||||||
static PFNGLBINDBUFFERPROC _glBindBuffer;
|
static PFNGLBINDBUFFERPROC _glBindBuffer;
|
||||||
|
@ -155,6 +159,18 @@ bool IsOpenGLVersionAtLeast(byte major, byte minor)
|
||||||
return (_gl_major_ver > major) || (_gl_major_ver == major && _gl_minor_ver >= minor);
|
return (_gl_major_ver > major) || (_gl_major_ver == major && _gl_minor_ver >= minor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Bind texture-related extension functions. */
|
||||||
|
static bool BindTextureExtensions()
|
||||||
|
{
|
||||||
|
if (IsOpenGLVersionAtLeast(1, 3)) {
|
||||||
|
_glActiveTexture = (PFNGLACTIVETEXTUREPROC)GetOGLProcAddress("glActiveTexture");
|
||||||
|
} else {
|
||||||
|
_glActiveTexture = (PFNGLACTIVETEXTUREPROC)GetOGLProcAddress("glActiveTextureARB");
|
||||||
|
}
|
||||||
|
|
||||||
|
return _glActiveTexture != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
/** Bind vertex buffer object extension functions. */
|
/** Bind vertex buffer object extension functions. */
|
||||||
static bool BindVBOExtension()
|
static bool BindVBOExtension()
|
||||||
{
|
{
|
||||||
|
@ -351,6 +367,7 @@ OpenGLBackend::~OpenGLBackend()
|
||||||
{
|
{
|
||||||
if (_glDeleteProgram != nullptr) {
|
if (_glDeleteProgram != nullptr) {
|
||||||
_glDeleteProgram(this->vid_program);
|
_glDeleteProgram(this->vid_program);
|
||||||
|
_glDeleteProgram(this->pal_program);
|
||||||
}
|
}
|
||||||
if (_glDeleteVertexArrays != nullptr) _glDeleteVertexArrays(1, &this->vao_quad);
|
if (_glDeleteVertexArrays != nullptr) _glDeleteVertexArrays(1, &this->vao_quad);
|
||||||
if (_glDeleteBuffers != nullptr) {
|
if (_glDeleteBuffers != nullptr) {
|
||||||
|
@ -358,6 +375,7 @@ OpenGLBackend::~OpenGLBackend()
|
||||||
_glDeleteBuffers(1, &this->vid_pbo);
|
_glDeleteBuffers(1, &this->vid_pbo);
|
||||||
}
|
}
|
||||||
glDeleteTextures(1, &this->vid_texture);
|
glDeleteTextures(1, &this->vid_texture);
|
||||||
|
glDeleteTextures(1, &this->pal_texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -385,6 +403,9 @@ const char *OpenGLBackend::Init()
|
||||||
if (!IsOpenGLVersionAtLeast(1, 3)) return "OpenGL version >= 1.3 required";
|
if (!IsOpenGLVersionAtLeast(1, 3)) return "OpenGL version >= 1.3 required";
|
||||||
/* Check for non-power-of-two texture support. */
|
/* Check for non-power-of-two texture support. */
|
||||||
if (!IsOpenGLVersionAtLeast(2, 0) && !IsOpenGLExtensionSupported("GL_ARB_texture_non_power_of_two")) return "Non-power-of-two textures not supported";
|
if (!IsOpenGLVersionAtLeast(2, 0) && !IsOpenGLExtensionSupported("GL_ARB_texture_non_power_of_two")) return "Non-power-of-two textures not supported";
|
||||||
|
/* Check for single element texture formats. */
|
||||||
|
if (!IsOpenGLVersionAtLeast(3, 0) && !IsOpenGLExtensionSupported("GL_ARB_texture_rg")) return "Single element texture formats not supported";
|
||||||
|
if (!BindTextureExtensions()) return "Failed to bind texture extension functions";
|
||||||
/* Check for vertex buffer objects. */
|
/* Check for vertex buffer objects. */
|
||||||
if (!IsOpenGLVersionAtLeast(1, 5) && !IsOpenGLExtensionSupported("ARB_vertex_buffer_object")) return "Vertex buffer objects not supported";
|
if (!IsOpenGLVersionAtLeast(1, 5) && !IsOpenGLExtensionSupported("ARB_vertex_buffer_object")) return "Vertex buffer objects not supported";
|
||||||
if (!BindVBOExtension()) return "Failed to bind VBO extension functions";
|
if (!BindVBOExtension()) return "Failed to bind VBO extension functions";
|
||||||
|
@ -413,10 +434,31 @@ const char *OpenGLBackend::Init()
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
if (glGetError() != GL_NO_ERROR) return "Can't generate video buffer texture";
|
if (glGetError() != GL_NO_ERROR) return "Can't generate video buffer texture";
|
||||||
|
|
||||||
/* Bind texture to shader program. */
|
/* Setup palette texture. */
|
||||||
|
glGenTextures(1, &this->pal_texture);
|
||||||
|
glBindTexture(GL_TEXTURE_1D, this->pal_texture);
|
||||||
|
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||||
|
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA8, 256, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, nullptr);
|
||||||
|
glBindTexture(GL_TEXTURE_1D, 0);
|
||||||
|
if (glGetError() != GL_NO_ERROR) return "Can't generate palette lookup texture";
|
||||||
|
|
||||||
|
/* Bind uniforms in RGB rendering shader program. */
|
||||||
GLint tex_location = _glGetUniformLocation(this->vid_program, "colour_tex");
|
GLint tex_location = _glGetUniformLocation(this->vid_program, "colour_tex");
|
||||||
|
GLint palette_location = _glGetUniformLocation(this->vid_program, "palette");
|
||||||
_glUseProgram(this->vid_program);
|
_glUseProgram(this->vid_program);
|
||||||
_glUniform1i(tex_location, 0); // Texture unit 0.
|
_glUniform1i(tex_location, 0); // Texture unit 0.
|
||||||
|
_glUniform1i(palette_location, 1); // Texture unit 1.
|
||||||
|
|
||||||
|
/* Bind uniforms in palette rendering shader program. */
|
||||||
|
tex_location = _glGetUniformLocation(this->pal_program, "colour_tex");
|
||||||
|
palette_location = _glGetUniformLocation(this->pal_program, "palette");
|
||||||
|
_glUseProgram(this->pal_program);
|
||||||
|
_glUniform1i(tex_location, 0); // Texture unit 0.
|
||||||
|
_glUniform1i(palette_location, 1); // Texture unit 1.
|
||||||
|
|
||||||
/* Create pixel buffer object as video buffer storage. */
|
/* Create pixel buffer object as video buffer storage. */
|
||||||
_glGenBuffers(1, &this->vid_pbo);
|
_glGenBuffers(1, &this->vid_pbo);
|
||||||
|
@ -525,27 +567,42 @@ bool OpenGLBackend::InitShaders()
|
||||||
_glCompileShader(vert_shader);
|
_glCompileShader(vert_shader);
|
||||||
if (!VerifyShader(vert_shader)) return false;
|
if (!VerifyShader(vert_shader)) return false;
|
||||||
|
|
||||||
/* Create fragment shader. */
|
/* Create fragment shader for plain RGBA. */
|
||||||
GLuint frag_shader = _glCreateShader(GL_FRAGMENT_SHADER);
|
GLuint frag_shader_rgb = _glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
_glShaderSource(frag_shader, glsl_150 ? lengthof(_frag_shader_direct_150) : lengthof(_frag_shader_direct), glsl_150 ? _frag_shader_direct_150 : _frag_shader_direct, nullptr);
|
_glShaderSource(frag_shader_rgb, glsl_150 ? lengthof(_frag_shader_direct_150) : lengthof(_frag_shader_direct), glsl_150 ? _frag_shader_direct_150 : _frag_shader_direct, nullptr);
|
||||||
_glCompileShader(frag_shader);
|
_glCompileShader(frag_shader_rgb);
|
||||||
if (!VerifyShader(frag_shader)) return false;
|
if (!VerifyShader(frag_shader_rgb)) return false;
|
||||||
|
|
||||||
|
/* Create fragment shader for paletted only. */
|
||||||
|
GLuint frag_shader_pal = _glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
_glShaderSource(frag_shader_pal, glsl_150 ? lengthof(_frag_shader_palette_150) : lengthof(_frag_shader_palette), glsl_150 ? _frag_shader_palette_150 : _frag_shader_palette, nullptr);
|
||||||
|
_glCompileShader(frag_shader_pal);
|
||||||
|
if (!VerifyShader(frag_shader_pal)) return false;
|
||||||
|
|
||||||
/* Link shaders to program. */
|
/* Link shaders to program. */
|
||||||
this->vid_program = _glCreateProgram();
|
this->vid_program = _glCreateProgram();
|
||||||
_glAttachShader(this->vid_program, vert_shader);
|
_glAttachShader(this->vid_program, vert_shader);
|
||||||
_glAttachShader(this->vid_program, frag_shader);
|
_glAttachShader(this->vid_program, frag_shader_rgb);
|
||||||
|
|
||||||
|
this->pal_program = _glCreateProgram();
|
||||||
|
_glAttachShader(this->pal_program, vert_shader);
|
||||||
|
_glAttachShader(this->pal_program, frag_shader_pal);
|
||||||
|
|
||||||
if (glsl_150) {
|
if (glsl_150) {
|
||||||
/* Bind fragment shader outputs. */
|
/* Bind fragment shader outputs. */
|
||||||
_glBindFragDataLocation(this->vid_program, 0, "colour");
|
_glBindFragDataLocation(this->vid_program, 0, "colour");
|
||||||
|
_glBindFragDataLocation(this->pal_program, 0, "colour");
|
||||||
}
|
}
|
||||||
|
|
||||||
_glLinkProgram(this->vid_program);
|
_glLinkProgram(this->vid_program);
|
||||||
if (!VerifyProgram(this->vid_program)) return false;
|
if (!VerifyProgram(this->vid_program)) return false;
|
||||||
|
|
||||||
|
_glLinkProgram(this->pal_program);
|
||||||
|
if (!VerifyProgram(this->pal_program)) return false;
|
||||||
|
|
||||||
_glDeleteShader(vert_shader);
|
_glDeleteShader(vert_shader);
|
||||||
_glDeleteShader(frag_shader);
|
_glDeleteShader(frag_shader_rgb);
|
||||||
|
_glDeleteShader(frag_shader_pal);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -561,26 +618,55 @@ bool OpenGLBackend::Resize(int w, int h, bool force)
|
||||||
{
|
{
|
||||||
if (!force && _screen.width == w && _screen.height == h) return false;
|
if (!force && _screen.width == w && _screen.height == h) return false;
|
||||||
|
|
||||||
|
int bpp = BlitterFactory::GetCurrentBlitter()->GetScreenDepth();
|
||||||
|
int pitch = bpp != 32 ? Align(w, 4) : w;
|
||||||
|
|
||||||
glViewport(0, 0, w, h);
|
glViewport(0, 0, w, h);
|
||||||
|
|
||||||
/* Re-allocate video buffer texture and backing store. */
|
/* Re-allocate video buffer texture and backing store. */
|
||||||
_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->vid_pbo);
|
_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->vid_pbo);
|
||||||
_glBufferData(GL_PIXEL_UNPACK_BUFFER, w * h * 4, nullptr, GL_DYNAMIC_READ); // Buffer content has to persist from frame to frame and is read back by the blitter, which means a READ usage hint.
|
_glBufferData(GL_PIXEL_UNPACK_BUFFER, pitch * h * bpp / 8, nullptr, GL_DYNAMIC_READ); // Buffer content has to persist from frame to frame and is read back by the blitter, which means a READ usage hint.
|
||||||
_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||||
|
|
||||||
|
_glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, this->vid_texture);
|
glBindTexture(GL_TEXTURE_2D, this->vid_texture);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, nullptr);
|
switch (bpp) {
|
||||||
|
case 8:
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, nullptr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, nullptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
/* Set new viewport. */
|
/* Set new viewport. */
|
||||||
_screen.height = h;
|
_screen.height = h;
|
||||||
_screen.width = w;
|
_screen.width = w;
|
||||||
_screen.pitch = w;
|
_screen.pitch = pitch;
|
||||||
_screen.dst_ptr = nullptr;
|
_screen.dst_ptr = nullptr;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the stored palette.
|
||||||
|
* @param pal Palette array with at least 256 elements.
|
||||||
|
* @param first First entry to update.
|
||||||
|
* @param length Number of entries to update.
|
||||||
|
*/
|
||||||
|
void OpenGLBackend::UpdatePalette(const Colour *pal, uint first, uint length)
|
||||||
|
{
|
||||||
|
assert(first + length <= 256);
|
||||||
|
|
||||||
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||||
|
_glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||||
|
_glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_1D, this->pal_texture);
|
||||||
|
glTexSubImage1D(GL_TEXTURE_1D, 0, first, length, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pal + first);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render video buffer to the screen.
|
* Render video buffer to the screen.
|
||||||
*/
|
*/
|
||||||
|
@ -589,8 +675,11 @@ void OpenGLBackend::Paint()
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
/* Blit video buffer to screen. */
|
/* Blit video buffer to screen. */
|
||||||
|
_glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, this->vid_texture);
|
glBindTexture(GL_TEXTURE_2D, this->vid_texture);
|
||||||
_glUseProgram(this->vid_program);
|
_glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_1D, this->pal_texture);
|
||||||
|
_glUseProgram(BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 8 ? this->pal_program : this->vid_program);
|
||||||
_glBindVertexArray(this->vao_quad);
|
_glBindVertexArray(this->vao_quad);
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
}
|
}
|
||||||
|
@ -618,9 +707,18 @@ void OpenGLBackend::ReleaseVideoBuffer(const Rect &update_rect)
|
||||||
|
|
||||||
/* Update changed rect of the video buffer texture. */
|
/* Update changed rect of the video buffer texture. */
|
||||||
if (!IsEmptyRect(update_rect)) {
|
if (!IsEmptyRect(update_rect)) {
|
||||||
|
_glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, this->vid_texture);
|
glBindTexture(GL_TEXTURE_2D, this->vid_texture);
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, _screen.pitch);
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, _screen.pitch);
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, update_rect.left, update_rect.top, update_rect.right - update_rect.left, update_rect.bottom - update_rect.top, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, (GLvoid *)(size_t)(update_rect.top * _screen.pitch * 4 + update_rect.left * 4));
|
switch (BlitterFactory::GetCurrentBlitter()->GetScreenDepth()) {
|
||||||
|
case 8:
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0, update_rect.left, update_rect.top, update_rect.right - update_rect.left, update_rect.bottom - update_rect.top, GL_RED, GL_UNSIGNED_BYTE, (GLvoid *)(size_t)(update_rect.top * _screen.pitch + update_rect.left));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0, update_rect.left, update_rect.top, update_rect.right - update_rect.left, update_rect.bottom - update_rect.top, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, (GLvoid *)(size_t)(update_rect.top * _screen.pitch * 4 + update_rect.left * 4));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include "../core/alloc_type.hpp"
|
#include "../core/alloc_type.hpp"
|
||||||
#include "../core/geometry_type.hpp"
|
#include "../core/geometry_type.hpp"
|
||||||
|
#include "../gfx_type.h"
|
||||||
|
|
||||||
typedef void (*OGLProc)();
|
typedef void (*OGLProc)();
|
||||||
typedef OGLProc (*GetOGLProcAddressProc)(const char *proc);
|
typedef OGLProc (*GetOGLProcAddressProc)(const char *proc);
|
||||||
|
@ -28,9 +29,11 @@ private:
|
||||||
|
|
||||||
GLuint vid_pbo; ///< Pixel buffer object storing the memory used for the video driver to draw to.
|
GLuint vid_pbo; ///< Pixel buffer object storing the memory used for the video driver to draw to.
|
||||||
GLuint vid_texture; ///< Texture handle for the video buffer texture.
|
GLuint vid_texture; ///< Texture handle for the video buffer texture.
|
||||||
GLuint vid_program; ///< Shader program for rendering the video buffer.
|
GLuint vid_program; ///< Shader program for rendering a RGBA video buffer.
|
||||||
|
GLuint pal_program; ///< Shader program for rendering a paletted video buffer.
|
||||||
GLuint vao_quad; ///< Vertex array object storing the rendering state for the fullscreen quad.
|
GLuint vao_quad; ///< Vertex array object storing the rendering state for the fullscreen quad.
|
||||||
GLuint vbo_quad; ///< Vertex buffer with a fullscreen quad.
|
GLuint vbo_quad; ///< Vertex buffer with a fullscreen quad.
|
||||||
|
GLuint pal_texture; ///< Palette lookup texture.
|
||||||
|
|
||||||
OpenGLBackend();
|
OpenGLBackend();
|
||||||
~OpenGLBackend();
|
~OpenGLBackend();
|
||||||
|
@ -47,6 +50,7 @@ public:
|
||||||
static const char *Create(GetOGLProcAddressProc get_proc);
|
static const char *Create(GetOGLProcAddressProc get_proc);
|
||||||
static void Destroy();
|
static void Destroy();
|
||||||
|
|
||||||
|
void UpdatePalette(const Colour *pal, uint first, uint length);
|
||||||
bool Resize(int w, int h, bool force = false);
|
bool Resize(int w, int h, bool force = false);
|
||||||
void Paint();
|
void Paint();
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,15 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Has this video driver an efficient code path for palette animated 8-bpp sprites?
|
||||||
|
* @return True if the driver has an efficient code path for 8-bpp.
|
||||||
|
*/
|
||||||
|
virtual bool HasEfficient8Bpp() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An edit box lost the input focus. Abort character compositing if necessary.
|
* An edit box lost the input focus. Abort character compositing if necessary.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1417,7 +1417,7 @@ static FVideoDriver_Win32OpenGL iFVideoDriver_Win32OpenGL;
|
||||||
|
|
||||||
const char *VideoDriver_Win32OpenGL::Start(const StringList ¶m)
|
const char *VideoDriver_Win32OpenGL::Start(const StringList ¶m)
|
||||||
{
|
{
|
||||||
if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 32) return "Only 32bpp blitters supported";
|
if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 0) return "Only real blitters supported";
|
||||||
|
|
||||||
Dimension old_res = _cur_resolution; // Save current screen resolution in case of errors, as MakeWindow invalidates it.
|
Dimension old_res = _cur_resolution; // Save current screen resolution in case of errors, as MakeWindow invalidates it.
|
||||||
this->vsync = GetDriverParamBool(param, "vsync");
|
this->vsync = GetDriverParamBool(param, "vsync");
|
||||||
|
@ -1565,6 +1565,9 @@ void VideoDriver_Win32OpenGL::Paint()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Blitter::PALETTE_ANIMATION_VIDEO_BACKEND:
|
case Blitter::PALETTE_ANIMATION_VIDEO_BACKEND:
|
||||||
|
OpenGLBackend::Get()->UpdatePalette(_local_palette.palette, _local_palette.first_dirty, _local_palette.count_dirty);
|
||||||
|
break;
|
||||||
|
|
||||||
case Blitter::PALETTE_ANIMATION_NONE:
|
case Blitter::PALETTE_ANIMATION_NONE:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -138,6 +138,8 @@ public:
|
||||||
|
|
||||||
bool AfterBlitterChange() override;
|
bool AfterBlitterChange() override;
|
||||||
|
|
||||||
|
bool HasEfficient8Bpp() const override { return true; }
|
||||||
|
|
||||||
const char *GetName() const override { return "win32-opengl"; }
|
const char *GetName() const override { return "win32-opengl"; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
Loading…
Reference in New Issue