📄 lesson48.cpp
字号:
/**************************************
* *
* Jeff Molofee's Basecode Example *
* nehe.gamedev.net *
* 2001 *
* *
**************************************/
#include <windows.h> // Header File For Windows
#include <gl\gl.h> // Header File For The OpenGL32 Library
#include <gl\glu.h> // Header File For The GLu32 Library
#include <gl\glaux.h> // Header File For The GLaux Library
#include "NeHeGL.h" // Header File For NeHeGL
#include "math.h" // NEW: Needed For Sqrtf
#include "ArcBall.h" // NEW: ArcBall Header
#pragma comment( lib, "opengl32.lib" ) // Search For OpenGL32.lib While Linking
#pragma comment( lib, "glu32.lib" ) // Search For GLu32.lib While Linking
#pragma comment( lib, "glaux.lib" ) // Search For GLaux.lib While Linking
#ifndef CDS_FULLSCREEN // CDS_FULLSCREEN Is Not Defined By Some
#define CDS_FULLSCREEN 4 // Compilers. By Defining It This Way,
#endif // We Can Avoid Errors
GL_Window* g_window;
Keys* g_keys;
// User Defined Variables
GLUquadricObj *quadratic; // Used For Our Quadric
const float PI2 = 2.0*3.1415926535f; // PI Squared
Matrix4fT Transform = { 1.0f, 0.0f, 0.0f, 0.0f, // NEW: Final Transform
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f };
Matrix3fT LastRot = { 1.0f, 0.0f, 0.0f, // NEW: Last Rotation
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f };
Matrix3fT ThisRot = { 1.0f, 0.0f, 0.0f, // NEW: This Rotation
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f };
ArcBallT ArcBall(640.0f, 480.0f); // NEW: ArcBall Instance
Point2fT MousePt; // NEW: Current Mouse Point
bool isClicked = false; // NEW: Clicking The Mouse?
bool isRClicked = false; // NEW: Clicking The Right Mouse Button?
bool isDragging = false; // NEW: Dragging The Mouse?
BOOL Initialize (GL_Window* window, Keys* keys) // Any GL Init Code & User Initialiazation Goes Here
{
g_window = window;
g_keys = keys;
// Start Of User Initialization
isClicked = false; // NEW: Clicking The Mouse?
isDragging = false; // NEW: Dragging The Mouse?
glClearColor (0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth (1.0f); // Depth Buffer Setup
glDepthFunc (GL_LEQUAL); // The Type Of Depth Testing (Less Or Equal)
glEnable (GL_DEPTH_TEST); // Enable Depth Testing
glShadeModel (GL_FLAT); // Select Flat Shading (Nice Definition Of Objects)
glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Set Perspective Calculations To Most Accurate
quadratic=gluNewQuadric(); // Create A Pointer To The Quadric Object
gluQuadricNormals(quadratic, GLU_SMOOTH); // Create Smooth Normals
gluQuadricTexture(quadratic, GL_TRUE); // Create Texture Coords
glEnable(GL_LIGHT0); // Enable Default Light
glEnable(GL_LIGHTING); // Enable Lighting
glEnable(GL_COLOR_MATERIAL); // Enable Color Material
return TRUE; // Return TRUE (Initialization Successful)
}
void Deinitialize (void) // Any User DeInitialization Goes Here
{
gluDeleteQuadric(quadratic);
}
void Update (DWORD milliseconds) // Perform Motion Updates Here
{
if (g_keys->keyDown [VK_ESCAPE] == TRUE) // Is ESC Being Pressed?
TerminateApplication (g_window); // Terminate The Program
if (g_keys->keyDown [VK_F1] == TRUE) // Is F1 Being Pressed?
ToggleFullscreen (g_window); // Toggle Fullscreen Mode
if (isRClicked) // If Right Mouse Clicked, Reset All Rotations
{
Matrix3fSetIdentity(&LastRot); // Reset Rotation
Matrix3fSetIdentity(&ThisRot); // Reset Rotation
Matrix4fSetRotationFromMatrix3f(&Transform, &ThisRot); // Reset Rotation
}
if (!isDragging) // Not Dragging
{
if (isClicked) // First Click
{
isDragging = true; // Prepare For Dragging
LastRot = ThisRot; // Set Last Static Rotation To Last Dynamic One
ArcBall.click(&MousePt); // Update Start Vector And Prepare For Dragging
}
}
else
{
if (isClicked) // Still Clicked, So Still Dragging
{
Quat4fT ThisQuat;
ArcBall.drag(&MousePt, &ThisQuat); // Update End Vector And Get Rotation As Quaternion
Matrix3fSetRotationFromQuat4f(&ThisRot, &ThisQuat); // Convert Quaternion Into Matrix3fT
Matrix3fMulMatrix3f(&ThisRot, &LastRot); // Accumulate Last Rotation Into This One
Matrix4fSetRotationFromMatrix3f(&Transform, &ThisRot); // Set Our Final Transform's Rotation From This One
}
else // No Longer Dragging
isDragging = false;
}
}
void Torus(float MinorRadius, float MajorRadius) // Draw A Torus With Normals
{
int i, j;
glBegin( GL_TRIANGLE_STRIP ); // Start A Triangle Strip
for (i=0; i<20; i++ ) // Stacks
{
for (j=-1; j<20; j++) // Slices
{
float wrapFrac = (j%20)/(float)20;
float phi = PI2*wrapFrac;
float sinphi = float(sin(phi));
float cosphi = float(cos(phi));
float r = MajorRadius + MinorRadius*cosphi;
glNormal3f(float(sin(PI2*(i%20+wrapFrac)/(float)20))*cosphi, sinphi, float(cos(PI2*(i%20+wrapFrac)/(float)20))*cosphi);
glVertex3f(float(sin(PI2*(i%20+wrapFrac)/(float)20))*r,MinorRadius*sinphi,float(cos(PI2*(i%20+wrapFrac)/(float)20))*r);
glNormal3f(float(sin(PI2*(i+1%20+wrapFrac)/(float)20))*cosphi, sinphi, float(cos(PI2*(i+1%20+wrapFrac)/(float)20))*cosphi);
glVertex3f(float(sin(PI2*(i+1%20+wrapFrac)/(float)20))*r,MinorRadius*sinphi,float(cos(PI2*(i+1%20+wrapFrac)/(float)20))*r);
}
}
glEnd(); // Done Torus
}
void Draw (void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glLoadIdentity(); // Reset The Current Modelview Matrix
glTranslatef(-1.5f,0.0f,-6.0f); // Move Left 1.5 Units And Into The Screen 6.0
glPushMatrix(); // NEW: Prepare Dynamic Transform
glMultMatrixf(Transform.M); // NEW: Apply Dynamic Transform
glColor3f(0.75f,0.75f,1.0f);
Torus(0.30f,1.00f);
glPopMatrix(); // NEW: Unapply Dynamic Transform
glLoadIdentity(); // Reset The Current Modelview Matrix
glTranslatef(1.5f,0.0f,-6.0f); // Move Right 1.5 Units And Into The Screen 7.0
glPushMatrix(); // NEW: Prepare Dynamic Transform
glMultMatrixf(Transform.M); // NEW: Apply Dynamic Transform
glColor3f(1.0f,0.75f,0.75f);
gluSphere(quadratic,1.3f,20,20);
glPopMatrix(); // NEW: Unapply Dynamic Transform
glFlush (); // Flush The GL Rendering Pipeline
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -