Jump to content
  • Advertisement
Sign in to follow this  
codetemplar

OpenGL gldrawpixels scaling

This topic is 2741 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all,

I have written a Master system emulator and I am using OpenGL to render the display buffer to an sdl window. Everything works correctly but I want to improve it. Here is my current code



?

bool MasterSystem::CreateSDLWindow( )

{

m_Width = 300 ;

m_Height = 200 ;

if( SDL_Init( SDL_INIT_EVERYTHING ) < 0 )

{

return false ;

}

if( SDL_SetVideoMode( m_Width, m_Height, 8, SDL_OPENGL ) == NULL )

{

return false ;

}

InitGL();

SDL_WM_SetCaption( "Sega Master System", NULL );

return true ;

}

?

?

void MasterSystem::InitGL( )

{

glViewport(0, 0, m_Width, m_Height);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

glOrtho(0, m_Width, m_Height, 0, -1.0, 1.0);

glClearColor(0, 0, 0, 1.0);

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glShadeModel(GL_FLAT);

glEnable(GL_TEXTURE_2D);

glDisable(GL_DEPTH_TEST);

glDisable(GL_CULL_FACE);

glDisable(GL_DITHER);

glDisable(GL_BLEND);

}

?

void MasterSystem::RenderGame( )

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();

glRasterPos2i(-1, 1);

glPixelZoom(1, -1);

glDrawPixels(m_Width, m_Height, GL_RGB, GL_UNSIGNED_BYTE, m_Emulator->GetGraphicChip().m_ScreenStandard);

SDL_GL_SwapBuffers( ) ;

}



Where m_Emulator->GetGraphicChip().m_ScreenStandard is a three-dimensional array defined as:

unsigned char m_ScreenStandard[ 200][ 300][3] ;

as I said everything is working perfectly I would just like to improve its functionality.

1. I would like to be able to change the size of the sdl window to be either x2 or x3 bigger and to get OpenGL to render to this new window size without having to change the variable m_ScreenStandard. So if I changed m_width and m_height to be 600 and 400 then the SDL window should double in size but the variable m_ScreenStandard remains 200x 300x3. So I imagine that I will have to do some kind of scaling in the render game function so the buffer gets rendered to the entire window. How can I modify the above code to do this?

2. The second piece of functionality I would like to be able to add is similar to the first except the user can resize the sdl window themselves by dragging the Windows border and opengl scales to fit the new screen size. How can I modify the above code to do this?

Thank you very much for any help

Share this post


Link to post
Share on other sites
Advertisement
Then don't use glDrawPixels. Draw a textured quad.
Create a texture first and everytime m_ScreenStandard[ 200][ 300][3] changes, update it with glTexSubImage2D.

I don't know about SDL for resizing a window. Look into their documents.

Share this post


Link to post
Share on other sites
Thanks for the reply. I have changed my code to look like this and everything is working ok. But how do I modify it to scale?




void MasterSystem::InitGL( )
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

// Create a new texture!

glGenTextures(1, &ImageID);

// Use a GL_TEXTURE_RECTANGLE_ARB:
glBindTexture(GL_TEXTURE_RECTANGLE_ARB,ImageID); // order?
glEnable( GL_TEXTURE_RECTANGLE_ARB ); // Allow texturing!

glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

// Copy to the graphics card:
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB,
m_Width, m_Height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);

glMatrixMode (GL_PROJECTION); // needed?
glLoadIdentity (); // needed?
gluOrtho2D(0.0, 1.0, 1.0, 0.0);}


void MasterSystem::RenderGame( )
{

glLoadIdentity ();
gluOrtho2D(0.0, 1.0, 1.0, 0.0);

glClear(GL_COLOR_BUFFER_BIT);

glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, // MipMap 0
0,0,m_Width,m_Height,
GL_RGB, GL_UNSIGNED_BYTE, (const GLvoid *)m_Emulator->GetGraphicChip().m_ScreenStandard);

// Draw it! (texture rect is accessed by real coords)
glColor4f(1.0, 1.0, 1.0, 1.0); // no alpha effect unless blending enabled
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2f(0, 0);
glTexCoord2f(m_Width,0); glVertex2f(1, 0);
glTexCoord2f(m_Width,m_Height); glVertex2f(1, 1);
glTexCoord2f(0, m_Height); glVertex2f(0, 1);
glEnd();

SDL_GL_SwapBuffers(); }
}



Thanks

Share this post


Link to post
Share on other sites
x=2.0

glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2f(0, 0);
glTexCoord2f(m_Width,0); glVertex2f(x, 0);
glTexCoord2f(m_Width,m_Height); glVertex2f(x, x);
glTexCoord2f(0, m_Height); glVertex2f(0, x);
glEnd();

Share this post


Link to post
Share on other sites
glDrawPixels can do scaling OK (look at glPixelZoom) but - and this is relevant to use of a texture as well - you have selected possibly the worst performing combination of parameters. There's no such thing as a 3-component internal format, all that you're doing is saying "give me an internal format in which R, G and B are significant and set A to 255" (assuming 8 bits). Sending 3-component data makes things worse as it now has to transfer 1 byte at a time instead of being able to fast transfer in blocks of more than 1. Using GL_RGB makes things worse again as your data is not arranged in a layout that's native to the GPU. Lots of intermediate software stages and swizzling will be needed to do uploads.

Read this: http://www.opengl.org/wiki/Common_Mistakes#Texture_upload_and_pixel_reads

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!