是否可以在 2 个窗口中使用 openGL?如在 2 个不同的窗口中(假设第一个是 640x480,另一个是 1024x768)呈现不同的东西(假设一个窗口是编辑器,另一个是主/普通窗口显示)
5 回答
如果您使用 GLUT,您可以使用 glutSetWindow() / glutGetWindow() 调用来选择正确的窗口(在使用 glutCreateSubWindow() 创建它们之后)。然而,有时 GLUT 可能不是适合这项工作的工具。
如果您在 Windows 上工作,您需要查看 wglMakeCurrent() 和 wglCreateContext()。在 OS X 上有 aglSetCurrentContext() 等等,而 X11 需要 glXMakeCurrent()。
这些函数激活您可以渲染到的当前 OpenGL 上下文。每个平台特定的库都有自己的方法来创建窗口并将 OpenGL 上下文绑定到它。
在 Windows 上,在为窗口获取 HWND 和 HDC 之后(在 CreateWindow 和 GetDC 调用之后)。您通常会执行以下操作来设置 OpenGL:
GLuint l_PixelFormat = 0;
// some pixel format descriptor that I generally use:
static PIXELFORMATDESCRIPTOR l_Pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1,
PFD_DRAW_TO_WINDOW + PFD_SUPPORT_OPENGL + PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA, m_BitsPerPixel, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0};
if(!(l_PixelFormat = ChoosePixelFormat(m_hDC, &l_Pfd))){
throw std::runtime_error("No matching pixel format descriptor");
}
if(!SetPixelFormat(m_hDC, l_PixelFormat, &l_Pfd)){
throw std::runtime_error("Can't set the pixel format");
}
if(!(m_hRC = wglCreateContext(m_hDC))){
throw std::runtime_error("Can't create rendering context");
}
wglMakeCurrent(m_hDC, m_hRC);
您使用该代码创建多个窗口并将 OpenGL 绑定到它,然后每次要绘制到特定窗口时,您必须在执行任何操作之前调用 wglMakeCurrent并传入与该窗口对应的参数。
附带说明一下,OpenGL 允许您在不同的上下文之间共享某些数据,但是根据规范,您可以共享的数据非常有限。但是,大多数操作系统允许您共享比规范中指定的更多的数据。
是的,这是可能的。对于每个窗口,您都需要创建一个唯一的设备上下文和渲染上下文。
HDC hDC = GetDC( hWnd ); /* get the device context for a particular window */
/* snip */
HGLRC hRC;
hRC = wglCreateContext( hDC ); /* get a render context for the same window */
/* repeat with hDC2 and hRC2 with another window handle*/
在对窗口进行 GL 调用之前,您必须像这样调用 wglMakeCurrent:
wglMakeCurrent( hDC, hRC );
/* GL calls for first window */
wglMakeCurrent( NULL, NULL);
wglMakeCurrent( hDC2, hRC2 );
/* GL calls for second window */
wglMakeCurrent( NULL, NULL);
在 Windows 上,您可以使用wglShareLists()共享 OpenGL 对象,例如纹理和着色器。尽管 MSDN 说了什么,但它通常会共享您关心的所有内容。
我之前在 MFC 应用程序中完成了多个 OpenGL 窗口。这是一个您可能会发现有用的类:由于 UI 线程中一次只能有一个当前渲染上下文,因此我编写了一个类包装器以使其更易于管理。
保存恢复RC.h
// this class helps to manage multiple RCs using an RAII design pattern
class CSaveRestoreRC
{
public:
HDC oldDC;
HGLRC oldRC;
CSaveRestoreRC(HDC hDC, HGLRC hRC);
~CSaveRestoreRC(void);
};
保存RestoreRC.cpp:
CSaveRestoreRC::CSaveRestoreRC(HDC hDC, HGLRC hRC)
{
ASSERT( hDC );
ASSERT( hRC );
oldDC = wglGetCurrentDC();
oldRC = wglGetCurrentContext();
BOOL result = wglMakeCurrent( hDC, hRC );
ASSERT( result );
}
CSaveRestoreRC::~CSaveRestoreRC(void)
{
if( !oldRC )
return;
ASSERT( oldDC );
BOOL result = wglMakeCurrent( oldDC, oldRC );
ASSERT( result );
}
现在从 CWnd 派生一个类并添加这些成员变量:
class COpenGLControl : public CWnd
{
// used to interface OpenGL with Windows
HDC hdc;
HGLRC hrc;
// ...
int COpenGLControl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// Get device context only once.
hdc = GetDC()->m_hDC;
// ... ChoosePixelFormat, SetPixelFormat, etc. here.
// Create the OpenGL Rendering Context.
hrc = wglCreateContext(hdc);
ASSERT( hrc );
然后在您调用任何 OpenGL 命令的每个成员函数中,使用 CSaveRestoreRC 以便您当前的渲染上下文不会搞砸。
void COpenGLControl::UpdateCamera()
{
CSaveRestoreRC c(hdc, hrc);
// Map the OpenGL device coordinates.
glViewport(0, 0, renderingWindow.Width(), renderingWindow.Height());
// Do your other OpenGL stuff here
// ...
// the CSaveRestoreRC destructor will automatically put the correct render context back,
// even if you call other functions. Of course, put another CSaveRestoreRC there too.
}
如果您只喜欢使用 glut 库,请查看Eric Stringer 的代码。
// Glutdualwindow.c
// By Eric Stringer 2002
// Simple examples of OpenGL and Glut usage.
// Keyboard input
// 'v' = view ortho/perspective
// 'l' = lighting on/off
#include <windows.h> // This header file will be needed for some windows compilers
//#include <GL/gl.h> // gl.h and glu.h also maybe needed for some compilers
//#include <GL/glu.h>
#include <GL/glut.h> // glut (gl utility toolkit) basic windows functions, keyboard, mouse.
#include <stdio.h> // standard (I/O library)
#include <stdlib.h> // standard library (set of standard C functions
#include <math.h> // Math library (Higher math functions )
// lighting
GLfloat LightAmbient[]= { 0.2f, 0.2f, 0.2f, 1.0f };
GLfloat LightDiffuse[]= { 0.5f, 0.5f, 0.5f, 1.0f };
GLfloat LightPosition[]= { 5.0f, 5.0f, -10.0f, 1.0f };
GLfloat mat_specular[] = { 0.2, 0.2, 0.2, 1.0 };
int window_1, window_2;
static int view_state = 0, light_state = 0;
int spin;
int shape;
// I use this to put text on the screen
void Sprint( int x, int y, char *st)
{
int l,i;
l=strlen( st ); // see how many characters are in text string.
glRasterPos2i( x, y); // location to start printing text
for( i=0; i < l; i++) // loop until i is greater then l
{
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, st[i]); // Print a character on the screen
}
}
// This creates the spinning of the cube.
static void TimeEvent(int te)
{
spin++; // increase cube rotation by 1
if (spin > 360) spin = 0; // if over 360 degress, start back at zero.
glutSetWindow( window_1 );
glutPostRedisplay(); // Update screen with new rotation data
glutSetWindow( window_2 );
glutPostRedisplay(); // Update screen with new rotation data
glutTimerFunc( 100, TimeEvent, 1); // Reset our timmer.
}
// Setup our Opengl world, called once at startup.
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0); // When screen cleared, use black.
glShadeModel (GL_SMOOTH); // How the object color will be rendered smooth or flat
glEnable(GL_DEPTH_TEST); // Check depth when rendering
// Lighting is added to scene
glLightfv(GL_LIGHT1 ,GL_AMBIENT, LightAmbient);
glLightfv(GL_LIGHT1 ,GL_DIFFUSE, LightDiffuse);
glLightfv(GL_LIGHT1 ,GL_POSITION, LightPosition);
glEnable(GL_LIGHTING); // Turn on lighting
glEnable(GL_LIGHT1); // Turn on light 1
}
// Draw our world
void display_1(void)
{
char *p;
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Clear the screen
glMatrixMode (GL_PROJECTION); // Tell opengl that we are doing project matrix work
glLoadIdentity(); // Clear the matrix
glOrtho(-8.0, 8.0, -8.0, 8.0, 0.0, 30.0); // Setup an Ortho view
glMatrixMode(GL_MODELVIEW); // Tell opengl that we are doing model matrix work. (drawing)
glLoadIdentity(); // Clear the model matrix
glColor3f(1.0, 1.0, 1.0);
if (shape == 0) Sprint(-3, -7 ,"Solid Cube");
if (shape == 1) Sprint(-3, -7 ,"Solid Cone");
if (shape == 2) Sprint(-3, -7 ,"Solid Sphere");
if (shape == 3) Sprint(-3, -7 ,"Solid Torus");
if (shape == 4) Sprint(-3, -7 ,"Solid Dodecahedron");
if (shape == 5) Sprint(-3, -7 ,"Solid Octahedron");
if (shape == 6) Sprint(-3, -7 ,"Solid Tetrahedron");
if (shape == 7) Sprint(-3, -7 ,"Solid Icosahedron");
if (shape == 8) Sprint(-3, -7 ,"Solid Teapot");
// Setup view, and print view state on screen
if (view_state == 1)
{
glColor3f( 1.0, 1.0, 1.0);
Sprint(-2, 4, "Perspective view");
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, 1, 1, 30);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}else
{
glColor3f( 1.0, 1.0, 1.0);
Sprint(-2, 4, "Ortho view");
}
glColor3f( 0.0, 0.0, 1.0); // Cube color
// Lighting on/off
if (light_state == 1)
{
glDisable(GL_LIGHTING); // Turn off lighting
glDisable(GL_COLOR_MATERIAL); // Turn off material, which needs lighting to work
}else
{
glEnable(GL_LIGHTING); // Turn on lighting
glEnable(GL_COLOR_MATERIAL); // Turn on material settings
glColorMaterial(GL_FRONT, GL_AMBIENT);
glColor4f(0.65, 0.65, 0.65, 0.4);
glColorMaterial(GL_FRONT, GL_EMISSION);
glColor4f(0.10, 0.10, 0.10, 0.0);
glColorMaterial(GL_FRONT, GL_SPECULAR);
glColor4f(0.5, 0.5, 0.5, 0.4);
glColorMaterial(GL_FRONT, GL_DIFFUSE);
glColor4f(0.85, 0.85, 0.85, 0.4);
}
gluLookAt( 0, 0, 20, 0, 0, 0, 0, 1, 0);
//glRotatef( 45, 1.0, 1.0, 0.0); // rotate cube
glRotatef( spin++, 1.0, 1.0, 1.0); // spin cube
if (shape == 0) glutSolidCube(10); // Draw a cube
if (shape == 1) glutSolidCone(5,10, 16,16); // Draw a Cone
if (shape == 2) glutSolidSphere(5, 16,16 ); // Draw a Sphere
if (shape == 3) glutSolidTorus( 2.5, 5, 16, 16);
if (shape == 4)
{
glScalef( 3.5, 3.5, 3.5);
glutSolidDodecahedron();
}
if (shape == 5)
{
glScalef( 5.0, 5.0, 5.0);
glutSolidOctahedron();
}
if (shape == 6)
{
glScalef( 5.0, 5.0, 5.0);
glutSolidTetrahedron();
}
if (shape == 7)
{
glScalef( 5.0, 5.0, 5.0);
glutSolidIcosahedron();
}
if (shape == 8) glutSolidTeapot( 5 );
glutSwapBuffers();
}
void display_2(void)
{
char *p;
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Clear the screen
glMatrixMode (GL_PROJECTION); // Tell opengl that we are doing project matrix work
glLoadIdentity(); // Clear the matrix
glOrtho(-8.0, 8.0, -8.0, 8.0, 0.0, 30.0); // Setup an Ortho view
glMatrixMode(GL_MODELVIEW); // Tell opengl that we are doing model matrix work. (drawing)
glLoadIdentity(); // Clear the model matrix
glColor3f(1.0, 1.0, 1.0);
if (shape == 0) Sprint(-3, -7 ,"Wire Cube");
if (shape == 1) Sprint(-3, -7 ,"Wire Cone");
if (shape == 2) Sprint(-3, -7 ,"Wire Sphere");
if (shape == 3) Sprint(-3, -7 ,"Wire Torus");
if (shape == 4) Sprint(-3, -7 ,"Wire Dodecahedron");
if (shape == 5) Sprint(-3, -7 ,"Wire Octahedron");
if (shape == 6) Sprint(-3, -7 ,"Wire Tetrahedron");
if (shape == 7) Sprint(-3, -7 ,"Wire Icosahedron");
if (shape == 8) Sprint(-3, -7 ,"Wire Teapot");
// Setup view, and print view state on screen
if (view_state == 1)
{
glColor3f( 1.0, 1.0, 1.0);
Sprint(-2, 4, "Perspective view");
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, 1, 1, 30);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}else
{
glColor3f( 1.0, 1.0, 1.0);
Sprint(-2, 4, "Ortho view");
}
glColor3f( 0.0, 0.0, 1.0); // Cube color
// Lighting on/off
if (light_state == 1)
{
glDisable(GL_LIGHTING); // Turn off lighting
glDisable(GL_COLOR_MATERIAL); // Turn off material, which needs lighting to work
}else
{
glEnable(GL_LIGHTING); // Turn on lighting
glEnable(GL_COLOR_MATERIAL); // Turn on material settings
glColorMaterial(GL_FRONT, GL_AMBIENT);
glColor4f(0.65, 0.65, 0.65, 0.4);
glColorMaterial(GL_FRONT, GL_EMISSION);
glColor4f(0.10, 0.10, 0.10, 0.0);
glColorMaterial(GL_FRONT, GL_SPECULAR);
glColor4f(0.5, 0.5, 0.5, 0.4);
glColorMaterial(GL_FRONT, GL_DIFFUSE);
glColor4f(0.85, 0.85, 0.85, 0.4);
}
gluLookAt( 0, 0, 20, 0, 0, 0, 0, 1, 0);
//glRotatef( 45, 1.0, 1.0, 0.0); // rotate cube
glRotatef( spin++, 1.0, 1.0, 1.0); // spin cube
if (shape == 0) glutWireCube(10); // Draw a cube
if (shape == 1) glutWireCone(5,10, 16,16); // Draw a Cone
if (shape == 2) glutWireSphere(5, 16,16 ); // Draw a Sphere
if (shape == 3) glutWireTorus( 2.5, 5, 16, 16);
if (shape == 4)
{
glScalef( 3.5, 3.5, 3.5);
glutSolidDodecahedron();
}
if (shape == 5)
{
glScalef( 5.0, 5.0, 5.0);
glutWireOctahedron();
}
if (shape == 6)
{
glScalef( 5.0, 5.0, 5.0);
glutWireTetrahedron();
}
if (shape == 7)
{
glScalef( 5.0, 5.0, 5.0);
glutWireIcosahedron();
}
if (shape == 8) glutWireTeapot( 5 );
glutSwapBuffers();
}
// This is called when the window has been resized.
void reshape_1 (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
}
// This is called when the window has been resized.
void reshape_2 (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
}
// Read the keyboard
void keyboard (unsigned char key, int x, int y)
{
switch (key)
{
case 'v':
case 'V':
view_state = abs(view_state -1);
break;
case 'l':
case 'L':
light_state = abs(light_state -1);
break;
case 's':
case 'S':
shape++;
break;
case 27:
exit(0); // exit program when [ESC] key presseed
break;
default:
break;
}
if (shape > 8) shape = 0;
}
// Main program
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (10, 10);
glutTimerFunc( 10, TimeEvent, 1);
window_1 = glutCreateWindow (argv[0]);
glutSetWindowTitle("GlutWindow 1");
init ();
glutDisplayFunc(display_1);
glutReshapeFunc(reshape_1);
glutKeyboardFunc(keyboard);
window_2 = glutCreateWindow (argv[0]);
glutSetWindowTitle("GlutWindow 2");
init ();
glutDisplayFunc(display_2);
glutReshapeFunc(reshape_2);
glutMainLoop();
return 0;
}
// Glutdualwindow.c
// By Eric Stringer 2002
// Simple examples of OpenGL and Glut usage.
// Keyboard input
// 'v' = view ortho/perspective
// 'l' = lighting on/off
#include <windows.h> // This header file will be needed for some windows compilers
//#include <GL/gl.h> // gl.h and glu.h also maybe needed for some compilers
//#include <GL/glu.h>
#include <GL/glut.h> // glut (gl utility toolkit) basic windows functions, keyboard, mouse.
#include <stdio.h> // standard (I/O library)
#include <stdlib.h> // standard library (set of standard C functions
#include <math.h> // Math library (Higher math functions )
// lighting
GLfloat LightAmbient[]= { 0.2f, 0.2f, 0.2f, 1.0f };
GLfloat LightDiffuse[]= { 0.5f, 0.5f, 0.5f, 1.0f };
GLfloat LightPosition[]= { 5.0f, 5.0f, -10.0f, 1.0f };
GLfloat mat_specular[] = { 0.2, 0.2, 0.2, 1.0 };
int window_1, window_2;
static int view_state = 0, light_state = 0;
int spin;
int shape;
// I use this to put text on the screen
void Sprint( int x, int y, char *st)
{
int l,i;
l=strlen( st ); // see how many characters are in text string.
glRasterPos2i( x, y); // location to start printing text
for( i=0; i < l; i++) // loop until i is greater then l
{
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, st[i]); // Print a character on the screen
}
}
// This creates the spinning of the cube.
static void TimeEvent(int te)
{
spin++; // increase cube rotation by 1
if (spin > 360) spin = 0; // if over 360 degress, start back at zero.
glutSetWindow( window_1 );
glutPostRedisplay(); // Update screen with new rotation data
glutSetWindow( window_2 );
glutPostRedisplay(); // Update screen with new rotation data
glutTimerFunc( 100, TimeEvent, 1); // Reset our timmer.
}
// Setup our Opengl world, called once at startup.
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0); // When screen cleared, use black.
glShadeModel (GL_SMOOTH); // How the object color will be rendered smooth or flat
glEnable(GL_DEPTH_TEST); // Check depth when rendering
// Lighting is added to scene
glLightfv(GL_LIGHT1 ,GL_AMBIENT, LightAmbient);
glLightfv(GL_LIGHT1 ,GL_DIFFUSE, LightDiffuse);
glLightfv(GL_LIGHT1 ,GL_POSITION, LightPosition);
glEnable(GL_LIGHTING); // Turn on lighting
glEnable(GL_LIGHT1); // Turn on light 1
}
// Draw our world
void display_1(void)
{
char *p;
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Clear the screen
glMatrixMode (GL_PROJECTION); // Tell opengl that we are doing project matrix work
glLoadIdentity(); // Clear the matrix
glOrtho(-8.0, 8.0, -8.0, 8.0, 0.0, 30.0); // Setup an Ortho view
glMatrixMode(GL_MODELVIEW); // Tell opengl that we are doing model matrix work. (drawing)
glLoadIdentity(); // Clear the model matrix
glColor3f(1.0, 1.0, 1.0);
if (shape == 0) Sprint(-3, -7 ,"Solid Cube");
if (shape == 1) Sprint(-3, -7 ,"Solid Cone");
if (shape == 2) Sprint(-3, -7 ,"Solid Sphere");
if (shape == 3) Sprint(-3, -7 ,"Solid Torus");
if (shape == 4) Sprint(-3, -7 ,"Solid Dodecahedron");
if (shape == 5) Sprint(-3, -7 ,"Solid Octahedron");
if (shape == 6) Sprint(-3, -7 ,"Solid Tetrahedron");
if (shape == 7) Sprint(-3, -7 ,"Solid Icosahedron");
if (shape == 8) Sprint(-3, -7 ,"Solid Teapot");
// Setup view, and print view state on screen
if (view_state == 1)
{
glColor3f( 1.0, 1.0, 1.0);
Sprint(-2, 4, "Perspective view");
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, 1, 1, 30);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}else
{
glColor3f( 1.0, 1.0, 1.0);
Sprint(-2, 4, "Ortho view");
}
glColor3f( 0.0, 0.0, 1.0); // Cube color
// Lighting on/off
if (light_state == 1)
{
glDisable(GL_LIGHTING); // Turn off lighting
glDisable(GL_COLOR_MATERIAL); // Turn off material, which needs lighting to work
}else
{
glEnable(GL_LIGHTING); // Turn on lighting
glEnable(GL_COLOR_MATERIAL); // Turn on material settings
glColorMaterial(GL_FRONT, GL_AMBIENT);
glColor4f(0.65, 0.65, 0.65, 0.4);
glColorMaterial(GL_FRONT, GL_EMISSION);
glColor4f(0.10, 0.10, 0.10, 0.0);
glColorMaterial(GL_FRONT, GL_SPECULAR);
glColor4f(0.5, 0.5, 0.5, 0.4);
glColorMaterial(GL_FRONT, GL_DIFFUSE);
glColor4f(0.85, 0.85, 0.85, 0.4);
}
gluLookAt( 0, 0, 20, 0, 0, 0, 0, 1, 0);
//glRotatef( 45, 1.0, 1.0, 0.0); // rotate cube
glRotatef( spin++, 1.0, 1.0, 1.0); // spin cube
if (shape == 0) glutSolidCube(10); // Draw a cube
if (shape == 1) glutSolidCone(5,10, 16,16); // Draw a Cone
if (shape == 2) glutSolidSphere(5, 16,16 ); // Draw a Sphere
if (shape == 3) glutSolidTorus( 2.5, 5, 16, 16);
if (shape == 4)
{
glScalef( 3.5, 3.5, 3.5);
glutSolidDodecahedron();
}
if (shape == 5)
{
glScalef( 5.0, 5.0, 5.0);
glutSolidOctahedron();
}
if (shape == 6)
{
glScalef( 5.0, 5.0, 5.0);
glutSolidTetrahedron();
}
if (shape == 7)
{
glScalef( 5.0, 5.0, 5.0);
glutSolidIcosahedron();
}
if (shape == 8) glutSolidTeapot( 5 );
glutSwapBuffers();
}
void display_2(void)
{
char *p;
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Clear the screen
glMatrixMode (GL_PROJECTION); // Tell opengl that we are doing project matrix work
glLoadIdentity(); // Clear the matrix
glOrtho(-8.0, 8.0, -8.0, 8.0, 0.0, 30.0); // Setup an Ortho view
glMatrixMode(GL_MODELVIEW); // Tell opengl that we are doing model matrix work. (drawing)
glLoadIdentity(); // Clear the model matrix
glColor3f(1.0, 1.0, 1.0);
if (shape == 0) Sprint(-3, -7 ,"Wire Cube");
if (shape == 1) Sprint(-3, -7 ,"Wire Cone");
if (shape == 2) Sprint(-3, -7 ,"Wire Sphere");
if (shape == 3) Sprint(-3, -7 ,"Wire Torus");
if (shape == 4) Sprint(-3, -7 ,"Wire Dodecahedron");
if (shape == 5) Sprint(-3, -7 ,"Wire Octahedron");
if (shape == 6) Sprint(-3, -7 ,"Wire Tetrahedron");
if (shape == 7) Sprint(-3, -7 ,"Wire Icosahedron");
if (shape == 8) Sprint(-3, -7 ,"Wire Teapot");
// Setup view, and print view state on screen
if (view_state == 1)
{
glColor3f( 1.0, 1.0, 1.0);
Sprint(-2, 4, "Perspective view");
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, 1, 1, 30);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}else
{
glColor3f( 1.0, 1.0, 1.0);
Sprint(-2, 4, "Ortho view");
}
glColor3f( 0.0, 0.0, 1.0); // Cube color
// Lighting on/off
if (light_state == 1)
{
glDisable(GL_LIGHTING); // Turn off lighting
glDisable(GL_COLOR_MATERIAL); // Turn off material, which needs lighting to work
}else
{
glEnable(GL_LIGHTING); // Turn on lighting
glEnable(GL_COLOR_MATERIAL); // Turn on material settings
glColorMaterial(GL_FRONT, GL_AMBIENT);
glColor4f(0.65, 0.65, 0.65, 0.4);
glColorMaterial(GL_FRONT, GL_EMISSION);
glColor4f(0.10, 0.10, 0.10, 0.0);
glColorMaterial(GL_FRONT, GL_SPECULAR);
glColor4f(0.5, 0.5, 0.5, 0.4);
glColorMaterial(GL_FRONT, GL_DIFFUSE);
glColor4f(0.85, 0.85, 0.85, 0.4);
}
gluLookAt( 0, 0, 20, 0, 0, 0, 0, 1, 0);
//glRotatef( 45, 1.0, 1.0, 0.0); // rotate cube
glRotatef( spin++, 1.0, 1.0, 1.0); // spin cube
if (shape == 0) glutWireCube(10); // Draw a cube
if (shape == 1) glutWireCone(5,10, 16,16); // Draw a Cone
if (shape == 2) glutWireSphere(5, 16,16 ); // Draw a Sphere
if (shape == 3) glutWireTorus( 2.5, 5, 16, 16);
if (shape == 4)
{
glScalef( 3.5, 3.5, 3.5);
glutSolidDodecahedron();
}
if (shape == 5)
{
glScalef( 5.0, 5.0, 5.0);
glutWireOctahedron();
}
if (shape == 6)
{
glScalef( 5.0, 5.0, 5.0);
glutWireTetrahedron();
}
if (shape == 7)
{
glScalef( 5.0, 5.0, 5.0);
glutWireIcosahedron();
}
if (shape == 8) glutWireTeapot( 5 );
glutSwapBuffers();
}
// This is called when the window has been resized.
void reshape_1 (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
}
// This is called when the window has been resized.
void reshape_2 (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
}
// Read the keyboard
void keyboard (unsigned char key, int x, int y)
{
switch (key)
{
case 'v':
case 'V':
view_state = abs(view_state -1);
break;
case 'l':
case 'L':
light_state = abs(light_state -1);
break;
case 's':
case 'S':
shape++;
break;
case 27:
exit(0); // exit program when [ESC] key presseed
break;
default:
break;
}
if (shape > 8) shape = 0;
}
// Main program
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (10, 10);
glutTimerFunc( 10, TimeEvent, 1);
window_1 = glutCreateWindow (argv[0]);
glutSetWindowTitle("GlutWindow 1");
init ();
glutDisplayFunc(display_1);
glutReshapeFunc(reshape_1);
glutKeyboardFunc(keyboard);
window_2 = glutCreateWindow (argv[0]);
glutSetWindowTitle("GlutWindow 2");
init ();
glutDisplayFunc(display_2);
glutReshapeFunc(reshape_2);
glutMainLoop();
return 0;
}
我在 Windows 7 上运行了示例代码,但我不得不将一行 glutIntit 替换为
glutInit(&argc, argv);