mirror of https://github.com/stella-emu/stella.git
Fixed incorrect initialization of certain OpenGL function pointers.
Basically, the OpenGL class can use functions from several different versions of OpenGL (1.3 and 2.0+), and all sections of code need to be wrapped in IF statements to make sure we don't use a function pointer that is NULL. Basically, this means that all GLSL/2.0+ stuff needs to be wrapped in 'if(myTvFiltersEnabled) ...'. This actually lays the groundwork for the next feature I'll be adding (frame buffer objects), since those require yet another level of OpenGL functions that may not be available everywhere. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1816 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
1275c25681
commit
79fdcb3480
|
@ -59,6 +59,7 @@ OGL_DECLARE(void,glPixelStorei,(GLenum, GLint));
|
||||||
OGL_DECLARE(void,glTexEnvf,(GLenum, GLenum, GLfloat));
|
OGL_DECLARE(void,glTexEnvf,(GLenum, GLenum, GLfloat));
|
||||||
OGL_DECLARE(void,glGenTextures,(GLsizei, GLuint*));
|
OGL_DECLARE(void,glGenTextures,(GLsizei, GLuint*));
|
||||||
OGL_DECLARE(void,glDeleteTextures,(GLsizei, const GLuint*));
|
OGL_DECLARE(void,glDeleteTextures,(GLsizei, const GLuint*));
|
||||||
|
OGL_DECLARE(void,glActiveTexture,(GLenum));
|
||||||
OGL_DECLARE(void,glBindTexture,(GLenum, GLuint));
|
OGL_DECLARE(void,glBindTexture,(GLenum, GLuint));
|
||||||
OGL_DECLARE(void,glTexImage2D,(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*));
|
OGL_DECLARE(void,glTexImage2D,(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*));
|
||||||
OGL_DECLARE(void,glTexSubImage2D,(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid*));
|
OGL_DECLARE(void,glTexSubImage2D,(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid*));
|
||||||
|
@ -77,7 +78,6 @@ OGL_DECLARE(void,glUniform1i,(GLint, GLint));
|
||||||
OGL_DECLARE(void,glUniform1f,(GLint, GLfloat));
|
OGL_DECLARE(void,glUniform1f,(GLint, GLfloat));
|
||||||
OGL_DECLARE(void,glCopyTexImage2D,(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint));
|
OGL_DECLARE(void,glCopyTexImage2D,(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint));
|
||||||
OGL_DECLARE(void,glCopyTexSubImage2D,(GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei));
|
OGL_DECLARE(void,glCopyTexSubImage2D,(GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei));
|
||||||
OGL_DECLARE(void,glActiveTexture,(GLenum));
|
|
||||||
OGL_DECLARE(void,glGetIntegerv,(GLenum, GLint*));
|
OGL_DECLARE(void,glGetIntegerv,(GLenum, GLint*));
|
||||||
OGL_DECLARE(void,glTexEnvi,(GLenum, GLenum, GLint));
|
OGL_DECLARE(void,glTexEnvi,(GLenum, GLenum, GLint));
|
||||||
OGL_DECLARE(void,glMultiTexCoord2f,(GLenum, GLfloat, GLfloat));
|
OGL_DECLARE(void,glMultiTexCoord2f,(GLenum, GLfloat, GLfloat));
|
||||||
|
@ -163,6 +163,7 @@ bool FrameBufferGL::loadFuncs(GLFunctionality functionality)
|
||||||
OGL_INIT(void,glTexEnvf,(GLenum, GLenum, GLfloat));
|
OGL_INIT(void,glTexEnvf,(GLenum, GLenum, GLfloat));
|
||||||
OGL_INIT(void,glGenTextures,(GLsizei, GLuint*));
|
OGL_INIT(void,glGenTextures,(GLsizei, GLuint*));
|
||||||
OGL_INIT(void,glDeleteTextures,(GLsizei, const GLuint*));
|
OGL_INIT(void,glDeleteTextures,(GLsizei, const GLuint*));
|
||||||
|
OGL_INIT(void,glActiveTexture,(GLenum));
|
||||||
OGL_INIT(void,glBindTexture,(GLenum, GLuint));
|
OGL_INIT(void,glBindTexture,(GLenum, GLuint));
|
||||||
OGL_INIT(void,glTexImage2D,(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*));
|
OGL_INIT(void,glTexImage2D,(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*));
|
||||||
OGL_INIT(void,glTexSubImage2D,(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid*));
|
OGL_INIT(void,glTexSubImage2D,(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid*));
|
||||||
|
@ -184,7 +185,6 @@ bool FrameBufferGL::loadFuncs(GLFunctionality functionality)
|
||||||
OGL_INIT(void,glUniform1f,(GLint, GLfloat));
|
OGL_INIT(void,glUniform1f,(GLint, GLfloat));
|
||||||
OGL_INIT(void,glCopyTexImage2D,(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint));
|
OGL_INIT(void,glCopyTexImage2D,(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint));
|
||||||
OGL_INIT(void,glCopyTexSubImage2D,(GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei));
|
OGL_INIT(void,glCopyTexSubImage2D,(GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei));
|
||||||
OGL_INIT(void,glActiveTexture,(GLenum));
|
|
||||||
OGL_INIT(void,glGetIntegerv,(GLenum, GLint*));
|
OGL_INIT(void,glGetIntegerv,(GLenum, GLint*));
|
||||||
OGL_INIT(void,glTexEnvi,(GLenum, GLenum, GLint));
|
OGL_INIT(void,glTexEnvi,(GLenum, GLenum, GLint));
|
||||||
OGL_INIT(void,glMultiTexCoord2f,(GLenum, GLfloat, GLfloat));
|
OGL_INIT(void,glMultiTexCoord2f,(GLenum, GLfloat, GLfloat));
|
||||||
|
@ -359,7 +359,7 @@ bool FrameBufferGL::setVidMode(VideoMode& mode)
|
||||||
myGLVersion = atof(version.substr(0, 3).c_str());
|
myGLVersion = atof(version.substr(0, 3).c_str());
|
||||||
|
|
||||||
// TV effects depend on the GLSL functions being available
|
// TV effects depend on the GLSL functions being available
|
||||||
myGLSLAvailable = myGLVersion >= 2.0 && loadFuncs(kGL_SHADER);
|
myGLSLAvailable = loadFuncs(kGL_SHADER);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
@ -429,7 +429,12 @@ cerr << "dimensions: " << (fullScreen() ? "(full)" : "") << endl
|
||||||
// and other UI surfaces are no longer tied together
|
// and other UI surfaces are no longer tied together
|
||||||
// Note that this may change in the future, when we add more
|
// Note that this may change in the future, when we add more
|
||||||
// complex filters/scalers, but for now it's fine
|
// complex filters/scalers, but for now it's fine
|
||||||
|
//
|
||||||
// Also note that TV filtering is only available with OpenGL 2.0+
|
// Also note that TV filtering is only available with OpenGL 2.0+
|
||||||
|
// The hint we provide here is only that GLSL is available and
|
||||||
|
// TV effects *can* be applied to this surface
|
||||||
|
// The specific TV effect settings still determine whether any
|
||||||
|
// filtering *will* be applied in such a case
|
||||||
myTiaSurface = new FBSurfaceGL(*this, baseWidth>>1, baseHeight,
|
myTiaSurface = new FBSurfaceGL(*this, baseWidth>>1, baseHeight,
|
||||||
mode.image_w, mode.image_h,
|
mode.image_w, mode.image_h,
|
||||||
myGLSLAvailable);
|
myGLSLAvailable);
|
||||||
|
@ -587,7 +592,7 @@ FBSurfaceGL::FBSurfaceGL(FrameBufferGL& buffer,
|
||||||
myPhosphorProgram(0),
|
myPhosphorProgram(0),
|
||||||
myTextureNoiseProgram(0),
|
myTextureNoiseProgram(0),
|
||||||
myNoiseNum(0),
|
myNoiseNum(0),
|
||||||
myTvFiltersEnabled(allowFiltering)
|
myTvFiltersEnabled(false)
|
||||||
{
|
{
|
||||||
// Fill buffer struct with valid data
|
// Fill buffer struct with valid data
|
||||||
// This changes depending on the texturing used
|
// This changes depending on the texturing used
|
||||||
|
@ -620,6 +625,19 @@ FBSurfaceGL::FBSurfaceGL(FrameBufferGL& buffer,
|
||||||
0x00007c00, 0x000003e0, 0x0000001f, 0x00000000);
|
0x00007c00, 0x000003e0, 0x0000001f, 0x00000000);
|
||||||
myPitch = myTexture->pitch >> 1;
|
myPitch = myTexture->pitch >> 1;
|
||||||
|
|
||||||
|
// The 'allowFiltering' boolean is only a hint that filtering is allowed
|
||||||
|
// on this surface
|
||||||
|
// We still need to check if the functionality exists to do it
|
||||||
|
if(allowFiltering)
|
||||||
|
{
|
||||||
|
// It's only enabled if we use one of the filters *AND* GLSL is available
|
||||||
|
myTvFiltersEnabled = myFB.myGLSLAvailable &&
|
||||||
|
(myFB.myUseTexture || myFB.myUseNoise ||
|
||||||
|
myFB.myUseBleed || myFB.myUseGLPhosphor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
myTvFiltersEnabled = false;
|
||||||
|
|
||||||
// Only do this if TV filters enabled, otherwise it won't be used anyway
|
// Only do this if TV filters enabled, otherwise it won't be used anyway
|
||||||
if(myTvFiltersEnabled)
|
if(myTvFiltersEnabled)
|
||||||
{
|
{
|
||||||
|
@ -643,11 +661,10 @@ FBSurfaceGL::FBSurfaceGL(FrameBufferGL& buffer,
|
||||||
myFilterTexCoord[2] = (GLfloat) scaleWidth / myFilterTexWidth;
|
myFilterTexCoord[2] = (GLfloat) scaleWidth / myFilterTexWidth;
|
||||||
myFilterTexCoord[1] = (GLfloat) scaleHeight / myFilterTexHeight;
|
myFilterTexCoord[1] = (GLfloat) scaleHeight / myFilterTexHeight;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Only do this if TV and color bleed filters are enabled
|
// Only do this if TV and color bleed filters are enabled
|
||||||
// This filer applies a color averaging of surrounding pixels for each pixel
|
// This filer applies a color averaging of surrounding pixels for each pixel
|
||||||
if(myTvFiltersEnabled && myFB.myUseBleed)
|
if(myFB.myUseBleed)
|
||||||
{
|
{
|
||||||
// Load shader programs. If it fails, don't use this filter.
|
// Load shader programs. If it fails, don't use this filter.
|
||||||
myBleedProgram = genShader(SHADER_BLEED);
|
myBleedProgram = genShader(SHADER_BLEED);
|
||||||
|
@ -662,7 +679,7 @@ FBSurfaceGL::FBSurfaceGL(FrameBufferGL& buffer,
|
||||||
// Make sure we can use three textures at once first
|
// Make sure we can use three textures at once first
|
||||||
GLint texUnits;
|
GLint texUnits;
|
||||||
p_glGetIntegerv(GL_MAX_TEXTURE_UNITS, &texUnits);
|
p_glGetIntegerv(GL_MAX_TEXTURE_UNITS, &texUnits);
|
||||||
if(myTvFiltersEnabled && texUnits >= 3 && myFB.myUseTexture && myFB.myUseNoise)
|
if(texUnits >= 3 && myFB.myUseTexture && myFB.myUseNoise)
|
||||||
{
|
{
|
||||||
// Load shader program. If it fails, don't use this shader.
|
// Load shader program. If it fails, don't use this shader.
|
||||||
myTextureNoiseProgram = genShader(SHADER_TEXNOISE);
|
myTextureNoiseProgram = genShader(SHADER_TEXNOISE);
|
||||||
|
@ -688,7 +705,7 @@ FBSurfaceGL::FBSurfaceGL(FrameBufferGL& buffer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Else, detect individual settings
|
// Else, detect individual settings
|
||||||
else if(myTvFiltersEnabled)
|
else
|
||||||
{
|
{
|
||||||
if(myFB.myUseTexture)
|
if(myFB.myUseTexture)
|
||||||
{
|
{
|
||||||
|
@ -714,8 +731,8 @@ FBSurfaceGL::FBSurfaceGL(FrameBufferGL& buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only do this if TV and color texture filters are enabled
|
// Only do this if TV and color texture filters are enabled
|
||||||
// This filer applies an RGB color pixel mask as well as a blackspace mask
|
// This filter applies an RGB color pixel mask as well as a blackspace mask
|
||||||
if(myTvFiltersEnabled && myFB.myUseTexture)
|
if(myFB.myUseTexture)
|
||||||
{
|
{
|
||||||
// Prepare subpixel texture
|
// Prepare subpixel texture
|
||||||
mySubpixelTexture = SDL_CreateRGBSurface(SDL_SWSURFACE,
|
mySubpixelTexture = SDL_CreateRGBSurface(SDL_SWSURFACE,
|
||||||
|
@ -751,7 +768,7 @@ FBSurfaceGL::FBSurfaceGL(FrameBufferGL& buffer,
|
||||||
|
|
||||||
// Only do this if TV and noise filters are enabled
|
// Only do this if TV and noise filters are enabled
|
||||||
// This filter applies a texture filled with gray pixel of random intensities
|
// This filter applies a texture filled with gray pixel of random intensities
|
||||||
if(myTvFiltersEnabled && myFB.myUseNoise)
|
if(myFB.myUseNoise)
|
||||||
{
|
{
|
||||||
// Get the current number of nose textures to use
|
// Get the current number of nose textures to use
|
||||||
myNoiseNum = myFB.myNoiseQuality;
|
myNoiseNum = myFB.myNoiseQuality;
|
||||||
|
@ -801,7 +818,7 @@ FBSurfaceGL::FBSurfaceGL(FrameBufferGL& buffer,
|
||||||
|
|
||||||
// Only do this if TV and phosphor filters are enabled
|
// Only do this if TV and phosphor filters are enabled
|
||||||
// This filter merges the past screen with the current one, to give a phosphor burn-off effect
|
// This filter merges the past screen with the current one, to give a phosphor burn-off effect
|
||||||
if(myTvFiltersEnabled && myFB.myUseGLPhosphor)
|
if(myFB.myUseGLPhosphor)
|
||||||
{
|
{
|
||||||
// Load shader program. If it fails, don't use this filter.
|
// Load shader program. If it fails, don't use this filter.
|
||||||
myPhosphorProgram = genShader(SHADER_PHOS);
|
myPhosphorProgram = genShader(SHADER_PHOS);
|
||||||
|
@ -811,6 +828,14 @@ FBSurfaceGL::FBSurfaceGL(FrameBufferGL& buffer,
|
||||||
cout << "ERROR: Failed to make phosphor program" << endl;
|
cout << "ERROR: Failed to make phosphor program" << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check to see if filters should still be used
|
||||||
|
// Filtering must have been previously enabled, and GLSL must still be
|
||||||
|
// available
|
||||||
|
myTvFiltersEnabled = myTvFiltersEnabled && myFB.myGLSLAvailable &&
|
||||||
|
(myFB.myUseTexture || myFB.myUseNoise ||
|
||||||
|
myFB.myUseBleed || myFB.myUseGLPhosphor);
|
||||||
|
|
||||||
// Associate the SDL surface with a GL texture object
|
// Associate the SDL surface with a GL texture object
|
||||||
reload();
|
reload();
|
||||||
|
@ -1025,11 +1050,8 @@ void FBSurfaceGL::update()
|
||||||
bool firstRender = true;
|
bool firstRender = true;
|
||||||
|
|
||||||
// Render as usual if no filters are used
|
// Render as usual if no filters are used
|
||||||
if(!myTvFiltersEnabled ||
|
if(!myTvFiltersEnabled)
|
||||||
(!myFB.myUseTexture && !myFB.myUseNoise && !myFB.myUseBleed && !myFB.myUseGLPhosphor))
|
|
||||||
{
|
{
|
||||||
p_glUseProgram(0);
|
|
||||||
|
|
||||||
// Texturemap complete texture to surface so we have free scaling
|
// Texturemap complete texture to surface so we have free scaling
|
||||||
// and antialiasing
|
// and antialiasing
|
||||||
p_glActiveTexture(GL_TEXTURE0);
|
p_glActiveTexture(GL_TEXTURE0);
|
||||||
|
@ -1054,6 +1076,7 @@ void FBSurfaceGL::update()
|
||||||
}
|
}
|
||||||
|
|
||||||
// If TV filters are enabled
|
// If TV filters are enabled
|
||||||
|
// TODO - check if this IF is necessary, or can it be chained by else to above
|
||||||
if(myTvFiltersEnabled)
|
if(myTvFiltersEnabled)
|
||||||
{
|
{
|
||||||
// If combined texture/noise program exists,
|
// If combined texture/noise program exists,
|
||||||
|
@ -1205,6 +1228,11 @@ void FBSurfaceGL::update()
|
||||||
// We have rendered, set firstRender to false
|
// We have rendered, set firstRender to false
|
||||||
firstRender = false;
|
firstRender = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Disable all shader programs for the next rendering pass
|
||||||
|
// This is placed here since it's a GLSL 2.0-specific function, and
|
||||||
|
// doesn't exist (and isn't required) for base OpenGL functionality
|
||||||
|
p_glUseProgram(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
mySurfaceIsDirty = false;
|
mySurfaceIsDirty = false;
|
||||||
|
|
Loading…
Reference in New Issue