# How to diplay proportianal correct texture image?

(I’m completely new to OpenGL…)

I’m using orthographic mode
this is (essentially) the code

GLsizei w = {width of view};
GLsizei h = {height of view};

GLsizei iw = {image width};
GLsizei ih = {image height};

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);

glTranslatef(0.0f,0.0f,0.0f);
glRotatef(0,0.0f,0.0f,1.0f);

glColor3f(1.0f,1.0f,1.0f);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,TexID1);

glBegin(GL_POLYGON);
glTexCoord2f(0.0f,1.0f); glVertex3f (-1.00, -1.00, 0.0);
glTexCoord2f(1.0f,1.0f); glVertex3f (+1.00, -1.00, 0.0);
glTexCoord2f(1.0f,0.0f); glVertex3f (+1.00, +1.00, 0.0);
glTexCoord2f(0.0f,0.0f); glVertex3f (-1.00, +1.00, 0.0);
glEnd();

This will display a texture that stretches and fills the entire screen space.

How do I display the texture so it is proportionally correct?
(based on textures actual width and height)

There are a few things to consider here.

First, you want to make sure your viewport is using square pixels. For that, get the aspect ratio of the viewport and set glOrtho to use it. That gives us a viewport that might be 1.33 wide and will always be 1.0 tall. Next you need to get the image’s aspect ratio:

``````double viewportAspect = (double)w / h;
glOrtho( 0.0, viewportAspect, 0.0, 1.0 );

double imageAspect = (double)iw / ih;
``````

Now what to do with this? You need to consider all the situations. Your window might be narrow (aspect ratio < 1) or it might be wide (aspect ratio >= 1). Next you need to make the same consideration for your image. Is the image aspect ratio < 1 or >= 1? You can now think of both your viewport and image as simple ratios where one dimension is 1.0 and the other is the ratio whatever it is, rather than the absolute dimensions of the pixels. Okay that was a convoluted explanation, how about some code?

``````float quadWidth = (float)viewportAspect;
``````

This is fine for most cases, except when the image is narrower than the viewport. There’s probably a more efficient way to do it, but for the sake of this let’s just do:

``````if( quadHeight > 1.0f )
{
}
``````

Lastly we need to create the quad with the right dimensions:

``````glBegin(GL_POLYGON);
glEnd();
``````

I -think- that’ll work for you. I’m not in a position to test it at the moment. Give it a try and let me know how it works. You might need to divide quadWidth and quadHeight by 2.0f first.

Thanks will try out.

Here is project

http://www.mediafire.com/file/btlmi5cez45/OrthoTest.zip

In Render.h is code

void Render(void)
{
GLuint TexID1; // Handles to our textures

``````double w = 800;
double h = 600;
double iw = 1024;
double ih = 1024;

//glViewport(0,0,w,h);

glViewport(0,0,800,600);

// This loop will run until Esc is pressed
while(RunLevel)
{
if(Keys[27]) // Esc Key
RunLevel=0;

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);

double viewportAspect = (double)w / h;
glOrtho( 0.0, viewportAspect, 0.0, 1.0, -1.0, 1.0 );

double imageAspect = (double)iw / ih;

glColor3f(1.0f,1.0f,1.0f);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,TexID1);

glBegin(GL_POLYGON);
glEnd();

SwapBuffers(GLDC);
}

glDeleteTextures(1,&TexID1);
}
``````

The code looks fine and makes sense, but I’m not getting the results.

Instead of getting whole penguin I get part of it.

It’s 1024x1024 image…(I scale it to that size so the penguin is actually not as fat as he looks in original image, I wanted to test with square image first)

The code looks correct, I should have gotten this…
What did I do wrong?

Guess it should be this:
glTexCoord2f(0.0f,1.0f); glVertex3f (0.0f, 0.0f, 0.0);
glTexCoord2f(1.0f,1.0f); glVertex3f ( quadWidth, 0.0f, 0.0);

I get the penguin moved to lower left quadrant…still not working.

I’m also new to OpenGL but you seem to be using glOrtho not correctly.

Also, you create a window of 1280X1024 but specify the viewport as 800X600.

This is the first part of your render function. Only replacing yours by this one should make this work.

``````
GLuint TexID1;      // Handles to our textures

double w = 1280;
double h = 1024;
double iw = 1024;
double ih = 1024;

//glViewport(0,0,w,h);

glViewport(0,0,1280,1024);

// This loop will run until Esc is pressed
while(RunLevel)
{
if(Keys[27]) // Esc Key
RunLevel=0;

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);

double viewportAspect = (double)w / h;
//glOrtho( 0.0, viewportAspect, 0.0, 1.0, -5.0, 5.0 );
glOrtho(0, w, 0, h, -5, 1);

double imageAspect = (double)iw / ih;

glMatrixMode(GL_MODELVIEW);
glColor3f(1.0f,1.0f,1.0f);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,TexID1);

glBegin(GL_POLYGON);
glTexCoord2f(0.0f,1.0f); glVertex3f (0.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f,1.0f); glVertex3f (iw, 0.0f, 0.0f);
glTexCoord2f(1.0f,0.0f); glVertex3f (iw, ih, 0.0f);
glTexCoord2f(0.0f,0.0f); glVertex3f (0.0f, ih, 0.0f);
glEnd();

SwapBuffers(GLDC);
}

glDeleteTextures(1,&TexID1);
}

``````

If you want to do this in a 800X600 viewport, you might want to change this : if(!StartGL(1280,1024,32)) and then the render code.

Hope this helps.

Thanks, it seems to be working…will try different images…

Ack…

It “works”, but is not generic enough if you use different sized (width / height) non-square images.

This is harder than I thought.

It is very possible that when you load a 50 X 64 image (for example), it considers it as a 64X64 texture. This is because a lot of videocard deals with power of 2 texture data.

So with my example of 50X64 texture, its possible that the data is loaded in a 64X64 so you have to compensate the texture UV to reflect your image correctly.

I don’t know if this is your problem but I saw that happen before.

This seems to work for the general case
(when iw > ih)

Will modify to handle both case of iw>ih and ih>iw

void Render(void)
{
GLuint TexID1; // Handles to our textures

``````int screenWidth = GetSystemMetrics(SM_CXSCREEN);
int screenHeight = GetSystemMetrics(SM_CYSCREEN);

double w = screenWidth;
double h = screenHeight;

double iw = 832;
double ih = 308;

// This loop will run until Esc is pressed
while(RunLevel)
{
if(Keys[27]) // Esc Key
RunLevel=0;

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);

double viewportAspect = (double)w / h;
glOrtho( -viewportAspect, viewportAspect, -1.0, 1.0, -1.0, 1.0  );

double imageAspect = (double)ih / iw;

glMatrixMode(GL_MODELVIEW);
glColor3f(1.0f,1.0f,1.0f);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,TexID1);

glBegin(GL_POLYGON);