Added openGL extension checks for GL_ARB_texture_rectangle and GL_ARB_texture_non_power_of_two. Default to GL_TEXTURE_2D if GL_TEXTURE_RECTANGLE is not available. Force power of 2 size for texture width and height if non-power of two externsion is not available.

This commit is contained in:
mjbudd77 2021-05-19 21:16:03 -04:00
parent 4ff17bcb8e
commit e8573b79bc
2 changed files with 199 additions and 30 deletions

View File

@ -61,7 +61,12 @@ ConsoleViewGL_t::ConsoleViewGL_t(QWidget *parent)
sx = 0; sy = 0;
rw = 256;
rh = 240;
txtWidth = 0;
txtHeight = 0;
mouseButtonMask = 0;
reqPwr2 = true;
textureType = GL_TEXTURE_2D;
//textureType = GL_TEXTURE_RECTANGLE;
setMinimumWidth( 256 );
setMinimumHeight( 224 );
@ -121,10 +126,32 @@ void ConsoleViewGL_t::reset(void)
return;
}
int ConsoleViewGL_t::forcePwr2(int in)
{
int out = 256;
if ( in > 1024 )
{
out = 2048;
}
else if ( in > 512 )
{
out = 1024;
}
else if ( in > 256 )
{
out = 512;
}
else
{
out = 256;
}
return out;
}
void ConsoleViewGL_t::buildTextures(void)
{
int w, h;
glEnable(GL_TEXTURE_RECTANGLE);
if ( gltexture )
{
@ -132,26 +159,125 @@ void ConsoleViewGL_t::buildTextures(void)
gltexture=0;
}
glGenTextures(1, &gltexture);
//printf("Linear Interpolation on GL Texture: %s \n", linearFilter ? "Enabled" : "Disabled");
if ( textureType == GL_TEXTURE_RECTANGLE )
{
printf("Using GL_TEXTURE_RECTANGLE\n");
glEnable(GL_TEXTURE_RECTANGLE);
glGenTextures(1, &gltexture);
//printf("Linear Interpolation on GL Texture: %s \n", linearFilter ? "Enabled" : "Disabled");
glBindTexture( GL_TEXTURE_RECTANGLE, gltexture);
glBindTexture( GL_TEXTURE_RECTANGLE, gltexture);
glTexParameteri( GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, linearFilter ? GL_LINEAR : GL_NEAREST );
glTexParameteri( GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, linearFilter ? GL_LINEAR : GL_NEAREST );
glTexParameteri( GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, linearFilter ? GL_LINEAR : GL_NEAREST );
glTexParameteri( GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, linearFilter ? GL_LINEAR : GL_NEAREST );
glTexParameteri( GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
w = nes_shm->video.ncol;
h = nes_shm->video.nrow;
txtWidth = w = nes_shm->video.ncol;
txtHeight = h = nes_shm->video.nrow;
glTexImage2D( GL_TEXTURE_RECTANGLE, 0,
GL_RGBA8, w, h, 0,
GL_BGRA, GL_UNSIGNED_BYTE, 0 );
glTexImage2D( GL_TEXTURE_RECTANGLE, 0,
GL_RGBA8, w, h, 0,
GL_BGRA, GL_UNSIGNED_BYTE, 0 );
}
else
{
printf("Using GL_TEXTURE_2D\n");
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &gltexture);
//printf("Linear Interpolation on GL Texture: %s \n", linearFilter ? "Enabled" : "Disabled");
glBindTexture( GL_TEXTURE_2D, gltexture);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linearFilter ? GL_LINEAR : GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, linearFilter ? GL_LINEAR : GL_NEAREST );
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 ( reqPwr2 )
{
txtWidth = w = forcePwr2( nes_shm->video.ncol );
txtHeight = h = forcePwr2( nes_shm->video.nrow );
}
else
{
txtWidth = w = nes_shm->video.ncol;
txtHeight = h = nes_shm->video.nrow;
}
glTexImage2D( GL_TEXTURE_2D, 0,
GL_RGBA8, w, h, 0,
GL_BGRA, GL_UNSIGNED_BYTE, 0 );
}
//printf("Texture Built: %ix%i\n", w, h);
}
void ConsoleViewGL_t::chkExtnsGL(void)
{
int i, j, NumberOfExtensions = 0;
char extName[256];
const GLubyte *c;
glGetIntegerv(GL_NUM_EXTENSIONS, &NumberOfExtensions);
printf("Number of GL Externsions: %i \n", NumberOfExtensions );
c = glGetString( GL_VERSION );
if ( c != NULL )
{
printf("GL Version: %s \n", c );
}
c = glGetString( GL_EXTENSIONS );
if ( c != NULL )
{
i=0; j=0;
while ( c[i] != 0 )
{
j=0;
while ( isspace(c[i]) ) i++;
if ( isalnum(c[i]) || (c[i] == '_') )
{
while ( isalnum(c[i]) || (c[i] == '_') )
{
extName[j] = c[i]; i++; j++;
}
extName[j] = 0;
}
else
{
// Something is wrong if this is hit
break;
}
if ( j > 0 )
{
//printf("%s\n", extName );
if ( strcmp( extName, "GL_ARB_texture_rectangle" ) == 0 )
{
printf("GL Has: %s\n", extName );
textureType = GL_TEXTURE_RECTANGLE;
}
else if ( strcmp( extName, "GL_ARB_texture_non_power_of_two" ) == 0 )
{
printf("GL Has: %s\n", extName );
reqPwr2 = false;
}
}
while ( isspace(c[i]) ) i++;
}
}
}
void ConsoleViewGL_t::initializeGL(void)
{
//printf("initializeGL\n");
@ -161,6 +287,7 @@ void ConsoleViewGL_t::initializeGL(void)
//QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
chkExtnsGL();
//printf("GL Init!\n");
buildTextures();
@ -432,28 +559,64 @@ void ConsoleViewGL_t::paintGL(void)
glDisable(GL_DEPTH_TEST);
glClearColor( 0.0, 0.0f, 0.0f, 0.0f); // Background color to black.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_RECTANGLE);
glBindTexture(GL_TEXTURE_RECTANGLE, gltexture);
glTexSubImage2D(GL_TEXTURE_RECTANGLE, 0,
0, 0, texture_width, texture_height,
GL_BGRA, GL_UNSIGNED_BYTE, localBuf );
glBegin(GL_QUADS);
glTexCoord2f( l, b); // Bottom left of picture.
glVertex2f( 0.0, 0.0f); // Bottom left of target.
if ( textureType == GL_TEXTURE_RECTANGLE )
{
glDisable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_RECTANGLE);
glBindTexture(GL_TEXTURE_RECTANGLE, gltexture);
glTexSubImage2D(GL_TEXTURE_RECTANGLE, 0,
0, 0, texture_width, texture_height,
GL_BGRA, GL_UNSIGNED_BYTE, localBuf );
glBegin(GL_QUADS);
glTexCoord2f( l, b); // Bottom left of picture.
glVertex2f( 0.0, 0.0f); // Bottom left of target.
glTexCoord2f(r, b);// Bottom right of picture.
glVertex2f( rw, 0.0f); // Bottom right of target.
glTexCoord2f(r, t); // Top right of our picture.
glVertex2f( rw, rh); // Top right of target.
glTexCoord2f(l, t); // Top left of our picture.
glVertex2f( 0.0f, rh); // Top left of target.
glEnd();
}
else
{
float x1, y1, x2, y2;
glTexCoord2f(r, b);// Bottom right of picture.
glVertex2f( rw, 0.0f); // Bottom right of target.
x1 = 0.0; y1 = 1.0;
x2 = 1.0; y2 = 0.0;
glTexCoord2f(r, t); // Top right of our picture.
glVertex2f( rw, rh); // Top right of target.
glTexCoord2f(l, t); // Top left of our picture.
glVertex2f( 0.0f, rh); // Top left of target.
glEnd();
x2 = (float)texture_width / (float)txtWidth;
y1 = (float)texture_height / (float)txtHeight;
glDisable(GL_TEXTURE_RECTANGLE);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, gltexture);
glTexSubImage2D(GL_TEXTURE_2D, 0,
0, 0, texture_width, texture_height,
GL_BGRA, GL_UNSIGNED_BYTE, localBuf );
glBegin(GL_QUADS);
glTexCoord2f( x1, y1); // Bottom left of picture.
glVertex2f( 0.0, 0.0f); // Bottom left of target.
glTexCoord2f( x2, y1);// Bottom right of picture.
glVertex2f( rw, 0.0f); // Bottom right of target.
glTexCoord2f( x2, y2); // Top right of our picture.
glVertex2f( rw, rh); // Top right of target.
glTexCoord2f( x1, y2); // Top left of our picture.
glVertex2f( 0.0f, rh); // Top left of target.
glEnd();
}
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_RECTANGLE);

View File

@ -46,6 +46,8 @@ class ConsoleViewGL_t : public QOpenGLWidget, protected QOpenGLFunctions
void buildTextures(void);
void calcPixRemap(void);
void doRemap(void);
void chkExtnsGL(void);
int forcePwr2( int in );
double devPixRatio;
double aspectRatio;
@ -59,11 +61,15 @@ class ConsoleViewGL_t : public QOpenGLWidget, protected QOpenGLFunctions
int sy;
int rw;
int rh;
int txtWidth;
int txtHeight;
GLuint gltexture;
bool linearFilter;
bool forceAspect;
bool autoScaleEna;
bool reqPwr2;
unsigned int textureType;
unsigned int mouseButtonMask;
uint32_t *localBuf;