Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: SetPixelFormat always returns false?

  1. #1
    Intern Newbie
    Join Date
    Jul 2011
    Location
    United States
    Posts
    31

    SetPixelFormat always returns false?

    Hello everyone! I am teaching myself OpenGL, and I am trying to just get a very basic, beginner OpenGL application up and running. However, I am running into a problem, and that is that the function SetPixelFormat always returns false. Here is my code (The specific code in question is in the function GameInitialize):

    Code :
     
    //-----------------------------------------------------------------
    // Include Files
    //-----------------------------------------------------------------
    #include "GameClient.h"
     
    //-----------------------------------------------------------------
    // Game Engine Functions
    //-----------------------------------------------------------------
    BOOL GameInitialize(HINSTANCE hInstance)
    {
      // Create the game engine
      // NOTE: _pGame is a global variable from GameClient.h
      _pGame = new GameEngine(hInstance, TEXT("Game Skeleton"),
                              TEXT("Game Skeleton"));
      if (_pGame == NULL)
      {
    	return FALSE;
      }
     
      // Set the frame rate
      _pGame->SetFrameRate(15);
     
    	//Perform OpenGL Initilization
     
    	HDC   hDC;
    	HWND  hWindow = _pGame->GetWindow();
    	hDC = GetDC(hWindow);
     
     
    		//Set up the Pixel Format
    		PIXELFORMATDESCRIPTOR pfd;
    		memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
    		pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
    		pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    		pfd.nVersion = 1; //Version
    		pfd.iPixelType = PFD_TYPE_RGBA; //Color Type
    		pfd.cColorBits = 32; //Desired Color Depth
    		pfd.cDepthBits = 24; //Depth Buffer
    		pfd.iLayerType = PFD_MAIN_PLANE; //Main layer
     
    		//Choose the best matching pixel format, return index
    		int pixelFormat = -1234;
    		pixelFormat = ChoosePixelFormat(hDC, &pfd);
     
    		//Test the pixel format
    		if (pixelFormat == -1234)
    		{
    			MessageBox(NULL, "OpenGL could not select a pixel format.", "An error occurred", MB_ICONERROR | MB_OK);
    		}
     
    		//Set pixel format to device context and test
    		if(!SetPixelFormat(hDC, pixelFormat, &pfd))
    		{
    			MessageBox(NULL, "A pixel format could not be set.", "An error occurred", MB_ICONERROR | MB_OK);
    		}
     
    		//Set up a Rendering Context
    		//Set the version we want. In this case, it is version 3.0
     
    		int attribs[] = {
    			WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
    			WGL_CONTEXT_MINOR_VERSION_ARB, 0,
    			0}; //Zero signifies the end of the array
     
     
    		//Create a temporary context so that we can get a pointer to the function we want.
    		HGLRC tempContext = wglCreateContext(hDC);
    		//Make the temporary context current
    		wglMakeCurrent(hDC, tempContext);
     
    		//Grabe the function pointer we want
     
    		PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
    		wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
     
     
    		//Test versions. If this is null, then 3.0 is not supported.	
    		if(!wglCreateContextAttribsARB)
    		{
    			MessageBox(NULL, "OpenGL 3.0 is not supported", "An error occurred", MB_ICONERROR | MB_OK);
     
    			//Because OpenGL 3.0 is not supported, wglCreateContextAttribsARB cannot be used to
    			//create our context. We instead will have to use wglCreateContext. This means that
    			//our temporary context is now our main context.
     
    			//Deselect the temporary context
    			wglMakeCurrent(hDC, NULL);
     
    			//Create the new context
    			renderContext = wglCreateContext(hDC);
     
    		}
    		else
    		{
    			//Create a new OpenGL 3.0 context
    			renderContext = wglCreateContextAttribsARB(hDC, 0, attribs);
     
    			//Deselect the temp context
    			wglMakeCurrent(hDC, NULL);
     
    			//Delete the temporary context.
    			wglDeleteContext(tempContext);
    		}
     
    		//Check the Rendering Context
    		if(!renderContext)
    		{
    			MessageBox(NULL, "Failed to create a Rendering Context", "An error occurred", MB_ICONERROR | MB_OK);
    		}
     
    		//Make the new context active and test.
    		if(!(wglMakeCurrent(hDC, renderContext)))
    		{
    			MessageBox(NULL, "Rendering Context could not be made active.", "An error occurred", MB_ICONERROR | MB_OK);
    		}
     
    		//OpenGL Drawing initialization
    		//Enable Depth testing
    		glEnable(GL_DEPTH_TEST);
     
    		//Set background
    		glClearColor(0.75f, 0.5f, 0.5f, 0.5f);
     
    	glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix
    	glLoadIdentity();	
     
    	glMatrixMode(GL_MODELVIEW);						// Select The Modelview Matrix
    	glLoadIdentity();	
     
    	ReleaseDC(hWindow, hDC);
     
      return TRUE;
    }
     
    void GameStart(HWND hWindow)
    {
      // Seed the random number generator
      srand(GetTickCount());
     
    }
     
    void GameDeactivate(HWND hWindow)
    {
      HDC   hDC;
      RECT  rect;
     
      // Draw deactivation text on the game screen
      GetClientRect(hWindow, &rect);
      hDC = GetDC(hWindow);
      DrawText(hDC, TEXT("Deactivated!"), -1, &rect,
        DT_SINGLELINE | DT_CENTER | DT_VCENTER);
      ReleaseDC(hWindow, hDC);
    }
     
    void GamePaint(HDC hDC)
    {
     
    }
     
    void GameCycle()
    {
      HDC   hDC;
      HWND  hWindow = _pGame->GetWindow();
     
      hDC = GetDC(hWindow);
     
      //OpenGL drawing
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    	glLoadIdentity();
     
    	glBegin(GL_TRIANGLES);
    		glColor3f(1.0f, 0.0f, 0.0f);
    		glVertex3f(-0.5f, -0.5f, -2.0f);
    		glColor3f(1.0f, 1.0f, 0.0f);
    		glVertex3f(0.5f, -0.5f, -2.0f);
    		glColor3f(0.0f, 0.0f, 1.0f);
    		glVertex3f(0.0f, 0.5f, -2.0f);
    	glEnd();
     
     
    	//SwapBuffers(hDC);
    	ReleaseDC(hWindow, hDC);
     
    }
     
    void GameEnd()
    {
      // Cleanup the game engine
      delete _pGame;
    }
     
    void GameActivate(HWND hWindow)
    {
      HDC   hDC;
      RECT  rect;
     
      // Draw activation text on the game screen
      GetClientRect(hWindow, &rect);
      hDC = GetDC(hWindow);
      DrawText(hDC, TEXT("Activated!"), -1, &rect,
        DT_SINGLELINE | DT_CENTER | DT_VCENTER);
     
     
      ReleaseDC(hWindow, hDC);
    }

    I know that is the problem because I am getting message boxes popping up stating that The pixel format could not be set, then that OpenGL 3.0 is not supported, then that A rendering context could not be created, and finally that the rendering context could not be made active. I feel like these all stem from the fact that I can't set a pixel format.

    I know that the right way to do things is to change the values used in the Pixel Format Descriptor since each card supports different things. However, this code is failing on a machine with an Nvidia GTX 470, but I get no error messages when I run it on a laptop with integrated graphics. That leads me to believe that my problem doesn't stem from the settings I have selected in my PFD - and besides, I thought that ChoosePixelFormat was supposed to do a little bit of the leg work and select and appropriate format anyway.

    (By the way, although this code generates none of the error message boxes I have programmed in on the laptop, the OpenGL aspect of the project does not work on either machine. I simply get a blank white screen.)

    Does anyone have any suggestions what could be going wrong? I'm trying to learn to do this the right way, so absolutely any information would be appreciated. I'm following with the book "Beginning OpenGL Game Programming, Second Edition" by Luke Benstead, and this is pretty much exactly how he shows to set up OpenGL.

  2. #2
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,723

    Re: SetPixelFormat always returns false?

    if (pixelFormat == -1234)
    What is this and where does it come from? If ChoosePixelFormat fails to find one, it returns zero, not -1234.

  3. #3
    Intern Newbie
    Join Date
    Jul 2011
    Location
    United States
    Posts
    31

    Re: SetPixelFormat always returns false?

    Quote Originally Posted by Alfonse Reinheart
    if (pixelFormat == -1234)
    What is this and where does it come from? If ChoosePixelFormat fails to find one, it returns zero, not -1234.
    Ok. I didn't know if the function would return 0 if it couldn't choose a good format, so I initially set pixelFormat to some number I knew it wouldn't use. Then after I call ChoosePixelFormat if the variable is still that number, I knew the function didn't change it at all. Now that i know that, I can change it and make this much better. Thanks!

    EDIT: I made the changes and now test pixelFormat to see if it is zero. The program's behavior hasn't changed, though. My message boxes are popping up stating that the pixel format could not be set, that OpenGL 3.0 is not supported, and that a rendering context could neither be created nor made active.

  4. #4
    Intern Newbie
    Join Date
    Jul 2011
    Location
    United States
    Posts
    31

    Re: SetPixelFormat always returns false?

    Update: I've tried to play with the settings in my Pixel Format Descriptor, but I still only get false back from SetPixelFormat. Here is the new pfd I'm using:

    Code :
    //Set up the Pixel Format
    		PIXELFORMATDESCRIPTOR pfd;
    		//memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
    		ZeroMemory(&pfd, sizeof(pfd));
    		pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
    		pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    		pfd.nVersion = 1; //Version
    		pfd.iPixelType = PFD_TYPE_RGBA; //Color Type
    		pfd.cColorBits = 24; //Desired Color Depth
    		pfd.cDepthBits = 16; //Depth Buffer
    		pfd.iLayerType = PFD_MAIN_PLANE; //Main layer

    Still no dice. The program is able to choose a format, but it cannot actually set it. What could be causing this?

  5. #5
    Advanced Member Frequent Contributor
    Join Date
    Mar 2009
    Location
    Singapore
    Posts
    802

    Re: SetPixelFormat always returns false?

    Since ur pixeltype is RGBA, shouldn't cColorBits be 32? and the depthbits 24?
    Code :
    pfd.cColorBits = 32; //Desired Color Depth
    pfd.cDepthBits = 24; //Depth Buffer
    Regards,
    Mobeen

  6. #6
    Intern Newbie
    Join Date
    Jul 2011
    Location
    United States
    Posts
    31

    Re: SetPixelFormat always returns false?

    Quote Originally Posted by mobeen
    Since ur pixeltype is RGBA, shouldn't cColorBits be 32? and the depthbits 24?
    Code :
    pfd.cColorBits = 32; //Desired Color Depth
    pfd.cDepthBits = 24; //Depth Buffer
    That's what I originally had it listed as, but it still cannot set the pixel format even with those numbers.

  7. #7
    Advanced Member Frequent Contributor
    Join Date
    Jan 2007
    Posts
    965

    Re: SetPixelFormat always returns false?

    What you specify in your PFD shouldn't matter (so far as this problem is concerned) as ChoosePixelFormat should always give a best match rather than needing to be absolutely constrained to an exact match.

    What are you getting back for the value of pixelFormat from ChoosePixelFormat? And have you tried putting it into DescribePixelFormat to see what values and flags it has? This would be a useful exercise as it would give you info on the format that SetPixelFormat is failing on.

    It's also possible to loop through the pixelformats available on your machine and confirm that your driver actually does expose valid formats. Note here that pixel format numbers are 1-based, not 0-based, so code might look something like this:
    Code :
    for (int pfnum = 1; ; pfnum++)
    {
       // return 0 = failed
       if (!DescribePixelFormat (hdc, pfnum, sizeof (PIXELFORMATDESCRIPTOR), &pfd)) break;
     
       // store or output info relating to this pixelformat
    }

  8. #8
    Intern Newbie
    Join Date
    Jul 2011
    Location
    United States
    Posts
    31

    Re: SetPixelFormat always returns false?

    Quote Originally Posted by mhagain
    What you specify in your PFD shouldn't matter (so far as this problem is concerned) as ChoosePixelFormat should always give a best match rather than needing to be absolutely constrained to an exact match.

    What are you getting back for the value of pixelFormat from ChoosePixelFormat? And have you tried putting it into DescribePixelFormat to see what values and flags it has? This would be a useful exercise as it would give you info on the format that SetPixelFormat is failing on.

    It's also possible to loop through the pixelformats available on your machine and confirm that your driver actually does expose valid formats. Note here that pixel format numbers are 1-based, not 0-based, so code might look something like this:
    Code :
    for (int pfnum = 1; ; pfnum++)
    {
       // return 0 = failed
       if (!DescribePixelFormat (hdc, pfnum, sizeof (PIXELFORMATDESCRIPTOR), &pfd)) break;
     
       // store or output info relating to this pixelformat
    }
    Thank you for your reply! I didn't know about DescribePixelFormat, but I'll use it to get more information on my problem.

    I'm interested in seeing what the results are because if my understanding is correct, ChoosePixelFormat does the leg work of finding a pixel format that will be good on my machine. It would seem, then, that if it is successful, feeding that result into SetPixelFormat would be sure to work. I guess what i'm saying is that it surprises me that the failure is happening in SetPixelFormat and not ChoosePixelFormat. But that could be because I don't completely know what I'm doing yet.

  9. #9
    Intern Newbie
    Join Date
    Jul 2011
    Location
    United States
    Posts
    31

    Re: SetPixelFormat always returns false?

    Ok. I found out that the index of the pixel format that ChoosePixelFormat returns is 7. I also did a little bit of digging, and found out that the cColorBits of pixelFormat 7 is 32, and the cDepthBits is 24, exactly as I specified in my code.

    Doesn't this mean that my drivers are, indeed, exposing formats to be used?

  10. #10
    Advanced Member Frequent Contributor
    Join Date
    Jan 2007
    Posts
    965

    Re: SetPixelFormat always returns false?

    Check the flags; these will be a bitwise mask of the values given here: http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx

    So you need code like:
    Code :
    if (pfd.dwFlags & PFD_FLAG_NAME_BLAH) // do something

    Check 'em all and let us know what you get for 7.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •