⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 openglapp.dpr

📁 自己刚刚作的一个关于opengl的小离子
💻 DPR
📖 第 1 页 / 共 3 页
字号:

		// Next, we just call our normal gluPerspective() function, exactly as we did on startup.
		// This is to multiply the perspective matrix by the pick matrix we created up above. 

		gluPerspective(45.0, viewportCoords[2]/viewportCoords[3], 0.5, 150.0);
		
		glMatrixMode(GL_MODELVIEW);						// Go back into our model view matrix
	
		glDraw();									// Now we render into our selective mode to pinpoint clicked objects

		// If we return to our normal render mode from select mode, glRenderMode returns
		// the number of objects that were found in our specified region (specified in gluPickMatrix())

		objectsFound := glRenderMode(GL_RENDER);			// Return to render mode and get the number of objects found

		glMatrixMode(GL_PROJECTION);					// Put our projection matrix back to normal.
	glPopMatrix();										// Stop effecting our projection matrix

	glMatrixMode(GL_MODELVIEW);							// Go back to our normal model view matrix

	// PHEW!  That was some stuff confusing stuff.  Now we are out of the clear and should have
	// an ID of the object we clicked on.  objectsFound should be at least 1 if we found an object.

	if (objectsFound > 0) then
	begin
		// If we found more than one object, we need to check the depth values
		// of all the objects found.  The object with the LEAST depth value is
		// the closest object that we clicked on.  Depending on what you are doing,
		// you might want ALL the objects that you clicked on (if some objects were
		// behind the closest one), but for this tutorial we just care about the one
		// in front.  So, how do we get the depth value?  Well, The selectionBuffer
		// holds it.  For every object there is 4 values.  The first value is
		// "the number of names in the name stack at the time of the event, followed 
		// by the minimum and maximum depth values of all vertices that hit since the 
		// previous event, then followed by the name stack contents, bottom name first." - MSDN
		// The only ones we care about are the minimum depth value (the second value) and
		// the object ID that was passed into glLoadName() (This is the fourth value).
		// So, [0 - 3] is the first object's data, [4 - 7] is the second object's data, etc...
		// Be carefull though, because if you are displaying 2D text in front, it will
		// always find that as the lowest object.  So make sure you disable text when
		// rendering the screen for the object test.  I use a flag for RenderScene().
		// So, lets get the object with the lowest depth!		

		// Set the lowest depth to the first object to start it off.
		// 1 is the first object's minimum Z value.
		// We use an unsigned int so we don't get a warning with selectBuffer below.
		lowestDepth := selectBuffer[1];

		// Set the selected object to the first object to start it off.
		// 3 is the first object's object ID we passed into glLoadName().
		selectedObject := selectBuffer[3];

		// Go through all of the objects found, but start at the second one
		for i := 1 to objectsFound - 1 do
		begin
			// Check if the current objects depth is lower than the current lowest
			// Notice we times i by 4 (4 values for each object) and add 1 for the depth.
			if (selectBuffer[(i * 4) + 1] < lowestDepth) then
			begin
				// Set the current lowest depth
				lowestDepth := selectBuffer[(i * 4) + 1];

				// Set the current object ID
				selectedObject := selectBuffer[(i * 4) + 3];
			end
		end;
		
		// Return the selected object
		result := selectedObject;
                exit;
	end;

	// We didn't click on any objects so return 0
	result := 0;											
end;


{------------------------------------------------------------------}
{  Initialise OpenGL                                               }
{------------------------------------------------------------------}
procedure glInit();
begin
  glClearColor(0.0, 0.0, 0.0, 0.0); 	   // Black Background
  glShadeModel(GL_SMOOTH);                 // Enables Smooth Color Shading
  glClearDepth(1.0);                       // Depth Buffer Setup
  glEnable(GL_DEPTH_TEST);                 // Enable Depth Buffer
  glDepthFunc(GL_LESS);		           // The Type Of Depth Test To Do

  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);   //Realy Nice perspective calculations

  glEnable(GL_TEXTURE_2D);                     // Enable Texture Mapping

  LoadTexture('Sun.bmp', SunTex, false);				// Load "Sun.bmp" into openGL as a texture for the Sun
  LoadTexture('Earth.bmp', EarthTex, false);			// Load "Earth.bmp" into openGL as a texture for the Earth
  LoadTexture('Pluto.bmp', PlutoTex, false);			// Load "Pluto.bmp" into openGL as a texture for Pluto
end;


{------------------------------------------------------------------}
{  Handle window resize                                            }
{------------------------------------------------------------------}
procedure glResizeWnd(Width, Height : Integer);
begin
  if (Height = 0) then                // prevent divide by zero exception
    Height := 1;
  glViewport(0, 0, Width, Height);    // Set the viewport for the OpenGL window
  glMatrixMode(GL_PROJECTION);        // Change Matrix Mode to Projection
  glLoadIdentity();                   // Reset View
  
  gluPerspective(45.0, Width/Height, 0.5, 150.0);
  
  glMatrixMode(GL_MODELVIEW);         // Return to the modelview matrix
  glLoadIdentity();                   // Reset View
end;


{------------------------------------------------------------------}
{  Processes all the keystrokes                                    }
{------------------------------------------------------------------}
procedure ProcessKeys;
begin

end;


{------------------------------------------------------------------}
{  Determines the application抯 response to the messages received  }
{------------------------------------------------------------------}
function WndProc(hWnd: HWND; Msg: UINT;  wParam: WPARAM;  lParam: LPARAM): LRESULT; stdcall;
var
   objectID: integer;
begin
  case (Msg) of
    WM_CREATE:
      begin
        // Insert stuff you want executed when the program starts
      end;
    WM_CLOSE:
      begin
        PostQuitMessage(0);
        Result := 0
      end;
    WM_KEYDOWN:       // Set the pressed key (wparam) to equal true so we can check if its pressed
      begin
        keys[wParam] := True;
        Result := 0;
      end;
    WM_KEYUP:         // Set the released key (wparam) to equal false so we can check if its pressed
      begin
        keys[wParam] := False;
        Result := 0;
      end;
    WM_SIZE:          // Resize the window with the new width and height
      begin
        glResizeWnd(LOWORD(lParam),HIWORD(lParam));
        Result := 0;
      end;
    WM_TIMER :                     // Add code here for all timers to be used.
      begin
        if wParam = FPS_TIMER then
        begin
          FPSCount :=Round(FPSCount * 1000/FPS_INTERVAL);   // calculate to get per Second incase intercal is less or greater than 1 second
          SetWindowText(h_Wnd, PChar(WND_TITLE + '   [' + intToStr(FPSCount) + ' FPS]'));
          FPSCount := 0;
          Result := 0;
        end;
      end;
    WM_LBUTTONDOWN:
      begin								// If the left mouse button was clicked
	// Here we pass in the cursors X and Y coordinates to test for an object under the mouse.
	objectID := RetrieveObjectID(LOWORD(lParam), HIWORD(lParam));

	// Now we just do a switch on our object ID's to see if we hit one.

	case (objectID)	of // Check the objectID passed back
	  SUN:	 MessageBox(0, 'The Sun!', 'Click', MB_OK);		
	  EARTH: MessageBox(0, 'The Earth!', 'Click', MB_OK);		
	  PLUTO: MessageBox(0, 'Pluto!', 'Click', MB_OK);
        end;
      end;
    else
      Result := DefWindowProc(hWnd, Msg, wParam, lParam);    // Default result if nothing happens
  end;
end;


{---------------------------------------------------------------------}
{  Properly destroys the window created at startup (no memory leaks)  }
{---------------------------------------------------------------------}
procedure glKillWnd(Fullscreen : Boolean);
begin
  if Fullscreen then             // Change back to non fullscreen
  begin
    ChangeDisplaySettings(devmode(nil^), 0);
    ShowCursor(True);
  end;

  // Makes current rendering context not current, and releases the device
  // context that is used by the rendering context.
  if (not wglMakeCurrent(h_DC, 0)) then
    MessageBox(0, 'Release of DC and RC failed!', 'Error', MB_OK or MB_ICONERROR);

  // Attempts to delete the rendering context
  if (not wglDeleteContext(h_RC)) then
  begin
    MessageBox(0, 'Release of rendering context failed!', 'Error', MB_OK or MB_ICONERROR);
    h_RC := 0;
  end;

  // Attemps to release the device context
  if ((h_DC > 0) and (ReleaseDC(h_Wnd, h_DC) = 0)) then
  begin
    MessageBox(0, 'Release of device context failed!', 'Error', MB_OK or MB_ICONERROR);
    h_DC := 0;
  end;

  // Attempts to destroy the window
  if ((h_Wnd <> 0) and (not DestroyWindow(h_Wnd))) then
  begin
    MessageBox(0, 'Unable to destroy window!', 'Error', MB_OK or MB_ICONERROR);
    h_Wnd := 0;
  end;

  // Attempts to unregister the window class
  if (not UnRegisterClass('OpenGL', hInstance)) then
  begin
    MessageBox(0, 'Unable to unregister window class!', 'Error', MB_OK or MB_ICONERROR);
    hInstance := 0;
  end;
end;


{--------------------------------------------------------------------}
{  Creates the window and attaches a OpenGL rendering context to it  }
{--------------------------------------------------------------------}
function glCreateWnd(Width, Height : Integer; Fullscreen : Boolean; PixelDepth : Integer) : Boolean;
var
  wndClass : TWndClass;         // Window class
  dwStyle : DWORD;              // Window styles
  dwExStyle : DWORD;            // Extended window styles
  dmScreenSettings : DEVMODE;   // Screen settings (fullscreen, etc...)
  PixelFormat : GLuint;         // Settings for the OpenGL rendering

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -