Why I can't display anything use glViewport in this program?

Started by
3 comments, last by was2_0 17 years, 10 months ago
I have tested it for a long time, but nothing be different...

#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>

unsigned long image[16] = {
	0xFF0000FF, 0xFF0000FF, 0xFF0000FF, 0xFF0000FF,
	0xFF0000FF, 0xFF0000FF, 0xFF0000FF, 0xFF0000FF,
	0xFF0000FF, 0xFF0000FF, 0xFF0000FF, 0xFF0000FF,
	0xFF0000FF, 0xFF0000FF, 0xFF0000FF, 0xFF0000FF,
};
unsigned int texobj[1];

LRESULT CALLBACK WndProc (HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC);
void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC);

int WINAPI WinMain (HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpCmdLine,
                    int iCmdShow)
{
    WNDCLASS wc;
    HWND hWnd;
    HDC hDC;
    HGLRC hRC;        
    MSG msg;
    BOOL bQuit = FALSE;

    /* register window class */
    wc.style = CS_OWNDC;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor (NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "GLSample";
    RegisterClass (&wc);

    /* create main window */
    hWnd = CreateWindow (
      "GLSample", "OpenGL Sample", 
      WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE,
      50, 50, 256, 256,
      NULL, NULL, hInstance, NULL);

    /* enable OpenGL for the window */
    EnableOpenGL (hWnd, &hDC, &hRC);
	glEnable(GL_BLEND);
	glEnable(GL_TEXTURE_2D);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glGenTextures(1, texobj);
	glBindTexture(GL_TEXTURE_2D, texobj[0]);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
glViewport(0, 0, 256, 256);
glMatrixMode(GL_PROJECTION);
glOrtho(-0.5, 256-0.5, 256-0.5, -0.5, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
    /* program main loop */
    while (!bQuit)
    {
        /* check for messages */
        if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
        {
            /* handle or dispatch messages */
            if (msg.message == WM_QUIT)
            {
                bQuit = TRUE;
            }
            else
            {
                TranslateMessage (&msg);
                DispatchMessage (&msg);
            }
        }
        else
        {
            /* OpenGL animation code goes here */

            glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
            glClear (GL_COLOR_BUFFER_BIT);

            glBegin (GL_QUADS);
            glTexCoord2f(0.0, 0.0);glColor4f(1.0f, 1.0f, 1.0f, 1.0f);glVertex2f(0.0f, 0.0f);
            glTexCoord2f(1.0, 0.0);glColor4f(1.0f, 1.0f, 1.0f, 1.0f);glVertex2f(10.5f, 0.0f);
            glTexCoord2f(1.0, 1.0);glColor4f(1.0f, 1.0f, 1.0f, 1.0f);glVertex2f(10.5f, 10.5f);
			glTexCoord2f(0.0, 1.0);glColor4f(1.0f, 1.0f, 1.0f, 1.0f);glVertex2f(0.0f, 10.5f);
            glEnd ();

            SwapBuffers (hDC);

            Sleep (1);
        }
    }

    /* shutdown OpenGL */
    DisableOpenGL (hWnd, hDC, hRC);

    /* destroy the window explicitly */
    DestroyWindow (hWnd);

    return msg.wParam;
}

LRESULT CALLBACK WndProc (HWND hWnd, UINT message,
                          WPARAM wParam, LPARAM lParam)
{

    switch (message)
    {
    case WM_CREATE:
        return 0;
    case WM_CLOSE:
        PostQuitMessage (0);
        return 0;

    case WM_DESTROY:
        return 0;

    case WM_KEYDOWN:
        switch (wParam)
        {
        case VK_ESCAPE:
            PostQuitMessage(0);
            return 0;
        }
        return 0;

    default:
        return DefWindowProc (hWnd, message, wParam, lParam);
    }
}

void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC)
{
    PIXELFORMATDESCRIPTOR pfd;
    int iFormat;

    /* get the device context (DC) */
    *hDC = GetDC (hWnd);

    /* set the pixel format for the DC */
    ZeroMemory (&pfd, sizeof (pfd));
    pfd.nSize = sizeof (pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | 
      PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 16;
    pfd.iLayerType = PFD_MAIN_PLANE;
    iFormat = ChoosePixelFormat (*hDC, &pfd);
    SetPixelFormat (*hDC, iFormat, &pfd);

    /* create and enable the render context (RC) */
    *hRC = wglCreateContext( *hDC );
    wglMakeCurrent( *hDC, *hRC );

}

void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC)
{
    wglMakeCurrent (NULL, NULL);
    wglDeleteContext (hRC);
    ReleaseDC (hWnd, hDC);
}

It run expectly if I remove the line:

glViewport(0, 0, 256, 256);
I tried testing the program to use glViewport correctly, but failed...
Advertisement
I have tested it for you. I don't know a lot of OGL though...
I change your code:

glOrtho(-0.5, 256-0.5, 256-0.5, -0.5, -1, 1);

to:

glOrtho(-0.5, 256-0.5, -0.5, 256-0.5, -1, 1);

then it display the red rect at lower left of window.(I can't make it at upper left though...)

hope that helpful...
Just so you know the 0.5 offset isn't necessary for pixel-perfect graphics in OpenGL.
Quote:Original post by Boder
Just so you know the 0.5 offset isn't necessary for pixel-perfect graphics in OpenGL.

Necessary if you're drawing lines and points, not necessary if you're drawing triangles. The rules which specifies which pixels are drawn are different for point/lines and triangles. One needs the offset, one doesn't. Or rather, it's needed/not needed only if you want to hit a pixel center with integer coordinates.
Quote:Original post by was2_0
I tried testing the program to use glViewport correctly, but failed...

Becuase the size of the window is not really what you think it is. The size you specify in CreateWindow includes borders and menu bars, so the effective area of you use for OpenGL is smaller than 256x256. Therefore, with a 256x256 viewport, the square you draw is effectively behind the title bar.

Quick solution; let Windows tell you the size of the client area instead of assume it's size.

Add two global variables.
int viewportwidth;int viewportheight;

Add a WM_SIZE to the message callback. This message holds the actual size of the client area.
case WM_SIZE:	viewportwidth = LOWORD(lParam);	viewportheight = HIWORD(lParam);	return 0;

And make some adjustments to the code just befor the message and rendering loop.
glViewport(0, 0, viewportwidth, viewportheight);glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(0, viewportwidth, viewportheight, 0, -1, 1);glMatrixMode(GL_MODELVIEW);glLoadIdentity();

If you want to specify a size of the client area instead of the window itself, check out AdjustWindowRect.
Quote:Original post by Brother Bob
Quote:Original post by Boder
Just so you know the 0.5 offset isn't necessary for pixel-perfect graphics in OpenGL.

Necessary if you're drawing lines and points, not necessary if you're drawing triangles. The rules which specifies which pixels are drawn are different for point/lines and triangles. One needs the offset, one doesn't. Or rather, it's needed/not needed only if you want to hit a pixel center with integer coordinates.
Quote:Original post by was2_0
I tried testing the program to use glViewport correctly, but failed...

Becuase the size of the window is not really what you think it is. The size you specify in CreateWindow includes borders and menu bars, so the effective area of you use for OpenGL is smaller than 256x256. Therefore, with a 256x256 viewport, the square you draw is effectively behind the title bar.

Quick solution; let Windows tell you the size of the client area instead of assume it's size.

Add two global variables.
int viewportwidth;int viewportheight;

Add a WM_SIZE to the message callback. This message holds the actual size of the client area.
case WM_SIZE:	viewportwidth = LOWORD(lParam);	viewportheight = HIWORD(lParam);	return 0;

And make some adjustments to the code just befor the message and rendering loop.
glViewport(0, 0, viewportwidth, viewportheight);glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(0, viewportwidth, viewportheight, 0, -1, 1);glMatrixMode(GL_MODELVIEW);glLoadIdentity();

If you want to specify a size of the client area instead of the window itself, check out AdjustWindowRect.

THANKS!!!

This topic is closed to new replies.

Advertisement