OpenGL Programming Guide- Red Book 例子程序库 -系列- 2-Introduction to OpenGL-Part2

Example 1-3 : A Double-Buffered Program: double.c 原始程序

#include #include #include #include "aux.h"static GLfloat spin = 0.0; void display(void) { glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); glRotatef(spin, 0.0, 0.0, 1.0); glRectf(-25.0, -25.0, 25.0, 25.0); glPopMatrix(); glFlush(); glXSwapBuffers(auxXDisplay(), auxXWindow()); }void spinDisplay(void) { spin = spin + 2.0; if (spin > 360.0) spin = spin - 360.0; display(); }void startIdleFunc(AUX_EVENTREC *event) { auxIdleFunc(spinDisplay); }void stopIdleFunc(AUX_EVENTREC *event) { auxIdleFunc(0); }void myinit(void) { glClearColor(0.0, 0.0, 0.0, 1.0); glColor3f(1.0, 1.0, 1.0); glShadeModel(GL_FLAT); }void myReshape(GLsizei w, GLsizei h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho (-50.0, 50.0, -50.0*(GLfloat)h/(GLfloat)w, 50.0*(GLfloat)h/(GLfloat)w, -1.0, 1.0); else glOrtho (-50.0*(GLfloat)w/(GLfloat)h, 50.0*(GLfloat)w/(GLfloat)h, -50.0, 50.0, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity (); }int main(int argc, char** argv) { auxInitDisplayMode(AUX_DOUBLE | AUX_RGBA); auxInitPosition(0, 0, 500, 500); auxInitWindow(argv[0]); myinit(); auxReshapeFunc(myReshape); auxIdleFunc(spinDisplay); auxMouseFunc(AUX_LEFTBUTTON, AUX_MOUSEDOWN, startIdleFunc); auxMouseFunc(AUX_MIDDLEBUTTON, AUX_MOUSEDOWN, stopIdleFunc); auxMainLoop(display); }


和前例一样添加了必要的头文件和lib之后
编译错误__stdcall
--------------------Configuration: Example_1_3 - Win32 Debug-------------------- Compiling... Example_1_3.cpp E:\OpenGLRB\Example_1_3\Example_1_3.cpp(31) : warning C4244: '=' : conversion from 'double' to 'float', possible loss of data E:\OpenGLRB\Example_1_3\Example_1_3.cpp(33) : warning C4244: '=' : conversion from 'double' to 'float', possible loss of data E:\OpenGLRB\Example_1_3\Example_1_3.cpp(39) : error C2664: 'auxIdleFunc' : cannot convert parameter 1 from 'void (void)' to 'void (__stdcall *)(void)' None of the functions with this name in scope match the target type E:\OpenGLRB\Example_1_3\Example_1_3.cpp(76) : error C2664: 'auxReshapeFunc' : cannot convert parameter 1 from 'void (int,int)' to 'void (__stdcall *)(int,int)' None of the functions with this name in scope match the target type E:\OpenGLRB\Example_1_3\Example_1_3.cpp(77) : error C2664: 'auxIdleFunc' : cannot convert parameter 1 from 'void (void)' to 'void (__stdcall *)(void)' None of the functions with this name in scope match the target type E:\OpenGLRB\Example_1_3\Example_1_3.cpp(78) : error C2664: 'auxMouseFunc' : cannot convert parameter 3 from 'void (struct _AUX_EVENTREC *)' to 'void (__stdcall *)(struct _AUX_EVENTREC *)' None of the functions with this name in scope match the target type E:\OpenGLRB\Example_1_3\Example_1_3.cpp(79) : error C2664: 'auxMouseFunc' : cannot convert parameter 3 from 'void (struct _AUX_EVENTREC *)' to 'void (__stdcall *)(struct _AUX_EVENTREC *)' None of the functions with this name in scope match the target type E:\OpenGLRB\Example_1_3\Example_1_3.cpp(80) : error C2664: 'auxMainLoop' : cannot convert parameter 1 from 'void (void)' to 'void (__stdcall *)(void)' None of the functions with this name in scope match the target type E:\OpenGLRB\Example_1_3\Example_1_3.cpp(81) : warning C4508: 'main' : function should return a value; 'void' return type assumed Error executing cl.exe. Creating browse info file...Example_1_3.exe - 6 error(s), 3 warning(s)


其中的
error C2664: 'auxMainLoop' : cannot convert parameter 1 from 'void (void)' to 'void (__stdcall *)(void)'

该错误处理方案为在各函数前添加__stdcall符号,如下

void __stdcall stopIdleFunc(AUX_EVENTREC *event) { auxIdleFunc(0); }void __stdcall myinit(void) { glClearColor(0.0, 0.0, 0.0, 1.0); glColor3f(1.0, 1.0, 1.0); glShadeModel(GL_FLAT); }

原始代码是在XWindows下面的编写的,转WindowVC,glx.h是无效的,glXSwapBuffers(auxXDisplay(), auxXWindow()); 函数调用也无效,改为auxSwapBuffers();


调整后cpp文件
// Example_1_3.cpp : Defines the entry point for the console application. //#include "stdafx.h" #include "windows.h" #include #include #pragma comment(lib,"opengl32.lib") #pragma comment(lib,"glaux.lib")static GLfloat spin = 0.0; void __stdcall display(void) { glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); glRotatef(spin, 0.0, 0.0, 1.0); glRectf(-25.0, -25.0, 25.0, 25.0); glPopMatrix(); glFlush(); //glXSwapBuffers(auxXDisplay(), auxXWindow()); auxSwapBuffers(); }void__stdcall spinDisplay(void) { spin = spin + 2.0; if (spin > 360.0) spin = spin - 360.0; display(); } void __stdcall startIdleFunc(AUX_EVENTREC *event) { auxIdleFunc(spinDisplay); }void __stdcall stopIdleFunc(AUX_EVENTREC *event) { auxIdleFunc(0); }void __stdcall myinit(void) { glClearColor(0.0, 0.0, 0.0, 1.0); glColor3f(1.0, 1.0, 1.0); glShadeModel(GL_FLAT); }void __stdcall myReshape(GLsizei w, GLsizei h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho (-50.0, 50.0, -50.0*(GLfloat)h/(GLfloat)w, 50.0*(GLfloat)h/(GLfloat)w, -1.0, 1.0); else glOrtho (-50.0*(GLfloat)w/(GLfloat)h, 50.0*(GLfloat)w/(GLfloat)h, -50.0, 50.0, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity (); }int main(int argc, char** argv) { auxInitDisplayMode(AUX_DOUBLE | AUX_RGBA); auxInitPosition(0, 0, 500, 500); auxInitWindow(argv[0]); myinit(); auxReshapeFunc(myReshape); auxIdleFunc(spinDisplay); auxMouseFunc(AUX_LEFTBUTTON, AUX_MOUSEDOWN, startIdleFunc); auxMouseFunc(AUX_MIDDLEBUTTON, AUX_MOUSEDOWN, stopIdleFunc); auxMainLoop(display); return 0; }




后记:此程序将Example1-1中的代码分散在多个函数中,但是流程顺序保持不变,通过改变参数实现动画效果,鼠标中键单击停止,左键单击启动。


所有aux开头的函数都不重要,所有gl开头的函数都是必须理解掌握的。

【OpenGL Programming Guide- Red Book 例子程序库 -系列- 2-Introduction to OpenGL-Part2】

    推荐阅读