GPU: NDSDisplayInfo now reports the backlight intensity for each display. The LMNTS demo now properly fades the backlights in and out, but only on frontends that support this feature. (Fixes #59.)
- Note: The backlight intensity is only emulated on frontends with 3D-based display methods, such as OpenGL and Metal. CPU-based display methods, such as DirectDraw, SDL and Cairo, are currently unsupported.
This commit is contained in:
parent
059ea519bc
commit
f5c9a36930
|
@ -35,7 +35,6 @@
|
|||
#include "gfx3d.h"
|
||||
#include "debug.h"
|
||||
#include "NDSSystem.h"
|
||||
#include "readwrite.h"
|
||||
#include "matrix.h"
|
||||
#include "emufile.h"
|
||||
|
||||
|
@ -7456,6 +7455,8 @@ void GPUSubsystem::Reset()
|
|||
this->_willFrameSkip = false;
|
||||
this->_videoFrameCount = 0;
|
||||
this->_render3DFrameCount = 0;
|
||||
this->_backlightIntensityTotal[NDSDisplayID_Main] = 0.0f;
|
||||
this->_backlightIntensityTotal[NDSDisplayID_Touch] = 0.0f;
|
||||
|
||||
this->ClearWithColor(0xFFFF);
|
||||
|
||||
|
@ -7476,6 +7477,9 @@ void GPUSubsystem::Reset()
|
|||
this->_displayInfo.engineID[NDSDisplayID_Main] = GPUEngineID_Main;
|
||||
this->_displayInfo.engineID[NDSDisplayID_Touch] = GPUEngineID_Sub;
|
||||
|
||||
this->_displayInfo.backlightIntensity[NDSDisplayID_Main] = 1.0f;
|
||||
this->_displayInfo.backlightIntensity[NDSDisplayID_Touch] = 1.0f;
|
||||
|
||||
this->_display[NDSDisplayID_Main]->SetEngineByID(GPUEngineID_Main);
|
||||
this->_display[NDSDisplayID_Touch]->SetEngineByID(GPUEngineID_Sub);
|
||||
|
||||
|
@ -8111,6 +8115,12 @@ void GPUSubsystem::RenderLine(const size_t l)
|
|||
this->_displayInfo.needConvertColorFormat[NDSDisplayID_Main] = (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev);
|
||||
this->_displayInfo.needConvertColorFormat[NDSDisplayID_Touch] = (OUTPUTFORMAT == NDSColorFormat_BGR666_Rev);
|
||||
|
||||
// Set the average backlight intensity and then reset the current total.
|
||||
this->_displayInfo.backlightIntensity[NDSDisplayID_Main] = this->_backlightIntensityTotal[NDSDisplayID_Main] / 263.0f;
|
||||
this->_displayInfo.backlightIntensity[NDSDisplayID_Touch] = this->_backlightIntensityTotal[NDSDisplayID_Touch] / 263.0f;
|
||||
this->_backlightIntensityTotal[NDSDisplayID_Main] = 0.0f;
|
||||
this->_backlightIntensityTotal[NDSDisplayID_Touch] = 0.0f;
|
||||
|
||||
this->_engineMain->UpdateMasterBrightnessDisplayInfo(this->_displayInfo);
|
||||
this->_engineSub->UpdateMasterBrightnessDisplayInfo(this->_displayInfo);
|
||||
|
||||
|
@ -8135,6 +8145,32 @@ void GPUSubsystem::RenderLine(const size_t l)
|
|||
}
|
||||
}
|
||||
|
||||
void GPUSubsystem::UpdateAverageBacklightIntensityTotal()
|
||||
{
|
||||
// The values in this table are, more or less, arbitrarily chosen.
|
||||
//
|
||||
// It would be nice to get some real testing done on a hardware NDS to have some more
|
||||
// accurate intensity values for each backlight level.
|
||||
static const float backlightLevelToIntensityTable[] = {0.100, 0.300, 0.600, 1.000};
|
||||
|
||||
IOREG_POWERMANCTL POWERMANCTL;
|
||||
IOREG_BACKLIGHTCTL BACKLIGHTCTL;
|
||||
POWERMANCTL.value = MMU.powerMan_Reg[0];
|
||||
BACKLIGHTCTL.value = MMU.powerMan_Reg[4];
|
||||
|
||||
if (POWERMANCTL.MainBacklight_Enable != 0)
|
||||
{
|
||||
const BacklightLevel level = ((BACKLIGHTCTL.ExternalPowerState != 0) && (BACKLIGHTCTL.ForceMaxBrightnessWithExtPower_Enable != 0)) ? BacklightLevel_Maximum : (BacklightLevel)BACKLIGHTCTL.Level;
|
||||
this->_backlightIntensityTotal[NDSDisplayID_Main] += backlightLevelToIntensityTable[level];
|
||||
}
|
||||
|
||||
if (POWERMANCTL.TouchBacklight_Enable != 0)
|
||||
{
|
||||
const BacklightLevel level = ((BACKLIGHTCTL.ExternalPowerState != 0) && (BACKLIGHTCTL.ForceMaxBrightnessWithExtPower_Enable != 0)) ? BacklightLevel_Maximum : (BacklightLevel)BACKLIGHTCTL.Level;
|
||||
this->_backlightIntensityTotal[NDSDisplayID_Touch] += backlightLevelToIntensityTable[level];
|
||||
}
|
||||
}
|
||||
|
||||
void GPUSubsystem::ClearWithColor(const u16 colorBGRA5551)
|
||||
{
|
||||
u16 color16 = colorBGRA5551;
|
||||
|
|
|
@ -764,6 +764,70 @@ typedef struct
|
|||
} GPU_IOREG; // 0x04000000, 0x04001000: GPU registers
|
||||
#include "PACKED_END.h"
|
||||
|
||||
typedef union
|
||||
{
|
||||
u8 value;
|
||||
|
||||
struct
|
||||
{
|
||||
#ifndef MSB_FIRST
|
||||
u8 SoundAmp_Enable:1; // 0: Sound amplifier; 0=Disable, 1=Enable
|
||||
u8 SoundAmp_Mute:1; // 1: Sound amplifier mute control; 0=Normal, 1=Mute
|
||||
u8 TouchBacklight_Enable:1; // 2: Touch display backlight; 0=Disable, 1=Enable
|
||||
u8 MainBacklight_Enable:1; // 3: Main display backlight; 0=Disable, 1=Enable
|
||||
u8 PowerLEDBlink_Enable:1; // 4: Power LED blink control; 0=Disable (Power LED remains steadily ON), 1=Enable
|
||||
u8 PowerLEDBlinkSpeed:1; // 5: Power LED blink speed when enabled; 0=Slow, 1=Fast
|
||||
u8 SystemPowerState:2; // 6: NDS system power state; 0=System is powered ON, 1=System is powered OFF
|
||||
u8 :1; // 7: Unused bit (should always be read as 0)
|
||||
#else
|
||||
u8 :1; // 7: Unused bit (should always be read as 0)
|
||||
u8 SystemPowerState:2; // 6: NDS system power state; 0=System is powered ON, 1=System is powered OFF
|
||||
u8 PowerLEDBlinkSpeed:1; // 5: Power LED blink speed when enabled; 0=Slow, 1=Fast
|
||||
u8 PowerLEDBlink_Enable:1; // 4: Power LED blink control; 0=Disable (LED is steady ON), 1=Enable
|
||||
u8 MainBacklight_Enable:1; // 3: Main display backlight; 0=Disable, 1=Enable
|
||||
u8 TouchBacklight_Enable:1; // 2: Touch display backlight; 0=Disable, 1=Enable
|
||||
u8 SoundAmp_Mute:1; // 1: Sound amplifier mute control; 0=Normal, 1=Mute
|
||||
u8 SoundAmp_Enable:1; // 0: Sound amplifier; 0=Disable, 1=Enable
|
||||
#endif
|
||||
};
|
||||
} IOREG_POWERMANCTL;
|
||||
|
||||
typedef union
|
||||
{
|
||||
u8 value;
|
||||
|
||||
struct
|
||||
{
|
||||
#ifndef MSB_FIRST
|
||||
u8 Level:2; // 0-1: Backlight brightness level;
|
||||
// 0=Low
|
||||
// 1=Medium
|
||||
// 2=High
|
||||
// 3=Maximum
|
||||
u8 ForceMaxBrightnessWithExtPower_Enable:1; // 2: Forces maximum brightness if external power is present, interacts with Bit 3; 0=Disable, 1=Enable
|
||||
u8 ExternalPowerState:1; // 3: External power state; 0=External power is not present, 1=External power is present
|
||||
u8 :4; // 4-7: Unknown bits (should always be read as 4)
|
||||
#else
|
||||
u8 :4; // 4-7: Unknown bits (should always be read as 4)
|
||||
u8 ExternalPowerState:1; // 3: External power state; 0=External power is not present, 1=External power is present
|
||||
u8 ForceMaxBrightnessWithExtPower_Enable:1; // 2: Forces maximum brightness if external power is present, interacts with Bit 3; 0=Disable, 1=Enable
|
||||
u8 Level:2; // 0-1: Backlight brightness level;
|
||||
// 0=Low
|
||||
// 1=Medium
|
||||
// 2=High
|
||||
// 3=Maximum
|
||||
#endif
|
||||
};
|
||||
} IOREG_BACKLIGHTCTL;
|
||||
|
||||
enum BacklightLevel
|
||||
{
|
||||
BacklightLevel_Low = 0,
|
||||
BacklightLevel_Medium = 1,
|
||||
BacklightLevel_High = 2,
|
||||
BacklightLevel_Maximum = 3
|
||||
};
|
||||
|
||||
enum ColorEffect
|
||||
{
|
||||
ColorEffect_Disable = 0,
|
||||
|
@ -1115,6 +1179,10 @@ typedef struct
|
|||
u8 masterBrightnessMode[2][GPU_FRAMEBUFFER_NATIVE_HEIGHT]; // The master brightness mode of each display line.
|
||||
u8 masterBrightnessIntensity[2][GPU_FRAMEBUFFER_NATIVE_HEIGHT]; // The master brightness intensity of each display line.
|
||||
|
||||
float backlightIntensity[2]; // Reports the intensity of the backlight.
|
||||
// 0.000 - The backlight is completely off.
|
||||
// 1.000 - The backlight is at its maximum brightness.
|
||||
|
||||
|
||||
|
||||
// Postprocessing information. These fields report the status of each postprocessing step.
|
||||
|
@ -1671,6 +1739,7 @@ private:
|
|||
GPUEngineA *_engineMain;
|
||||
GPUEngineB *_engineSub;
|
||||
NDSDisplay *_display[2];
|
||||
float _backlightIntensityTotal[2];
|
||||
|
||||
u32 _videoFrameCount; // Internal variable that increments when a video frame is completed. Resets every 60 video frames.
|
||||
u32 _render3DFrameCount; // The current 3D rendering frame count, saved to this variable once every 60 video frames.
|
||||
|
@ -1757,6 +1826,7 @@ public:
|
|||
void ResolveDisplayToCustomFramebuffer(const NDSDisplayID displayID, NDSDisplayInfo &mutableInfo);
|
||||
|
||||
template<NDSColorFormat OUTPUTFORMAT> void RenderLine(const size_t l);
|
||||
void UpdateAverageBacklightIntensityTotal();
|
||||
void ClearWithColor(const u16 colorBGRA5551);
|
||||
};
|
||||
|
||||
|
|
|
@ -1534,6 +1534,8 @@ static void execHardware_hstart()
|
|||
gfx3d_VBlankEndSignal(frameSkipper.ShouldSkip3D());
|
||||
}
|
||||
|
||||
GPU->UpdateAverageBacklightIntensityTotal();
|
||||
|
||||
if (nds.VCount == 263)
|
||||
{
|
||||
nds.VCount = 0;
|
||||
|
|
|
@ -332,10 +332,11 @@ static const char *BicubicSample6x6Output_VertShader_110 = {"\
|
|||
static const char *PassthroughOutputFragShader_110 = {"\
|
||||
VARYING vec2 texCoord[1];\n\
|
||||
uniform sampler2DRect tex;\n\
|
||||
uniform float backlightIntensity;\n\
|
||||
\n\
|
||||
void main()\n\
|
||||
{\n\
|
||||
OUT_FRAG_COLOR.rgb = SAMPLE3_TEX_RECT(tex, texCoord[0]);\n\
|
||||
OUT_FRAG_COLOR.rgb = SAMPLE3_TEX_RECT(tex, texCoord[0]) * backlightIntensity;\n\
|
||||
OUT_FRAG_COLOR.a = 1.0;\n\
|
||||
}\n\
|
||||
"};
|
||||
|
@ -583,6 +584,7 @@ static const char *FilterDeposterizeFragShader_110 = {"\
|
|||
static const char *FilterBicubicBSplineFragShader_110 = {"\
|
||||
VARYING vec2 texCoord[16];\n\
|
||||
uniform sampler2DRect tex;\n\
|
||||
uniform float backlightIntensity;\n\
|
||||
\n\
|
||||
vec4 WeightBSpline(float f)\n\
|
||||
{\n\
|
||||
|
@ -624,6 +626,7 @@ static const char *FilterBicubicBSplineFragShader_110 = {"\
|
|||
+ SAMPLE3_TEX_RECT(tex, texCoord[14]) * wx.g\n\
|
||||
+ SAMPLE3_TEX_RECT(tex, texCoord[13]) * wx.b\n\
|
||||
+ SAMPLE3_TEX_RECT(tex, texCoord[12]) * wx.a) * wy.a;\n\
|
||||
OUT_FRAG_COLOR.rgb *= backlightIntensity;\n\
|
||||
OUT_FRAG_COLOR.a = 1.0;\n\
|
||||
}\n\
|
||||
"};
|
||||
|
@ -631,6 +634,7 @@ static const char *FilterBicubicBSplineFragShader_110 = {"\
|
|||
static const char *FilterBicubicBSplineFastFragShader_110 = {"\
|
||||
VARYING vec2 texCoord[1];\n\
|
||||
uniform sampler2DRect tex;\n\
|
||||
uniform float backlightIntensity;\n\
|
||||
\n\
|
||||
void main()\n\
|
||||
{\n\
|
||||
|
@ -652,6 +656,7 @@ static const char *FilterBicubicBSplineFastFragShader_110 = {"\
|
|||
SAMPLE3_TEX_RECT(tex, vec2(t1.x, t0.y)) * s1.x) * s0.y +\n\
|
||||
(SAMPLE3_TEX_RECT(tex, vec2(t0.x, t1.y)) * s0.x +\n\
|
||||
SAMPLE3_TEX_RECT(tex, vec2(t1.x, t1.y)) * s1.x) * s1.y;\n\
|
||||
OUT_FRAG_COLOR.rgb *= backlightIntensity;\n\
|
||||
OUT_FRAG_COLOR.a = 1.0;\n\
|
||||
}\n\
|
||||
"};
|
||||
|
@ -659,6 +664,7 @@ static const char *FilterBicubicBSplineFastFragShader_110 = {"\
|
|||
static const char *FilterBicubicMitchellNetravaliFragShader_110 = {"\
|
||||
VARYING vec2 texCoord[16];\n\
|
||||
uniform sampler2DRect tex;\n\
|
||||
uniform float backlightIntensity;\n\
|
||||
\n\
|
||||
vec4 WeightMitchellNetravali(float f)\n\
|
||||
{\n\
|
||||
|
@ -700,6 +706,7 @@ static const char *FilterBicubicMitchellNetravaliFragShader_110 = {"\
|
|||
+ SAMPLE3_TEX_RECT(tex, texCoord[14]) * wx.g\n\
|
||||
+ SAMPLE3_TEX_RECT(tex, texCoord[13]) * wx.b\n\
|
||||
+ SAMPLE3_TEX_RECT(tex, texCoord[12]) * wx.a) * wy.a;\n\
|
||||
OUT_FRAG_COLOR.rgb *= backlightIntensity;\n\
|
||||
OUT_FRAG_COLOR.a = 1.0;\n\
|
||||
}\n\
|
||||
"};
|
||||
|
@ -707,6 +714,7 @@ static const char *FilterBicubicMitchellNetravaliFragShader_110 = {"\
|
|||
static const char *FilterBicubicMitchellNetravaliFastFragShader_110 = {"\
|
||||
VARYING vec2 texCoord[1];\n\
|
||||
uniform sampler2DRect tex;\n\
|
||||
uniform float backlightIntensity;\n\
|
||||
\n\
|
||||
void main()\n\
|
||||
{\n\
|
||||
|
@ -728,6 +736,7 @@ static const char *FilterBicubicMitchellNetravaliFastFragShader_110 = {"\
|
|||
SAMPLE3_TEX_RECT(tex, vec2(t1.x, t0.y)) * s1.x) * s0.y +\n\
|
||||
(SAMPLE3_TEX_RECT(tex, vec2(t0.x, t1.y)) * s0.x +\n\
|
||||
SAMPLE3_TEX_RECT(tex, vec2(t1.x, t1.y)) * s1.x) * s1.y;\n\
|
||||
OUT_FRAG_COLOR.rgb *= backlightIntensity;\n\
|
||||
OUT_FRAG_COLOR.a = 1.0;\n\
|
||||
}\n\
|
||||
"};
|
||||
|
@ -739,6 +748,7 @@ static const char *FilterLanczos2FragShader_110 = {"\
|
|||
\n\
|
||||
VARYING vec2 texCoord[16];\n\
|
||||
uniform sampler2DRect tex;\n\
|
||||
uniform float backlightIntensity;\n\
|
||||
\n\
|
||||
vec4 WeightLanczos2(float f)\n\
|
||||
{\n\
|
||||
|
@ -778,6 +788,7 @@ static const char *FilterLanczos2FragShader_110 = {"\
|
|||
+ SAMPLE3_TEX_RECT(tex, texCoord[14]) * wx.g\n\
|
||||
+ SAMPLE3_TEX_RECT(tex, texCoord[13]) * wx.b\n\
|
||||
+ SAMPLE3_TEX_RECT(tex, texCoord[12]) * wx.a) * wy.a;\n\
|
||||
OUT_FRAG_COLOR.rgb *= backlightIntensity;\n\
|
||||
OUT_FRAG_COLOR.a = 1.0;\n\
|
||||
}\n\
|
||||
"};
|
||||
|
@ -795,6 +806,7 @@ static const char *FilterLanczos3FragShader_110 = {"\
|
|||
VARYING vec2 texCoord[16];\n\
|
||||
#endif\n\
|
||||
uniform sampler2DRect tex;\n\
|
||||
uniform float backlightIntensity;\n\
|
||||
\n\
|
||||
vec3 weight3(float x)\n\
|
||||
{\n\
|
||||
|
@ -938,6 +950,7 @@ static const char *FilterLanczos3FragShader_110 = {"\
|
|||
+ SAMPLE3_TEX_RECT(tex, texCoord[ 0] + vec2( 2.0, 3.0)) * wx1.b\n\
|
||||
+ SAMPLE3_TEX_RECT(tex, texCoord[ 0] + vec2( 3.0, 3.0)) * wx2.b) * wy2.b;\n\
|
||||
#endif\n\
|
||||
OUT_FRAG_COLOR.rgb *= backlightIntensity;\n\
|
||||
OUT_FRAG_COLOR.a = 1.0;\n\
|
||||
}\n\
|
||||
"};
|
||||
|
@ -5695,6 +5708,7 @@ OGLImage::OGLImage(OGLContextInfo *contextInfo, GLsizei imageWidth, GLsizei imag
|
|||
_uniformScalar = glGetUniformLocation(finalOutputProgramID, "scalar");
|
||||
_uniformViewSize = glGetUniformLocation(finalOutputProgramID, "viewSize");
|
||||
_uniformRenderFlipped = glGetUniformLocation(finalOutputProgramID, "renderFlipped");
|
||||
_uniformBacklightIntensity = glGetUniformLocation(finalOutputProgramID, "backlightIntensity");
|
||||
glUseProgram(0);
|
||||
}
|
||||
else
|
||||
|
@ -6225,7 +6239,12 @@ void OGLImage::ProcessOGL()
|
|||
|
||||
void OGLImage::RenderOGL()
|
||||
{
|
||||
glUseProgram(this->_finalOutputProgram->GetProgramID());
|
||||
if (this->_canUseShaderOutput)
|
||||
{
|
||||
glUseProgram(this->_finalOutputProgram->GetProgramID());
|
||||
glUniform1f(this->_uniformBacklightIntensity, 1.0f);
|
||||
}
|
||||
|
||||
this->UploadTransformationOGL();
|
||||
|
||||
if (this->_needUploadVertices)
|
||||
|
@ -6712,6 +6731,7 @@ OGLDisplayLayer::OGLDisplayLayer(OGLVideoOutput *oglVO)
|
|||
_uniformScalar = glGetUniformLocation(finalOutputProgramID, "scalar");
|
||||
_uniformViewSize = glGetUniformLocation(finalOutputProgramID, "viewSize");
|
||||
_uniformRenderFlipped = glGetUniformLocation(finalOutputProgramID, "renderFlipped");
|
||||
_uniformBacklightIntensity = glGetUniformLocation(finalOutputProgramID, "backlightIntensity");
|
||||
glUseProgram(0);
|
||||
}
|
||||
else
|
||||
|
@ -7204,8 +7224,9 @@ void OGLDisplayLayer::ProcessOGL()
|
|||
void OGLDisplayLayer::RenderOGL(bool isRenderingFlipped)
|
||||
{
|
||||
const NDSDisplayInfo &emuDisplayInfo = this->_output->GetEmuDisplayInfo();
|
||||
const bool isShaderSupported = this->_output->GetContextInfo()->IsShaderSupported();
|
||||
|
||||
if (this->_output->GetContextInfo()->IsShaderSupported())
|
||||
if (isShaderSupported)
|
||||
{
|
||||
glUseProgram(this->_finalOutputProgram->GetProgramID());
|
||||
|
||||
|
@ -7258,6 +7279,11 @@ void OGLDisplayLayer::RenderOGL(bool isRenderingFlipped)
|
|||
{
|
||||
if (this->_output->IsSelectedDisplayEnabled(NDSDisplayID_Main))
|
||||
{
|
||||
if (isShaderSupported)
|
||||
{
|
||||
glUniform1f(this->_uniformBacklightIntensity, emuDisplayInfo.backlightIntensity[NDSDisplayID_Main]);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[NDSDisplayID_Main]);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[NDSDisplayID_Main]);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[NDSDisplayID_Main]);
|
||||
|
@ -7270,6 +7296,11 @@ void OGLDisplayLayer::RenderOGL(bool isRenderingFlipped)
|
|||
{
|
||||
if (this->_output->IsSelectedDisplayEnabled(NDSDisplayID_Touch))
|
||||
{
|
||||
if (isShaderSupported)
|
||||
{
|
||||
glUniform1f(this->_uniformBacklightIntensity, emuDisplayInfo.backlightIntensity[NDSDisplayID_Touch]);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[NDSDisplayID_Touch]);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[NDSDisplayID_Touch]);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[NDSDisplayID_Touch]);
|
||||
|
@ -7291,6 +7322,11 @@ void OGLDisplayLayer::RenderOGL(bool isRenderingFlipped)
|
|||
{
|
||||
if (this->_output->IsSelectedDisplayEnabled(majorDisplayID))
|
||||
{
|
||||
if (isShaderSupported)
|
||||
{
|
||||
glUniform1f(this->_uniformBacklightIntensity, emuDisplayInfo.backlightIntensity[majorDisplayID]);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[majorDisplayID]);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[majorDisplayID]);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[majorDisplayID]);
|
||||
|
@ -7305,6 +7341,11 @@ void OGLDisplayLayer::RenderOGL(bool isRenderingFlipped)
|
|||
|
||||
if (this->_output->IsSelectedDisplayEnabled(NDSDisplayID_Main))
|
||||
{
|
||||
if (isShaderSupported)
|
||||
{
|
||||
glUniform1f(this->_uniformBacklightIntensity, emuDisplayInfo.backlightIntensity[NDSDisplayID_Main]);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[NDSDisplayID_Main]);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[NDSDisplayID_Main]);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[NDSDisplayID_Main]);
|
||||
|
@ -7313,6 +7354,11 @@ void OGLDisplayLayer::RenderOGL(bool isRenderingFlipped)
|
|||
|
||||
if (this->_output->IsSelectedDisplayEnabled(NDSDisplayID_Touch))
|
||||
{
|
||||
if (isShaderSupported)
|
||||
{
|
||||
glUniform1f(this->_uniformBacklightIntensity, emuDisplayInfo.backlightIntensity[NDSDisplayID_Touch]);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->_texVideoOutputID[NDSDisplayID_Touch]);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter[NDSDisplayID_Touch]);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter[NDSDisplayID_Touch]);
|
||||
|
|
|
@ -213,6 +213,7 @@ protected:
|
|||
GLint _uniformScalar;
|
||||
GLint _uniformViewSize;
|
||||
GLint _uniformRenderFlipped;
|
||||
GLint _uniformBacklightIntensity;
|
||||
|
||||
void UploadVerticesOGL();
|
||||
void UploadTexCoordsOGL();
|
||||
|
@ -259,6 +260,7 @@ protected:
|
|||
GLint _uniformScalar;
|
||||
GLint _uniformViewSize;
|
||||
GLint _uniformRenderFlipped;
|
||||
GLint _uniformBacklightIntensity;
|
||||
|
||||
public:
|
||||
virtual ~OGLVideoLayer() {};
|
||||
|
|
|
@ -1629,6 +1629,8 @@
|
|||
// Draw the NDS displays.
|
||||
if (_willDrawDisplays)
|
||||
{
|
||||
const NDSDisplayInfo &displayInfo = cdp->GetEmuDisplayInfo();
|
||||
|
||||
[rce setRenderPipelineState:outputPipelineState];
|
||||
[rce setVertexBuffer:_displayVtxPositionBuffer offset:0 atIndex:0];
|
||||
[rce setVertexBuffer:_displayTexCoordBuffer offset:0 atIndex:1];
|
||||
|
@ -1640,6 +1642,7 @@
|
|||
{
|
||||
if (cdp->IsSelectedDisplayEnabled(NDSDisplayID_Main))
|
||||
{
|
||||
[rce setFragmentBytes:&displayInfo.backlightIntensity[NDSDisplayID_Main] length:sizeof(displayInfo.backlightIntensity[NDSDisplayID_Main]) atIndex:0];
|
||||
[rce setFragmentTexture:_texDisplayOutput[NDSDisplayID_Main] atIndex:0];
|
||||
[rce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4];
|
||||
}
|
||||
|
@ -1650,6 +1653,7 @@
|
|||
{
|
||||
if (cdp->IsSelectedDisplayEnabled(NDSDisplayID_Touch))
|
||||
{
|
||||
[rce setFragmentBytes:&displayInfo.backlightIntensity[NDSDisplayID_Touch] length:sizeof(displayInfo.backlightIntensity[NDSDisplayID_Touch]) atIndex:0];
|
||||
[rce setFragmentTexture:_texDisplayOutput[NDSDisplayID_Touch] atIndex:0];
|
||||
[rce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:4 vertexCount:4];
|
||||
}
|
||||
|
@ -1669,6 +1673,7 @@
|
|||
{
|
||||
if (cdp->IsSelectedDisplayEnabled(majorDisplayID))
|
||||
{
|
||||
[rce setFragmentBytes:&displayInfo.backlightIntensity[majorDisplayID] length:sizeof(displayInfo.backlightIntensity[majorDisplayID]) atIndex:0];
|
||||
[rce setFragmentTexture:_texDisplayOutput[majorDisplayID] atIndex:0];
|
||||
[rce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:majorDisplayVtx vertexCount:4];
|
||||
}
|
||||
|
@ -1681,12 +1686,14 @@
|
|||
|
||||
if (cdp->IsSelectedDisplayEnabled(NDSDisplayID_Main))
|
||||
{
|
||||
[rce setFragmentBytes:&displayInfo.backlightIntensity[NDSDisplayID_Main] length:sizeof(displayInfo.backlightIntensity[NDSDisplayID_Main]) atIndex:0];
|
||||
[rce setFragmentTexture:_texDisplayOutput[NDSDisplayID_Main] atIndex:0];
|
||||
[rce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4];
|
||||
}
|
||||
|
||||
if (cdp->IsSelectedDisplayEnabled(NDSDisplayID_Touch))
|
||||
{
|
||||
[rce setFragmentBytes:&displayInfo.backlightIntensity[NDSDisplayID_Touch] length:sizeof(displayInfo.backlightIntensity[NDSDisplayID_Touch]) atIndex:0];
|
||||
[rce setFragmentTexture:_texDisplayOutput[NDSDisplayID_Touch] atIndex:0];
|
||||
[rce drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:4 vertexCount:4];
|
||||
}
|
||||
|
|
|
@ -226,17 +226,21 @@ vertex DisplayVtx display_output_bicubic_vertex(const device float2 *inPosition
|
|||
|
||||
//---------------------------------------
|
||||
// Input Pixel Mapping: 00
|
||||
fragment float4 output_filter_nearest(const DisplayVtx vtx [[stage_in]], const texture2d<float> tex [[texture(0)]])
|
||||
fragment float4 output_filter_nearest(const DisplayVtx vtx [[stage_in]],
|
||||
const texture2d<float> tex [[texture(0)]],
|
||||
const device float *inBacklightIntensity [[buffer(0)]])
|
||||
{
|
||||
return tex.sample(genSampler, vtx.texCoord);
|
||||
return float4(tex.sample(genSampler, vtx.texCoord).rgb * *inBacklightIntensity, 1.0f);
|
||||
}
|
||||
|
||||
//---------------------------------------
|
||||
// Input Pixel Mapping: 00|01
|
||||
// 02|03
|
||||
fragment float4 output_filter_bilinear(const DisplayVtx vtx [[stage_in]], const texture2d<float> tex [[texture(0)]])
|
||||
fragment float4 output_filter_bilinear(const DisplayVtx vtx [[stage_in]],
|
||||
const texture2d<float> tex [[texture(0)]],
|
||||
const device float *inBacklightIntensity [[buffer(0)]])
|
||||
{
|
||||
return tex.sample(outputSamplerBilinear, vtx.texCoord);
|
||||
return float4(tex.sample(outputSamplerBilinear, vtx.texCoord).rgb * *inBacklightIntensity, 1.0f);
|
||||
}
|
||||
|
||||
//---------------------------------------
|
||||
|
@ -244,7 +248,9 @@ fragment float4 output_filter_bilinear(const DisplayVtx vtx [[stage_in]], const
|
|||
// 04|05|06|07
|
||||
// 08|09|10|11
|
||||
// 12|13|14|15
|
||||
fragment float4 output_filter_bicubic_bspline(const DisplayVtx vtx [[stage_in]], const texture2d<float> tex [[texture(0)]])
|
||||
fragment float4 output_filter_bicubic_bspline(const DisplayVtx vtx [[stage_in]],
|
||||
const texture2d<float> tex [[texture(0)]],
|
||||
const device float *inBacklightIntensity [[buffer(0)]])
|
||||
{
|
||||
float2 f = fract(vtx.texCoord);
|
||||
float4 wx = bicubic_weight_bspline(f.x);
|
||||
|
@ -271,7 +277,7 @@ fragment float4 output_filter_bicubic_bspline(const DisplayVtx vtx [[stage_in]],
|
|||
+ tex.sample(genSampler, vtx.texCoord, int2( 1, 2)) * wx.b
|
||||
+ tex.sample(genSampler, vtx.texCoord, int2( 2, 2)) * wx.a) * wy.a;
|
||||
|
||||
return float4(outFragment.rgb, 1.0f);
|
||||
return float4(outFragment.rgb * *inBacklightIntensity, 1.0f);
|
||||
}
|
||||
|
||||
//---------------------------------------
|
||||
|
@ -279,7 +285,9 @@ fragment float4 output_filter_bicubic_bspline(const DisplayVtx vtx [[stage_in]],
|
|||
// 04|05|06|07
|
||||
// 08|09|10|11
|
||||
// 12|13|14|15
|
||||
fragment float4 output_filter_bicubic_mitchell_netravali(const DisplayVtx vtx [[stage_in]], const texture2d<float> tex [[texture(0)]])
|
||||
fragment float4 output_filter_bicubic_mitchell_netravali(const DisplayVtx vtx [[stage_in]],
|
||||
const texture2d<float> tex [[texture(0)]],
|
||||
const device float *inBacklightIntensity [[buffer(0)]])
|
||||
{
|
||||
float2 f = fract(vtx.texCoord);
|
||||
float4 wx = bicubic_weight_mitchell_netravali(f.x);
|
||||
|
@ -306,7 +314,7 @@ fragment float4 output_filter_bicubic_mitchell_netravali(const DisplayVtx vtx [[
|
|||
+ tex.sample(genSampler, vtx.texCoord, int2( 1, 2)) * wx.b
|
||||
+ tex.sample(genSampler, vtx.texCoord, int2( 2, 2)) * wx.a) * wy.a;
|
||||
|
||||
return float4(outFragment.rgb, 1.0f);
|
||||
return float4(outFragment.rgb * *inBacklightIntensity, 1.0f);
|
||||
}
|
||||
|
||||
//---------------------------------------
|
||||
|
@ -314,7 +322,9 @@ fragment float4 output_filter_bicubic_mitchell_netravali(const DisplayVtx vtx [[
|
|||
// 04|05|06|07
|
||||
// 08|09|10|11
|
||||
// 12|13|14|15
|
||||
fragment float4 output_filter_lanczos2(const DisplayVtx vtx [[stage_in]], const texture2d<float> tex [[texture(0)]])
|
||||
fragment float4 output_filter_lanczos2(const DisplayVtx vtx [[stage_in]],
|
||||
const texture2d<float> tex [[texture(0)]],
|
||||
const device float *inBacklightIntensity [[buffer(0)]])
|
||||
{
|
||||
const float2 f = fract(vtx.texCoord);
|
||||
float4 wx = bicubic_weight_lanczos2(f.x);
|
||||
|
@ -341,7 +351,7 @@ fragment float4 output_filter_lanczos2(const DisplayVtx vtx [[stage_in]], const
|
|||
+ tex.sample(genSampler, vtx.texCoord, int2( 1, 2)) * wx.b
|
||||
+ tex.sample(genSampler, vtx.texCoord, int2( 2, 2)) * wx.a) * wy.a;
|
||||
|
||||
return float4(outFragment.rgb, 1.0f);
|
||||
return float4(outFragment.rgb * *inBacklightIntensity, 1.0f);
|
||||
}
|
||||
|
||||
//---------------------------------------
|
||||
|
@ -351,7 +361,9 @@ fragment float4 output_filter_lanczos2(const DisplayVtx vtx [[stage_in]], const
|
|||
// 18|19|20|21|22|23
|
||||
// 24|25|26|27|28|29
|
||||
// 30|31|32|33|34|35
|
||||
fragment float4 output_filter_lanczos3(const DisplayVtx vtx [[stage_in]], const texture2d<float> tex [[texture(0)]])
|
||||
fragment float4 output_filter_lanczos3(const DisplayVtx vtx [[stage_in]],
|
||||
const texture2d<float> tex [[texture(0)]],
|
||||
const device float *inBacklightIntensity [[buffer(0)]])
|
||||
{
|
||||
const float2 f = fract(vtx.texCoord);
|
||||
float3 wx1 = bicubic_weight_lanczos3(0.5f - f.x * 0.5f);
|
||||
|
@ -404,7 +416,7 @@ fragment float4 output_filter_lanczos3(const DisplayVtx vtx [[stage_in]], const
|
|||
+ tex.sample(genSampler, vtx.texCoord, int2( 2, 3)) * wx1.b
|
||||
+ tex.sample(genSampler, vtx.texCoord, int2( 3, 3)) * wx2.b) * wy2.b;
|
||||
|
||||
return float4(outFragment.rgb, 1.0f);
|
||||
return float4(outFragment.rgb * *inBacklightIntensity, 1.0f);
|
||||
}
|
||||
|
||||
#pragma mark NDS Emulation Functions
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* main.c - this file is part of DeSmuME
|
||||
*
|
||||
* Copyright (C) 2006-2015 DeSmuME Team
|
||||
* Copyright (C) 2006-2017 DeSmuME Team
|
||||
* Copyright (C) 2007 Pascal Giard (evilynux)
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
|
@ -138,7 +138,6 @@ public:
|
|||
|
||||
#ifdef INCLUDE_OPENGL_2D
|
||||
int opengl_2d;
|
||||
int soft_colour_convert;
|
||||
#endif
|
||||
|
||||
int firmware_language;
|
||||
|
@ -155,7 +154,6 @@ init_config( class configured_features *config) {
|
|||
|
||||
#ifdef INCLUDE_OPENGL_2D
|
||||
config->opengl_2d = 0;
|
||||
config->soft_colour_convert = 0;
|
||||
#endif
|
||||
|
||||
/* use the default language */
|
||||
|
@ -184,7 +182,6 @@ fill_config( class configured_features *config,
|
|||
"SAVETYPE"},
|
||||
#ifdef INCLUDE_OPENGL_2D
|
||||
{ "opengl-2d", 0, 0, G_OPTION_ARG_NONE, &config->opengl_2d, "Enables using OpenGL for screen rendering", NULL},
|
||||
{ "soft-convert", 0, 0, G_OPTION_ARG_NONE, &config->soft_colour_convert, "Use software colour conversion during OpenGL screen rendering. May produce better or worse frame rates depending on hardware.",
|
||||
NULL},
|
||||
#endif
|
||||
{ "fwlang", 0, 0, G_OPTION_ARG_INT, &config->firmware_language, "Set the language in the firmware, LANG as follows:\n"
|
||||
|
@ -274,9 +271,9 @@ joinThread_gdb( void *thread_handle) {
|
|||
static int
|
||||
initGL( GLuint *screen_texture) {
|
||||
GLenum errCode;
|
||||
u16 blank_texture[256 * 512];
|
||||
u16 blank_texture[256 * 256];
|
||||
|
||||
memset(blank_texture, 0x001f, sizeof(blank_texture));
|
||||
memset(blank_texture, 0, sizeof(blank_texture));
|
||||
|
||||
/* Enable Texture Mapping */
|
||||
glEnable( GL_TEXTURE_2D );
|
||||
|
@ -294,19 +291,25 @@ initGL( GLuint *screen_texture) {
|
|||
glDepthFunc( GL_LEQUAL );
|
||||
|
||||
/* Create The Texture */
|
||||
glGenTextures( 1, &screen_texture[0]);
|
||||
glGenTextures(2, screen_texture);
|
||||
|
||||
glBindTexture( GL_TEXTURE_2D, screen_texture[0]);
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, screen_texture[i]);
|
||||
|
||||
/* Generate The Texture */
|
||||
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 256, 512,
|
||||
0, GL_RGBA,
|
||||
GL_UNSIGNED_SHORT_1_5_5_5_REV,
|
||||
blank_texture);
|
||||
/* Generate The Texture */
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256,
|
||||
0, GL_RGBA,
|
||||
GL_UNSIGNED_SHORT_1_5_5_5_REV,
|
||||
blank_texture);
|
||||
|
||||
/* Linear Filtering */
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
/* Linear Filtering */
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
if ((errCode = glGetError()) != GL_NO_ERROR) {
|
||||
const GLubyte *errString;
|
||||
|
@ -368,9 +371,8 @@ resizeWindow( u16 width, u16 height, GLuint *screen_texture) {
|
|||
|
||||
|
||||
static void
|
||||
opengl_Draw( GLuint *texture, int software_convert) {
|
||||
GLenum errCode;
|
||||
u16 *gpuFramebuffer = (u16 *)GPU->GetDisplayInfo().masterNativeBuffer;
|
||||
opengl_Draw(GLuint *texture) {
|
||||
const NDSDisplayInfo &displayInfo = GPU->GetDisplayInfo();
|
||||
|
||||
/* Clear The Screen And The Depth Buffer */
|
||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||
|
@ -378,54 +380,39 @@ opengl_Draw( GLuint *texture, int software_convert) {
|
|||
/* Move Into The Screen 5 Units */
|
||||
glLoadIdentity( );
|
||||
|
||||
/* Select screen Texture */
|
||||
glBindTexture( GL_TEXTURE_2D, texture[0]);
|
||||
if ( software_convert) {
|
||||
int i;
|
||||
u8 converted[256 * 384 * 3];
|
||||
/* Draw the main screen as a textured quad */
|
||||
glBindTexture(GL_TEXTURE_2D, texture[NDSDisplayID_Main]);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192,
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_SHORT_1_5_5_5_REV,
|
||||
displayInfo.renderedBuffer[NDSDisplayID_Main]);
|
||||
|
||||
for ( i = 0; i < (256 * 384); i++) {
|
||||
converted[(i * 3) + 0] = ((gpuFramebuffer[i] >> 0) & 0x1f) << 3;
|
||||
converted[(i * 3) + 1] = ((gpuFramebuffer[i] >> 5) & 0x1f) << 3;
|
||||
converted[(i * 3) + 2] = ((gpuFramebuffer[i] >> 10) & 0x1f) << 3;
|
||||
}
|
||||
GLfloat backlightIntensity = displayInfo.backlightIntensity[NDSDisplayID_Main];
|
||||
|
||||
glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 256, 384,
|
||||
GL_RGB,
|
||||
GL_UNSIGNED_BYTE,
|
||||
converted);
|
||||
}
|
||||
else {
|
||||
glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 256, 384,
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_SHORT_1_5_5_5_REV,
|
||||
gpuFramebuffer);
|
||||
}
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0.00f, 0.00f); glVertex2f( 0.0f, 0.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
|
||||
glTexCoord2f(1.00f, 0.00f); glVertex2f(256.0f, 0.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
|
||||
glTexCoord2f(1.00f, 0.75f); glVertex2f(256.0f, 192.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
|
||||
glTexCoord2f(0.00f, 0.75f); glVertex2f( 0.0f, 192.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
|
||||
glEnd();
|
||||
|
||||
if ((errCode = glGetError()) != GL_NO_ERROR) {
|
||||
const GLubyte *errString;
|
||||
/* Draw the touch screen as a textured quad */
|
||||
glBindTexture(GL_TEXTURE_2D, texture[NDSDisplayID_Touch]);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192,
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_SHORT_1_5_5_5_REV,
|
||||
displayInfo.renderedBuffer[NDSDisplayID_Touch]);
|
||||
|
||||
errString = gluErrorString(errCode);
|
||||
fprintf( stderr, "GL subimage failed: %s\n", errString);
|
||||
}
|
||||
backlightIntensity = displayInfo.backlightIntensity[NDSDisplayID_Touch];
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0.00f, 0.00f); glVertex2f( 0.0f, 192.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
|
||||
glTexCoord2f(1.00f, 0.00f); glVertex2f(256.0f, 192.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
|
||||
glTexCoord2f(1.00f, 0.75f); glVertex2f(256.0f, 384.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
|
||||
glTexCoord2f(0.00f, 0.75f); glVertex2f( 0.0f, 384.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
|
||||
glEnd();
|
||||
|
||||
/* Draw the screen as a textured quad */
|
||||
glBegin( GL_QUADS);
|
||||
glTexCoord2f( 0.0f, 0.0f ); glVertex3f( 0.0f, 0.0f, 0.0f );
|
||||
glTexCoord2f( 1.0f, 0.0f ); glVertex3f( 256.0f, 0.0f, 0.0f );
|
||||
glTexCoord2f( 1.0f, 0.75f ); glVertex3f( 256.0f, 384.0f, 0.0f );
|
||||
glTexCoord2f( 0.0f, 0.75f ); glVertex3f( 0.0f, 384.0f, 0.0f );
|
||||
glEnd( );
|
||||
|
||||
if ((errCode = glGetError()) != GL_NO_ERROR) {
|
||||
const GLubyte *errString;
|
||||
|
||||
errString = gluErrorString(errCode);
|
||||
fprintf( stderr, "GL draw failed: %s\n", errString);
|
||||
}
|
||||
|
||||
/* Draw it to the screen */
|
||||
/* Flush the drawing to the screen */
|
||||
SDL_GL_SwapBuffers( );
|
||||
}
|
||||
#endif
|
||||
|
@ -510,7 +497,7 @@ int main(int argc, char ** argv) {
|
|||
#endif
|
||||
|
||||
#ifdef INCLUDE_OPENGL_2D
|
||||
GLuint screen_texture[1];
|
||||
GLuint screen_texture[2];
|
||||
#endif
|
||||
/* this holds some info about our display */
|
||||
const SDL_VideoInfo *videoInfo;
|
||||
|
@ -772,7 +759,7 @@ int main(int argc, char ** argv) {
|
|||
|
||||
#ifdef INCLUDE_OPENGL_2D
|
||||
if ( my_config.opengl_2d) {
|
||||
opengl_Draw( screen_texture, my_config.soft_colour_convert);
|
||||
opengl_Draw(screen_texture);
|
||||
ctrls_cfg.resize_cb = &resizeWindow;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* gdk_gl.cpp - this file is part of DeSmuME
|
||||
*
|
||||
* Copyright (C) 2007-2016 DeSmuME Team
|
||||
* Copyright (C) 2007-2017 DeSmuME Team
|
||||
* Copyright (C) 2007 Damien Nozay (damdoum)
|
||||
* Author: damdoum at users.sourceforge.net
|
||||
*
|
||||
|
@ -33,7 +33,6 @@
|
|||
#define _DUP4(a) a,a,a,a
|
||||
#define _DUP2(a) a,a
|
||||
|
||||
GLuint Textures[2];
|
||||
// free number we can use in tools 0-1 reserved for screens
|
||||
static int free_gl_drawable=2;
|
||||
GdkGLConfig *my_glConfig=NULL;
|
||||
|
@ -41,10 +40,7 @@ GdkGLContext *my_glContext[8]={_DUP8(NULL)};
|
|||
GdkGLDrawable *my_glDrawable[8]={_DUP8(NULL)};
|
||||
GtkWidget *pDrawingTexArea;
|
||||
|
||||
GLuint screen_texture[1];
|
||||
|
||||
/* enable software colour format conversion */
|
||||
static int gtk_glade_use_software_colour_convert;
|
||||
GLuint screen_texture[2];
|
||||
|
||||
#undef _DUP8
|
||||
#undef _DUP4
|
||||
|
@ -141,32 +137,45 @@ int init_GL_free(GtkWidget * widget) {
|
|||
return r;
|
||||
}
|
||||
|
||||
void init_GL_capabilities( int use_software_convert) {
|
||||
void init_GL_capabilities() {
|
||||
|
||||
uint16_t blank_texture[256 * 256];
|
||||
memset(blank_texture, 0, sizeof(blank_texture));
|
||||
|
||||
uint16_t blank_texture[256 * 512];
|
||||
my_glConfig = gdk_gl_config_new_by_mode (
|
||||
(GdkGLConfigMode) (GDK_GL_MODE_RGBA
|
||||
| GDK_GL_MODE_DEPTH
|
||||
| GDK_GL_MODE_DOUBLE)
|
||||
);
|
||||
|
||||
gtk_glade_use_software_colour_convert = use_software_convert;
|
||||
// initialize 1st drawing area
|
||||
init_GL(pDrawingArea,0,0);
|
||||
my_gl_Clear(0);
|
||||
|
||||
if (!my_gl_Begin(0)) return;
|
||||
// generate ONE texture (display)
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glGenTextures(2, Textures);
|
||||
|
||||
/* Generate The Texture */
|
||||
glBindTexture( GL_TEXTURE_2D, Textures[0]);
|
||||
memset(blank_texture, 0, sizeof(blank_texture));
|
||||
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 256, 512,
|
||||
0, GL_RGBA,
|
||||
GL_UNSIGNED_SHORT_1_5_5_5_REV,
|
||||
blank_texture);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glGenTextures(2, screen_texture);
|
||||
|
||||
/* Generate The Texture */
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, screen_texture[i]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
#define MyFILTER GL_LINEAR
|
||||
//#define MyFILTER GL_NEAREST
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, MyFILTER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, MyFILTER);
|
||||
#undef MyFILTER
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256,
|
||||
0, GL_RGBA,
|
||||
GL_UNSIGNED_SHORT_1_5_5_5_REV,
|
||||
blank_texture);
|
||||
}
|
||||
|
||||
my_gl_End(0);
|
||||
|
||||
// initialize 2nd drawing area (sharing context)
|
||||
|
@ -192,52 +201,44 @@ void reshape (GtkWidget * widget, int screen) {
|
|||
/* TEXTURING */
|
||||
/************************************************/
|
||||
|
||||
static void my_gl_Texture2D() {
|
||||
glBindTexture(GL_TEXTURE_2D, Textures[0]);
|
||||
#define MyFILTER GL_LINEAR
|
||||
//#define MyFILTER GL_NEAREST
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, MyFILTER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, MyFILTER);
|
||||
#undef MyFILTER
|
||||
}
|
||||
|
||||
static void
|
||||
my_gl_ScreenTex( int software_convert) {
|
||||
u16 *gpuFramebuffer = (u16 *)GPU->GetDisplayInfo().masterNativeBuffer;
|
||||
my_gl_ScreenTex() {
|
||||
const NDSDisplayInfo &displayInfo = GPU->GetDisplayInfo();
|
||||
|
||||
if ( software_convert) {
|
||||
u8 converted[256 * 384 * 3];
|
||||
int i;
|
||||
glBindTexture(GL_TEXTURE_2D, screen_texture[NDSDisplayID_Main]);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192,
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_SHORT_1_5_5_5_REV,
|
||||
displayInfo.renderedBuffer[NDSDisplayID_Main]);
|
||||
|
||||
for ( i = 0; i < (256 * 384); i++) {
|
||||
converted[(i * 3) + 0] = ((gpuFramebuffer[i] >> 0) & 0x1f) << 3;
|
||||
converted[(i * 3) + 1] = ((gpuFramebuffer[i] >> 5) & 0x1f) << 3;
|
||||
converted[(i * 3) + 2] = ((gpuFramebuffer[i] >> 10) & 0x1f) << 3;
|
||||
}
|
||||
|
||||
glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 256, 384,
|
||||
GL_RGB,
|
||||
GL_UNSIGNED_BYTE,
|
||||
converted);
|
||||
}
|
||||
else {
|
||||
glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 256, 384,
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_SHORT_1_5_5_5_REV,
|
||||
gpuFramebuffer);
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, screen_texture[NDSDisplayID_Touch]);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192,
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_SHORT_1_5_5_5_REV,
|
||||
displayInfo.renderedBuffer[NDSDisplayID_Touch]);
|
||||
}
|
||||
|
||||
static void my_gl_ScreenTexApply(int screen) {
|
||||
float off = (screen)?0.375:0;
|
||||
const NDSDisplayInfo &displayInfo = GPU->GetDisplayInfo();
|
||||
|
||||
glColor4ub(255,255,255,255);
|
||||
GLfloat backlightIntensity = displayInfo.backlightIntensity[NDSDisplayID_Main];
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, screen_texture[NDSDisplayID_Main]);
|
||||
glBegin(GL_QUADS);
|
||||
// texcoords 0.375 means 192, 1 means 256
|
||||
glTexCoord2f(0.0, off+0.000); glVertex2d(-1.0, 1.0);
|
||||
glTexCoord2f(1.0, off+0.000); glVertex2d( 1.0, 1.0);
|
||||
glTexCoord2f(1.0, off+0.375); glVertex2d( 1.0,-1.0);
|
||||
glTexCoord2f(0.0, off+0.375); glVertex2d(-1.0,-1.0);
|
||||
glTexCoord2f(0.00f, 0.00f); glVertex2f(-1.0f, 1.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
|
||||
glTexCoord2f(1.00f, 0.00f); glVertex2f( 1.0f, 1.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
|
||||
glTexCoord2f(1.00f, 0.75f); glVertex2f( 1.0f, 0.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
|
||||
glTexCoord2f(0.00f, 0.75f); glVertex2f(-1.0f, 0.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
|
||||
glEnd();
|
||||
|
||||
backlightIntensity = displayInfo.backlightIntensity[NDSDisplayID_Touch];
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, screen_texture[NDSDisplayID_Touch]);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0.00f, 0.00f); glVertex2f(-1.0f, 0.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
|
||||
glTexCoord2f(1.00f, 0.00f); glVertex2f( 1.0f, 0.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
|
||||
glTexCoord2f(1.00f, 0.75f); glVertex2f( 1.0f, -1.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
|
||||
glTexCoord2f(0.00f, 0.75f); glVertex2f(-1.0f, -1.0f); glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
@ -247,7 +248,6 @@ static void my_gl_ScreenTexApply(int screen) {
|
|||
|
||||
gboolean screen (GtkWidget * widget, int viewportscreen) {
|
||||
int screen;
|
||||
GPUEngineBase * gpu;
|
||||
|
||||
// we take care to draw the right thing the right place
|
||||
// we need to rearrange widgets not to use this trick
|
||||
|
@ -271,10 +271,8 @@ gboolean screen (GtkWidget * widget, int viewportscreen) {
|
|||
if (desmume_running()) {
|
||||
// rotate
|
||||
glRotatef(ScreenRotate, 0.0, 0.0, 1.0);
|
||||
// create the texture for both display
|
||||
my_gl_Texture2D();
|
||||
if (viewportscreen==0) {
|
||||
my_gl_ScreenTex( gtk_glade_use_software_colour_convert);
|
||||
my_gl_ScreenTex();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -90,7 +90,6 @@ GPU3DInterface *core3DList[] = {
|
|||
*/
|
||||
struct configured_features {
|
||||
int load_slot;
|
||||
int software_colour_convert;
|
||||
int opengl_2d;
|
||||
int engine_3d;
|
||||
int disable_limiter;
|
||||
|
@ -110,8 +109,6 @@ init_configured_features( struct configured_features *config) {
|
|||
config->arm9_gdb_port = 0;
|
||||
config->arm7_gdb_port = 0;
|
||||
|
||||
config->software_colour_convert = 0;
|
||||
|
||||
config->opengl_2d = 0;
|
||||
config->engine_3d = 1;
|
||||
|
||||
|
@ -137,12 +134,6 @@ fill_configured_features( struct configured_features *config,
|
|||
g_print( _("OPTIONS:\n"));
|
||||
g_print( _("\
|
||||
--load-slot=NUM Load game saved under NUM position.\n\n"));
|
||||
#ifdef GTKGLEXT_AVAILABLE
|
||||
g_print( _("\
|
||||
--soft-convert Use software colour conversion during OpenGL\n\
|
||||
screen rendering. May produce better or worse\n\
|
||||
frame rates depending on hardware.\n\n"));
|
||||
#endif
|
||||
g_print( _("\
|
||||
--3d-engine=ENGINE Selects 3D rendering engine\n\
|
||||
0 = disabled\n\
|
||||
|
@ -198,9 +189,6 @@ fill_configured_features( struct configured_features *config,
|
|||
// FIXME: to be implemented
|
||||
config->opengl_2d = 1;
|
||||
}
|
||||
else if ( strcmp( argv[i], "--soft-convert") == 0) {
|
||||
config->software_colour_convert = 1;
|
||||
}
|
||||
#define MAX3DEMU 2
|
||||
#else
|
||||
#define MAX3DEMU 1
|
||||
|
@ -466,7 +454,7 @@ common_gtk_glade_main( struct configured_features *my_config) {
|
|||
glade_xml_signal_autoconnect_StringObject(xml);
|
||||
glade_xml_signal_autoconnect_StringObject(xml_tools);
|
||||
|
||||
init_GL_capabilities( my_config->software_colour_convert);
|
||||
init_GL_capabilities();
|
||||
|
||||
/* check command line file */
|
||||
if( my_config->nds_file) {
|
||||
|
|
|
@ -1625,6 +1625,8 @@ static void OGL_DoDisplay()
|
|||
{
|
||||
if(!gldisplay.begin()) return;
|
||||
|
||||
const NDSDisplayInfo &displayInfo = GPU->GetDisplayInfo();
|
||||
|
||||
static GLuint tex = 0;
|
||||
if(tex == 0)
|
||||
glGenTextures(1,&tex);
|
||||
|
@ -1641,8 +1643,8 @@ static void OGL_DoDisplay()
|
|||
|
||||
//the ds screen fills the texture entirely, so we dont have garbage at edge to worry about,
|
||||
//but we need to make sure this is clamped for when filtering is selected
|
||||
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_S,GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
|
||||
|
||||
if(GetStyle()&DWS_FILTER)
|
||||
{
|
||||
|
@ -1700,7 +1702,7 @@ static void OGL_DoDisplay()
|
|||
int r = (color_rev>>0)&0xFF;
|
||||
int g = (color_rev>>8)&0xFF;
|
||||
int b = (color_rev>>16)&0xFF;
|
||||
glClearColor(r/255.0f,g/255.0f,b/255.0f,1);
|
||||
glClearColor(r/255.0f,g/255.0f,b/255.0f,1.0f);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
@ -1708,7 +1710,7 @@ static void OGL_DoDisplay()
|
|||
|
||||
|
||||
RECT srcRects [2];
|
||||
const bool isMainGPUFirst = (GPU->GetDisplayInfo().engineID[NDSDisplayID_Main] == GPUEngineID_Main);
|
||||
const bool isMainGPUFirst = (displayInfo.engineID[NDSDisplayID_Main] == GPUEngineID_Main);
|
||||
|
||||
if(video.swap == 0)
|
||||
{
|
||||
|
@ -1776,12 +1778,21 @@ static void OGL_DoDisplay()
|
|||
float u[] = {u1,u2,u2,u1};
|
||||
float v[] = {v1,v1,v2,v2};
|
||||
|
||||
const GLfloat backlightIntensity = displayInfo.backlightIntensity[i];
|
||||
|
||||
glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
|
||||
glTexCoord2f(u[(ofs+0)%4],v[(ofs+0)%4]);
|
||||
glVertex2i(dr[i].left,dr[i].top);
|
||||
|
||||
glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
|
||||
glTexCoord2f(u[(ofs+1)%4],v[(ofs+1)%4]);
|
||||
glVertex2i(dr[i].right,dr[i].top);
|
||||
|
||||
glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
|
||||
glTexCoord2f(u[(ofs+2)%4],v[(ofs+2)%4]);
|
||||
glVertex2i(dr[i].right,dr[i].bottom);
|
||||
|
||||
glColor4f(backlightIntensity, backlightIntensity, backlightIntensity, 1.0f);
|
||||
glTexCoord2f(u[(ofs+3)%4],v[(ofs+3)%4]);
|
||||
glVertex2i(dr[i].left,dr[i].bottom);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue