implement openglpp output

This commit is contained in:
Anton Shepelev 2021-01-19 23:36:35 -05:00 committed by Wengier
parent ebb3e54243
commit 5e5d7d1bf4
9 changed files with 161 additions and 61 deletions

View File

@ -1,4 +1,9 @@
0.83.10 0.83.10
- DOSBox-X now natively supports the pixel-perfect
scaling! Set output=openglpp in [sdl] section to
enable this output. Alternatively, the output can
be selected from the menu ("Video" => "Output" =>
"OpenGL perfect") at run-time. (ant_222 & Wengier)
- Added abliity to resolve file paths that include - Added abliity to resolve file paths that include
environment variables on Windows or tildes (~) on environment variables on Windows or tildes (~) on
other platforms for various options in the config other platforms for various options in the config
@ -61,7 +66,9 @@
"config -set ttf.cols=100". (Wengier) "config -set ttf.cols=100". (Wengier)
- You can now supply a ZIP/7Z file as a parameter to - You can now supply a ZIP/7Z file as a parameter to
DOSBox-X directly so that it will be mounted as C: DOSBox-X directly so that it will be mounted as C:
drive when DOSBox-X starts. (Wengeir) drive when DOSBox-X starts. (Wengier)
- Fixed the DOSBox-X window size when restoring from
a maximized window in SDL2 builds. (Wengier)
- Fixed Ctrl+C not working in GNU ed. (Wengier) - Fixed Ctrl+C not working in GNU ed. (Wengier)
- Fixed large ISO images (>2GB) unable to be mounted - Fixed large ISO images (>2GB) unable to be mounted
using IMGMOUNT command. (Wengier) using IMGMOUNT command. (Wengier)

View File

@ -124,6 +124,7 @@ struct SDL_Block {
bool prevent_fullscreen = false; bool prevent_fullscreen = false;
bool lazy_fullscreen_req = false; bool lazy_fullscreen_req = false;
bool doublebuf = false; bool doublebuf = false;
bool isperfect = false;
SCREEN_TYPES type = (SCREEN_TYPES)0; SCREEN_TYPES type = (SCREEN_TYPES)0;
SCREEN_TYPES want_type = (SCREEN_TYPES)0; SCREEN_TYPES want_type = (SCREEN_TYPES)0;
} desktop; } desktop;

View File

@ -1361,7 +1361,7 @@ void DOSBOX_SetupConfigSections(void) {
const char* switchoutputs[] = { const char* switchoutputs[] = {
"auto", "surface", "auto", "surface",
#if C_OPENGL #if C_OPENGL
"opengl", "openglnb", "openglhq", "opengl", "openglnb", "openglhq", "openglpp",
#endif #endif
#if C_DIRECT3D #if C_DIRECT3D
"direct3d", "direct3d",
@ -2317,7 +2317,8 @@ void DOSBOX_SetupConfigSections(void) {
Pmulti->Set_help("Scaler used to enlarge/enhance low resolution modes. If 'forced' is appended,\n" Pmulti->Set_help("Scaler used to enlarge/enhance low resolution modes. If 'forced' is appended,\n"
"then the scaler will be used even if the result might not be desired.\n" "then the scaler will be used even if the result might not be desired.\n"
"To fit a scaler in the resolution used at full screen may require a border or side bars.\n" "To fit a scaler in the resolution used at full screen may require a border or side bars.\n"
"To fill the screen entirely, depending on your hardware, a different scaler/fullresolution might work."); "To fill the screen entirely, depending on your hardware, a different scaler/fullresolution might work.\n"
"Scalers should work with most output options, but they are ignored for openglpp and TrueType font output.");
Pmulti->SetBasic(true); Pmulti->SetBasic(true);
Pstring = Pmulti->GetSection()->Add_string("type",Property::Changeable::Always,"normal2x"); Pstring = Pmulti->GetSection()->Add_string("type",Property::Changeable::Always,"normal2x");
Pstring->Set_values(scalers); Pstring->Set_values(scalers);

View File

@ -325,6 +325,7 @@ static const char *def_menu_video_output[] =
#if defined(C_OPENGL) && !defined(HX_DOS) #if defined(C_OPENGL) && !defined(HX_DOS)
"output_opengl", "output_opengl",
"output_openglnb", "output_openglnb",
"output_openglpp",
#endif #endif
#if defined(USE_TTF) #if defined(USE_TTF)
"output_ttf", "output_ttf",

View File

@ -469,6 +469,9 @@ void RENDER_Reset( void ) {
} }
} }
if( sdl.desktop.isperfect ) /* Handle scaling if no pixel-perfect mode */
goto forcenormal;
if ((dblh && dblw) || (render.scale.forced && dblh == dblw/*this branch works best with equal scaling in both directions*/)) { if ((dblh && dblw) || (render.scale.forced && dblh == dblw/*this branch works best with equal scaling in both directions*/)) {
/* Initialize always working defaults */ /* Initialize always working defaults */
if (render.scale.size == 2) if (render.scale.size == 2)
@ -576,7 +579,8 @@ void RENDER_Reset( void ) {
else else
simpleBlock = &ScaleNormalDh; simpleBlock = &ScaleNormalDh;
} }
} else { }
if( simpleBlock == NULL && complexBlock == NULL ) {
forcenormal: forcenormal:
complexBlock = 0; complexBlock = 0;
if(scalerOpGray==render.scale.op){ if(scalerOpGray==render.scale.op){

View File

@ -3541,11 +3541,13 @@ void OUTPUT_TTF_Select(int fsize=-1) {
const char *outputstr=render_section->Get_string("ttf.outputswitch"); const char *outputstr=render_section->Get_string("ttf.outputswitch");
#if C_DIRECT3D #if C_DIRECT3D
if (!strcasecmp(outputstr, "direct3d")) if (!strcasecmp(outputstr, "direct3d"))
switchoutput = 5; switchoutput = 6;
else else
#endif #endif
#if C_OPENGL #if C_OPENGL
if (!strcasecmp(outputstr, "openglnb")) if (!strcasecmp(outputstr, "openglpp"))
switchoutput = 5;
else if (!strcasecmp(outputstr, "openglnb"))
switchoutput = 4; switchoutput = 4;
else if (!strcasecmp(outputstr, "opengl")||!strcasecmp(outputstr, "openglnq")) else if (!strcasecmp(outputstr, "opengl")||!strcasecmp(outputstr, "openglnq"))
switchoutput = 3; switchoutput = 3;
@ -3679,6 +3681,7 @@ void change_output(int output) {
Section_prop * section=static_cast<Section_prop *>(sec); Section_prop * section=static_cast<Section_prop *>(sec);
sdl.overscan_width=(unsigned int)section->Get_int("overscan"); sdl.overscan_width=(unsigned int)section->Get_int("overscan");
UpdateOverscanMenu(); UpdateOverscanMenu();
sdl.desktop.isperfect = false; /* Reset before selection */
switch (output) { switch (output) {
case 0: case 0:
@ -3692,37 +3695,41 @@ void change_output(int output) {
case 3: case 3:
#if C_OPENGL #if C_OPENGL
change_output(2); change_output(2);
OUTPUT_OPENGL_Select(); OUTPUT_OPENGL_Select(GLBilinear);
sdl_opengl.bilinear = true;
#endif #endif
break; break;
case 4: case 4:
#if C_OPENGL #if C_OPENGL
change_output(2); change_output(2);
OUTPUT_OPENGL_Select(); OUTPUT_OPENGL_Select(GLNearest);
sdl_opengl.bilinear = false; //NB
#endif #endif
break; break;
#if C_DIRECT3D
case 5: case 5:
#if C_OPENGL
change_output(2);
OUTPUT_OPENGL_Select(GLPerfect);
#endif
break;
#if C_DIRECT3D
case 6:
OUTPUT_DIRECT3D_Select(); OUTPUT_DIRECT3D_Select();
break; break;
#endif #endif
case 6:
break;
case 7: case 7:
// do not set want_type
break; break;
case 8: case 8:
// do not set want_type
break;
case 9:
#if C_DIRECT3D #if C_DIRECT3D
if (sdl.desktop.want_type == SCREEN_DIRECT3D) if (sdl.desktop.want_type == SCREEN_DIRECT3D)
OUTPUT_DIRECT3D_Select(); OUTPUT_DIRECT3D_Select();
#endif #endif
break; break;
#if defined(USE_TTF) #if defined(USE_TTF)
case 9:
OUTPUT_TTF_Select();
case 10: case 10:
OUTPUT_TTF_Select();
case 11:
sdl.desktop.want_type = SCREEN_TTF; sdl.desktop.want_type = SCREEN_TTF;
ttf.inUse = true; ttf.inUse = true;
break; break;
@ -5201,7 +5208,7 @@ static void GUI_StartUp() {
if (sdl_xbrz.enable) { if (sdl_xbrz.enable) {
// xBRZ requirements // xBRZ requirements
if ((output != "surface") && (output != "direct3d") && (output != "opengl") && (output != "openglhq") && (output != "openglnb")) if ((output != "surface") && (output != "direct3d") && (output != "opengl") && (output != "openglhq") && (output != "openglnb") && (output != "openglpp"))
output = "surface"; output = "surface";
} }
#endif #endif
@ -5219,6 +5226,8 @@ static void GUI_StartUp() {
#endif #endif
} }
// FIXME: this selection of output is duplicated in change_output:
sdl.desktop.isperfect = false; /* Reset before selection */
if (output == "surface") if (output == "surface")
{ {
OUTPUT_SURFACE_Select(); OUTPUT_SURFACE_Select();
@ -5230,13 +5239,15 @@ static void GUI_StartUp() {
} }
else if (output == "opengl" || output == "openglhq") else if (output == "opengl" || output == "openglhq")
{ {
OUTPUT_OPENGL_Select(); OUTPUT_OPENGL_Select(GLBilinear);
sdl_opengl.bilinear = true;
} }
else if (output == "openglnb") else if (output == "openglnb")
{ {
OUTPUT_OPENGL_Select(); OUTPUT_OPENGL_Select(GLNearest);
sdl_opengl.bilinear = false; }
else if (output == "openglpp")
{
OUTPUT_OPENGL_Select(GLPerfect);
#endif #endif
#if C_DIRECT3D #if C_DIRECT3D
} }
@ -5568,6 +5579,10 @@ void GFX_HandleVideoResize(int width, int height) {
} }
else { else {
UpdateWindowDimensions(); UpdateWindowDimensions();
if (window_was_maximized && !menu.maxwindow) {
userResizeWindowWidth = currentWindowWidth==sdl.surface->w?0:(unsigned int)currentWindowWidth;
userResizeWindowHeight = currentWindowHeight==sdl.surface->h?0:(unsigned int)currentWindowHeight;
}
} }
/* TODO: Only if FULLSCREEN_DESKTOP */ /* TODO: Only if FULLSCREEN_DESKTOP */
@ -6727,10 +6742,10 @@ void* GetSetSDLValue(int isget, std::string& target, void* setval) {
if (isget) return (void*) sdl.wait_on_error; if (isget) return (void*) sdl.wait_on_error;
else sdl.wait_on_error = setval; else sdl.wait_on_error = setval;
} }
else if (target == "opengl.bilinear") { else if (target == "opengl.kind") {
#if C_OPENGL #if C_OPENGL
if (isget) return (void*) sdl_opengl.bilinear; if (isget) return (void*) sdl_opengl.kind;
else sdl_opengl.bilinear = setval; else sdl_opengl.kind = (GLKind)(intptr_t)setval;
#else #else
if (isget) return (void*) 0; if (isget) return (void*) 0;
#endif #endif
@ -7581,7 +7596,7 @@ void SDL_SetupConfigSection() {
const char* outputs[] = { const char* outputs[] = {
"default", "surface", "overlay", "default", "surface", "overlay",
#if C_OPENGL #if C_OPENGL
"opengl", "openglnb", "openglhq", "opengl", "openglnb", "openglhq", "openglpp",
#endif #endif
"ddraw", "ddraw",
#if C_DIRECT3D #if C_DIRECT3D
@ -10061,7 +10076,7 @@ bool overscan_menu_callback(DOSBoxMenu * const menu,DOSBoxMenu::item * const men
sprintf(tmp,"%d",f); sprintf(tmp,"%d",f);
SetVal("sdl", "overscan", tmp); SetVal("sdl", "overscan", tmp);
change_output(7); change_output(8);
return true; return true;
} }
@ -10086,7 +10101,7 @@ bool vsync_menu_callback(DOSBoxMenu * const menu,DOSBoxMenu::item * const menuit
SetVal("vsync", "vsyncmode", val); SetVal("vsync", "vsyncmode", val);
void change_output(int output); void change_output(int output);
change_output(8); change_output(9);
VGA_Vsync VGA_Vsync_Decode(const char *vsyncmodestr); VGA_Vsync VGA_Vsync_Decode(const char *vsyncmodestr);
void VGA_VsyncUpdateMode(VGA_Vsync vsyncmode); void VGA_VsyncUpdateMode(VGA_Vsync vsyncmode);
@ -10126,20 +10141,26 @@ bool output_menu_callback(DOSBoxMenu * const menu,DOSBoxMenu::item * const menui
} }
else if (!strcmp(what,"opengl")) { else if (!strcmp(what,"opengl")) {
#if C_OPENGL #if C_OPENGL
if (sdl.desktop.want_type == SCREEN_OPENGL && sdl_opengl.bilinear) return true; if (sdl.desktop.want_type == SCREEN_OPENGL && sdl_opengl.kind == GLBilinear) return true;
change_output(3); change_output(3);
#endif #endif
} }
else if (!strcmp(what,"openglnb")) { else if (!strcmp(what,"openglnb")) {
#if C_OPENGL #if C_OPENGL
if (sdl.desktop.want_type == SCREEN_OPENGL && !sdl_opengl.bilinear) return true; if (sdl.desktop.want_type == SCREEN_OPENGL && sdl_opengl.kind == GLNearest) return true;
change_output(4); change_output(4);
#endif
}
else if (!strcmp(what,"openglpp")) {
#if C_OPENGL
if (sdl.desktop.want_type == SCREEN_OPENGL && sdl_opengl.kind == GLPerfect) return true;
change_output(5);
#endif #endif
} }
else if (!strcmp(what,"direct3d")) { else if (!strcmp(what,"direct3d")) {
#if C_DIRECT3D #if C_DIRECT3D
if (sdl.desktop.want_type == SCREEN_DIRECT3D) return true; if (sdl.desktop.want_type == SCREEN_DIRECT3D) return true;
change_output(5); change_output(6);
#endif #endif
} }
else if (!strcmp(what,"ttf")) { else if (!strcmp(what,"ttf")) {
@ -10162,7 +10183,7 @@ bool output_menu_callback(DOSBoxMenu * const menu,DOSBoxMenu::item * const menui
putenv("SDL_VIDEO_CENTERED=center"); putenv("SDL_VIDEO_CENTERED=center");
#endif #endif
firstset=false; firstset=false;
change_output(9); change_output(10);
#endif #endif
} }
if (reset) RENDER_Reset(); if (reset) RENDER_Reset();
@ -11150,8 +11171,9 @@ void OutputSettingMenuUpdate(void) {
mainMenu.get_item("output_direct3d").check(sdl.desktop.want_type == SCREEN_DIRECT3D).refresh_item(mainMenu); mainMenu.get_item("output_direct3d").check(sdl.desktop.want_type == SCREEN_DIRECT3D).refresh_item(mainMenu);
#endif #endif
#if C_OPENGL #if C_OPENGL
mainMenu.get_item("output_opengl").check(sdl.desktop.want_type == SCREEN_OPENGL && sdl_opengl.bilinear).refresh_item(mainMenu); mainMenu.get_item("output_opengl").check(sdl.desktop.want_type == SCREEN_OPENGL && sdl_opengl.kind == GLBilinear).refresh_item(mainMenu);
mainMenu.get_item("output_openglnb").check(sdl.desktop.want_type == SCREEN_OPENGL && !sdl_opengl.bilinear).refresh_item(mainMenu); mainMenu.get_item("output_openglnb").check(sdl.desktop.want_type == SCREEN_OPENGL && sdl_opengl.kind == GLNearest).refresh_item(mainMenu);
mainMenu.get_item("output_openglpp").check(sdl.desktop.want_type == SCREEN_OPENGL && sdl_opengl.kind == GLPerfect).refresh_item(mainMenu);
#endif #endif
#if defined(USE_TTF) #if defined(USE_TTF)
mainMenu.get_item("output_ttf").check(sdl.desktop.want_type == SCREEN_TTF).refresh_item(mainMenu); mainMenu.get_item("output_ttf").check(sdl.desktop.want_type == SCREEN_TTF).refresh_item(mainMenu);
@ -12024,7 +12046,9 @@ int main(int argc, char* argv[]) SDL_MAIN_NOEXCEPT {
set_callback_function(output_menu_callback); set_callback_function(output_menu_callback);
mainMenu.alloc_item(DOSBoxMenu::item_type_id,"output_opengl").set_text("OpenGL"). mainMenu.alloc_item(DOSBoxMenu::item_type_id,"output_opengl").set_text("OpenGL").
set_callback_function(output_menu_callback); set_callback_function(output_menu_callback);
mainMenu.alloc_item(DOSBoxMenu::item_type_id,"output_openglnb").set_text("OpenGL NB"). mainMenu.alloc_item(DOSBoxMenu::item_type_id,"output_openglnb").set_text("OpenGL nearest").
set_callback_function(output_menu_callback);
mainMenu.alloc_item(DOSBoxMenu::item_type_id,"output_openglpp").set_text("OpenGL perfect").
set_callback_function(output_menu_callback); set_callback_function(output_menu_callback);
#if defined(USE_TTF) #if defined(USE_TTF)
mainMenu.alloc_item(DOSBoxMenu::item_type_id,"output_ttf").set_text("TrueType font"). mainMenu.alloc_item(DOSBoxMenu::item_type_id,"output_ttf").set_text("TrueType font").

View File

@ -1145,14 +1145,16 @@ void ttf_switch_off(bool ss=true) {
output = "opengl"; output = "opengl";
else if (switchoutput==4) else if (switchoutput==4)
output = "openglnb"; output = "openglnb";
else if (switchoutput==5)
output = "openglpp";
#endif #endif
#if C_DIRECT3D #if C_DIRECT3D
else if (switchoutput==5) else if (switchoutput==6)
output = "direct3d"; output = "direct3d";
#endif #endif
else { else {
#if C_DIRECT3D #if C_DIRECT3D
out = 5; out = 6;
output = "direct3d"; output = "direct3d";
#elif C_OPENGL #elif C_OPENGL
out = 3; out = 3;

View File

@ -7,7 +7,10 @@
#include <sys/types.h> #include <sys/types.h>
#include <assert.h> #include <assert.h>
#include <math.h> #include <math.h>
extern "C" {
#include "ppscale.h"
#include "ppscale.c"
}
#include "dosbox.h" #include "dosbox.h"
#include <output/output_opengl.h> #include <output/output_opengl.h>
@ -94,6 +97,48 @@ int Voodoo_OGL_GetWidth();
int Voodoo_OGL_GetHeight(); int Voodoo_OGL_GetHeight();
bool Voodoo_OGL_Active(); bool Voodoo_OGL_Active();
static void PPScale (
uint16_t fixed_w , uint16_t fixed_h,
uint16_t* window_w, uint16_t* window_h )
{
int sx, sy, orig_w, orig_h, min_w, min_h;
double par, par_sq;
orig_w = min_w = render.src.width;
orig_h = min_h = render.src.height;
par = ( double) orig_w / orig_h * 3 / 4;
/* HACK: because REDNER_SetSize() does not set dblw and dblh correctly: */
/* E.g. in 360x360 mode DOXBox will wrongly allocate a 720x360 area. I */
/* therefore calculate square-pixel proportions par_sq myself: */
if( par < 0.707 ) { par_sq = 0.5; min_w *= 2; }
else if( par > 1.414 ) { par_sq = 2.0; min_h *= 2; }
else par_sq = 1.0;
if( !render.aspect ) par = par_sq;
*window_w = fixed_w; *window_h = fixed_h;
/* Handle non-fixed resolutions and ensure a sufficient window size: */
if( fixed_w < min_w ) fixed_w = *window_w = min_w;
if( fixed_h < min_h ) fixed_h = *window_h = min_h;
pp_getscale(
orig_w , orig_h , par ,
fixed_w, fixed_h, 1.14,
&sx , &sy );
sdl.clip.w = orig_w * sx;
sdl.clip.h = orig_h * sy;
sdl.clip.x = (*window_w - sdl.clip.w) / 2;
sdl.clip.y = (*window_h - sdl.clip.h) / 2;
LOG_MSG( "OpenGL PP: [%ix%i]: %ix%i (%3.2f) -> [%ix%i] -> %ix%i (%3.2f)",
fixed_w, fixed_h,
orig_w, orig_h, par,
sx, sy,
sdl.clip.w, sdl.clip.h, (double)sy/sx );
}
static SDL_Surface* SetupSurfaceScaledOpenGL(uint32_t sdl_flags, uint32_t bpp) static SDL_Surface* SetupSurfaceScaledOpenGL(uint32_t sdl_flags, uint32_t bpp)
{ {
uint16_t fixedWidth; uint16_t fixedWidth;
@ -161,7 +206,7 @@ retry:
LOG_MSG("menuScale=%d", scale); LOG_MSG("menuScale=%d", scale);
mainMenu.setScale((unsigned int)scale); mainMenu.setScale((unsigned int)scale);
if (mainMenu.isVisible() && !sdl.desktop.fullscreen) if (mainMenu.isVisible() && !sdl.desktop.fullscreen && fixedHeight)
fixedHeight -= mainMenu.menuBox.h; fixedHeight -= mainMenu.menuBox.h;
} }
#endif #endif
@ -172,20 +217,24 @@ retry:
/* 3Dfx openGL do not allow resize */ /* 3Dfx openGL do not allow resize */
sdl.clip.w = windowWidth = (uint16_t)Voodoo_OGL_GetWidth(); sdl.clip.w = windowWidth = (uint16_t)Voodoo_OGL_GetWidth();
sdl.clip.h = windowHeight = (uint16_t)Voodoo_OGL_GetHeight(); sdl.clip.h = windowHeight = (uint16_t)Voodoo_OGL_GetHeight();
} } else if (sdl_opengl.kind == GLPerfect ) {
else if (fixedWidth && fixedHeight) PPScale( fixedWidth, fixedHeight, &windowWidth, &windowHeight );
{ } else
sdl.clip.w = windowWidth = fixedWidth; if (fixedWidth && fixedHeight)
sdl.clip.h = windowHeight = fixedHeight; {
if (render.aspect) aspectCorrectFitClip(sdl.clip.w, sdl.clip.h, sdl.clip.x, sdl.clip.y, fixedWidth, fixedHeight); windowWidth = fixedWidth;
} windowHeight = fixedHeight;
else sdl.clip.w = windowWidth;
{ sdl.clip.h = windowHeight;
windowWidth = (uint16_t)(sdl.draw.width * sdl.draw.scalex); if (render.aspect) aspectCorrectFitClip(sdl.clip.w, sdl.clip.h, sdl.clip.x, sdl.clip.y, fixedWidth, fixedHeight);
windowHeight = (uint16_t)(sdl.draw.height * sdl.draw.scaley); }
if (render.aspect) aspectCorrectExtend(windowWidth, windowHeight); else
sdl.clip.w = windowWidth; sdl.clip.h = windowHeight; {
} windowWidth = (uint16_t)(sdl.draw.width * sdl.draw.scalex);
windowHeight = (uint16_t)(sdl.draw.height * sdl.draw.scaley);
if (render.aspect) aspectCorrectExtend(windowWidth, windowHeight);
sdl.clip.w = windowWidth; sdl.clip.h = windowHeight;
}
LOG(LOG_MISC, LOG_DEBUG)("GFX_SetSize OpenGL window=%ux%u clip=x,y,w,h=%d,%d,%d,%d", LOG(LOG_MISC, LOG_DEBUG)("GFX_SetSize OpenGL window=%ux%u clip=x,y,w,h=%d,%d,%d,%d",
(unsigned int)windowWidth, (unsigned int)windowWidth,
@ -257,7 +306,7 @@ void OUTPUT_OPENGL_Initialize()
memset(&sdl_opengl, 0, sizeof(sdl_opengl)); memset(&sdl_opengl, 0, sizeof(sdl_opengl));
} }
void OUTPUT_OPENGL_Select() void OUTPUT_OPENGL_Select( GLKind kind )
{ {
sdl.desktop.want_type = SCREEN_OPENGL; sdl.desktop.want_type = SCREEN_OPENGL;
render.aspectOffload = true; render.aspectOffload = true;
@ -285,6 +334,8 @@ void OUTPUT_OPENGL_Select()
sdl.desktop.want_type = SCREEN_SURFACE; sdl.desktop.want_type = SCREEN_SURFACE;
} else if (initgl!=2) { } else if (initgl!=2) {
initgl = 1; initgl = 1;
sdl_opengl.kind = kind;
sdl.desktop.isperfect = true;
sdl_opengl.program_object = 0; sdl_opengl.program_object = 0;
glAttachShader = (PFNGLATTACHSHADERPROC)SDL_GL_GetProcAddress("glAttachShader"); glAttachShader = (PFNGLATTACHSHADERPROC)SDL_GL_GetProcAddress("glAttachShader");
glCompileShader = (PFNGLCOMPILESHADERPROC)SDL_GL_GetProcAddress("glCompileShader"); glCompileShader = (PFNGLCOMPILESHADERPROC)SDL_GL_GetProcAddress("glCompileShader");
@ -341,7 +392,7 @@ void OUTPUT_OPENGL_Select()
Bitu OUTPUT_OPENGL_GetBestMode(Bitu flags) Bitu OUTPUT_OPENGL_GetBestMode(Bitu flags)
{ {
if (!(flags & GFX_CAN_32)) return 0; // OpenGL requires 32-bit output mode if (!(flags & GFX_CAN_32)) return 0; // OpenGL requires 32-bit output mode
flags |= GFX_SCALING; flags |= GFX_SCALING;
flags &= ~(GFX_CAN_8 | GFX_CAN_15 | GFX_CAN_16); flags &= ~(GFX_CAN_8 | GFX_CAN_15 | GFX_CAN_16);
return flags; return flags;
} }
@ -364,7 +415,7 @@ static GLuint BuildShader ( GLenum type, const char *shaderSrc ) {
} }
top += (type==GL_VERTEX_SHADER) ? "#define VERTEX 1\n":"#define FRAGMENT 1\n"; top += (type==GL_VERTEX_SHADER) ? "#define VERTEX 1\n":"#define FRAGMENT 1\n";
if (!sdl_opengl.bilinear) if (sdl_opengl.kind == GLNearest || sdl_opengl.kind == GLPerfect)
top += "#define OPENGLNB 1\n"; top += "#define OPENGLNB 1\n";
src_strings[0] = top.c_str(); src_strings[0] = top.c_str();
@ -632,8 +683,12 @@ Bitu OUTPUT_OPENGL_SetSize()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, sdl_opengl.bilinear ? GL_LINEAR : GL_NEAREST); GLint interp;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, sdl_opengl.bilinear ? GL_LINEAR : GL_NEAREST); if( sdl_opengl.kind == GLNearest || sdl_opengl.kind == GLPerfect )
interp = GL_NEAREST; else
interp = GL_LINEAR ;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, interp );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, interp );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texsize, texsize, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texsize, texsize, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, 0);
@ -990,4 +1045,4 @@ void OUTPUT_OPENGL_Shutdown()
// nothing to shutdown (yet?) // nothing to shutdown (yet?)
} }
#endif #endif

View File

@ -68,6 +68,8 @@ typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size,
# include <SDL_video.h> # include <SDL_video.h>
#endif #endif
enum GLKind {GLNearest, GLBilinear, GLPerfect};
struct SDL_OpenGL { struct SDL_OpenGL {
bool inited; bool inited;
Bitu pitch; Bitu pitch;
@ -76,7 +78,7 @@ struct SDL_OpenGL {
GLuint texture; GLuint texture;
GLuint displaylist; GLuint displaylist;
GLint max_texsize; GLint max_texsize;
bool bilinear; GLKind kind;
bool packed_pixel; bool packed_pixel;
bool paletted_texture; bool paletted_texture;
bool pixel_buffer_object; bool pixel_buffer_object;
@ -121,7 +123,10 @@ extern SDL_OpenGL sdl_opengl;
// output API // output API
void OUTPUT_OPENGL_Initialize(); void OUTPUT_OPENGL_Initialize();
void OUTPUT_OPENGL_Select(); /* Anton Shepelev: the GLKind parameter violates the generality of the API, */
/* but I think will do until a more useful general API is adopted. One */
/* example of doing it seen in my original Pixel-perfect patch: */
void OUTPUT_OPENGL_Select( GLKind );
Bitu OUTPUT_OPENGL_GetBestMode(Bitu flags); Bitu OUTPUT_OPENGL_GetBestMode(Bitu flags);
Bitu OUTPUT_OPENGL_SetSize(); Bitu OUTPUT_OPENGL_SetSize();
bool OUTPUT_OPENGL_StartUpdate(uint8_t* &pixels, Bitu &pitch); bool OUTPUT_OPENGL_StartUpdate(uint8_t* &pixels, Bitu &pitch);
@ -130,4 +135,4 @@ void OUTPUT_OPENGL_Shutdown();
#endif //C_OPENGL #endif //C_OPENGL
#endif /*DOSBOX_OUTPUT_OPENGL_H*/ #endif /*DOSBOX_OUTPUT_OPENGL_H*/