opengl学习手记(三) 旋转的三维立方体
- 格式:doc
- 大小:44.00 KB
- 文档页数:5
opengl学习(三)----绘制简单图形(⼀)今天说⼀说⼏种简单的图元。
所有的⼏何图元都是根据它们的顶点来描绘的。
⽽顶点就是它们在屏幕上的坐标位置。
我喜欢把这⼏个简单的图元称为点线⾯。
点,可以看到⼀个顶点;线,就是两个顶点指定的⼀条有限长度的线段;⾯,其实更准确讲是⼀个凸多边形。
opengl⾥所讲的多边形是内部⽤颜⾊填充的,视觉上称为⾯我个⼈认为是更贴近的。
当然,多边形也是由指定的顶点组成的。
需要注意的是,要想被opengl按照设计被绘制必须正确的认识到,所谓的多边形是顶点都处于⼀个平⾯上,凸多边形。
凸多边形不能理解的,请问度娘。
来看⼀个例⼦:C++代码1. glBegin(GL_POLYGON);2. glVertex2f(0.0, 0.0);3. glVertex2f(0.0, 3.0);4. glVertex2f(4.0, 3.0);5. glVertex2f(6.0, 1.5);6. glVertex2f(4.0, 0.0);7. glEnd();先不去关⼼代码本⾝,这段代码最终的结果是要指定5个顶点绘制⼀个凸五边形。
注意,不是5条线段⽽是⼀个凸五边形的平⾯。
不管是点线⾯的哪⼀种,都是需要指定⼀组顶点的。
如何判定顶点指定的开始和结束就是glBegin和glEnd的⼯作。
引⽤void glBegin(Glenum mode);标志着⼀个顶点数据列表的开始,它描述了⼀个⼏何图元。
mode参数指定了图元的类型。
void glEnd(void);标志着⼀个顶点数据列表的结束。
mode设置的不同,代表着将要绘制的图元也不同。
下⾯这个表就是图元的名称和含义:值含义GL_POINTS 单个的点GL_LINES ⼀对顶点被解释为⼀条直线GL_LINE_STRIP ⼀系列的连接直线GL_LINE_LOOP 和上⾯相同,但第⼀个顶点和最后⼀个顶点彼此相连GL_TRIANGLES 3个顶点被解释为⼀个三⾓形GL_TRIANGLES_STRIP 三⾓形的连接串GL_TRIANGLES_FAN 连接成扇形的三⾓形系列GL_QUADS 4个顶点被解释为⼀个四边形GL_QUADS_STRIP 四边形的连接串GL_POLYGON 简单的凸多边形的边界试想着,如果将glBegin(GL_POLYGON)修改为glBegin(GL_POINTS),绘制出来的将是什么图形呢? 哈哈,那就是5个点⽽已么。
glLoadIdentity()与glTranslatef()和glRotatef()--坐标变换glLoadIdentity()将当前的用户坐标系的原点移到了屏幕中心:类似于一个复位操作1.X坐标轴从左至右,Y坐标轴从下至上,Z坐标轴从里至外。
2.OpenGL屏幕中心的坐标值是X和Y轴上的0.0f点。
3.中心左面的坐标值是负值,右面是正值。
移向屏幕顶端是正值,移向屏幕底端是负值。
移入屏幕深处是负值,移出屏幕则是正值。
glTranslatef(x, y, z)沿着X, Y 和Z 轴移动。
注意在glTranslatef(x, y, z)中,当您移动的时候,您并不是相对屏幕中心移动,而是相对与当前所在的屏幕位置。
其作用就是将你绘点坐标的原点在当前原点的基础上平移一个(x,y,z)向量。
/////////////////////////////////////////////////////////////////////////////////////////////////////////////glLoadIdentity();glTranslatef(-1.5f,0.0f,-6.0f);glBegin(GL_TRIANGLES);glVertex3f(0.0f,0.0f, 0.0f);glVertex3f(1.0f,0.0f, 0.0f);glVertex3f(0.0f,1.0f, 0.0f);glEnd();glLoadIdentity();glTranslatef(0.0f,0.0f,-6.0f);glBegin(GL_TRIANGLES);glVertex3f(0.0f,0.0f, 0.0f);glVertex3f(1.0f,0.0f, 0.0f);glVertex3f(0.0f,1.0f, 0.0f);glEnd();/////////////////////////////////////////////////////////////////////////////////////程序的运行结果如下:左边的三角形是第一步绘制的,可以看到该三角形绘制的坐标系,实际上是以(-1.5f,0.0f,-6.0f)为原点的。
OpenGL实现3DS文件中的模型自由旋转文章出处:/course/3_program/c++/cppsl/20071119/86921_2.html摘要简述如何在OpenGL中,读入和显示3DS文件中的模型,并着重阐述通过鼠标拖动对其进行自由旋转的数学基础和编程实现的方法。
关键词OpenGL 3DS文件格式VC++ 自由旋转现在已经有很多论文和书籍提到在OpenGL中实现读入和显示3DS文件中的模型。
但是在很多场合,仅读入和显示是不够的。
我们需要从各个角度观察模型,以便更好地理解模型的形态,形成更为直观的感性认识。
例如,在医学髁上骨折诊断中,如果把骨折后,断骨错位旋转的情况用三维模型模拟出来,并仅用鼠标的拖动就能实现从任何角度观看骨折的情况,这将对医生做出正确的诊断大有裨益。
这也是我们为何考虑实现此项功能的初衷。
本文将简要介绍3DS文件格式,怎样读入和显示模型,而重点放在通过鼠标拖动实现模型自由旋转的数学基础和编程实现的方法和经验。
3DS文件的格式以及读入和显示文件中模型的一些经验.3DS文件是由许多块(chunk)组成的(大块中镶嵌子块)。
由于至今为止,没有一个官方的文献说明其格式,所以还有很多未知的块。
不过这并不影响我们读入3DS文件中的模型。
因为我们在读入时,可以根据自己的需要选择性地读入自己需要的块,而忽略掉那些不感兴趣或未知的块。
这正是块结构给我们带来的好处。
一个块由块信息和块数据组成。
块信息又由块的ID(两个字节长的标识,如4D4D)和块的长度(四个字节,其实也就是下一个块的偏移字节数)组成。
用VC++以十六进制方式打开一3DS文件可以很清楚的看到其结构。
在读入这种块结构(大块中嵌套小块,而块的结构固定)的文件时,完全可以用递归的方法实现,而返回上一级(子块读完,返回父块)的条件则是当前已经读入的块的字节数是否等于块的长度。
从父块转向读入其子块,则可用switch语句实现,通过子块的ID判断进入哪个分支。
/** This Code Was Created By Jeff Molofee 2000* A HUGE Thanks To Fredric Echols For Cleaning Up* And Optimizing The Base Code, Making It More Flexible!* If You've Found This Code Useful, Please Let Me Know.* Visit My Site At */#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 LibraryHDC hDC=NULL; // Private GDI Device ContextHGLRC hRC=NULL; // Permanent Rendering ContextHWND hWnd=NULL; // Holds Our Window HandleHINSTANCE hInstance; // Holds The Instance Of The Applicationbool keys[256]; // Array Used For The Keyboard Routinebool active=TRUE; // Window Active Flag Set To TRUE By Defaultbool fullscreen=TRUE; // Fullscreen Flag Set To Fullscreen Mode By DefaultGLfloat rtri; // Angle For The Triangle ( NEW )GLfloat rquad; // Angle For The Quad ( NEW )LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProcGLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize The GL Window{if (height==0) // Prevent A Divide By Zero By{height=1; // Making Height Equal One }glViewport(0,0,width,height); // Reset The Current ViewportglMatrixMode(GL_PROJECTION); // Select The Projection MatrixglLoadIdentity(); // Reset The Projection Matrix// Calculate The Aspect Ratio Of The WindowgluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);glMatrixMode(GL_MODELVIEW); // Select The Modelview MatrixglLoadIdentity(); // Reset The Modelview Matrix}int InitGL(GLvoid) // All Setup For OpenGL Goes Here{glShadeModel(GL_SMOOTH); // Enable Smooth ShadingglClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black BackgroundglClearDepth(1.0f); // Depth Buffer Setup glEnable(GL_DEPTH_TEST); // Enables Depth TestingglDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To DoglHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculationsreturn TRUE; // Initialization Went OK}int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth BufferglLoadIdentity(); // Reset The Current Modelview MatrixglTranslatef(-1.5f,0.0f,-6.0f); // Move Left 1.5 Units And Into The Screen 6.0glRotatef(rtri,0.0f,1.0f,0.0f); // Rotate The Triangle On The Y axis ( NEW )glBegin(GL_TRIANGLES); // Start Drawing A TriangleglColor3f(1.0f,0.0f,0.0f); // RedglVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Front) glColor3f(0.0f,1.0f,0.0f); // GreenglVertex3f(-1.0f,-1.0f, 1.0f); // Left Of Triangle (Front)glColor3f(0.0f,0.0f,1.0f); // BlueglVertex3f( 1.0f,-1.0f, 1.0f); // Right Of Triangle (Front)glColor3f(1.0f,0.0f,0.0f); // RedglVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Right) glColor3f(0.0f,0.0f,1.0f); // BlueglVertex3f( 1.0f,-1.0f, 1.0f); // Left Of Triangle (Right)glColor3f(0.0f,1.0f,0.0f); // GreenglVertex3f( 1.0f,-1.0f, -1.0f); // Right Of Triangle (Right)glColor3f(1.0f,0.0f,0.0f); // RedglVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Back) glColor3f(0.0f,1.0f,0.0f); // GreenglVertex3f( 1.0f,-1.0f, -1.0f); // Left Of Triangle (Back) glColor3f(0.0f,0.0f,1.0f); // BlueglVertex3f(-1.0f,-1.0f, -1.0f); // Right Of Triangle (Back)glColor3f(1.0f,0.0f,0.0f); // RedglVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Left) glColor3f(0.0f,0.0f,1.0f); // BlueglVertex3f(-1.0f,-1.0f,-1.0f); // Left Of Triangle (Left) glColor3f(0.0f,1.0f,0.0f); // GreenglVertex3f(-1.0f,-1.0f, 1.0f); // Right Of Triangle (Left)glEnd(); // Done Drawing The PyramidglLoadIdentity(); // Reset The Current Modelview MatrixglTranslatef(1.5f,0.0f,-7.0f); // Move Right 1.5 Units And Into The Screen 7.0glRotatef(rquad,1.0f,1.0f,1.0f); // Rotate The Quad On The X axis ( NEW )glBegin(GL_QUADS); // Draw A Quad glColor3f(0.0f,1.0f,0.0f); // Set The Color To Green glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Top)glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Top)glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Quad (Top)glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Quad (Top)glColor3f(1.0f,0.5f,0.0f); // Set The Color To Orange glVertex3f( 1.0f,-1.0f, 1.0f); // Top Right Of The Quad (Bottom)glVertex3f(-1.0f,-1.0f, 1.0f); // Top Left Of The Quad (Bottom)glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Bottom)glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Bottom)glColor3f(1.0f,0.0f,0.0f); // Set The Color To RedglVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Front)glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Front)glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Front)glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Front)glColor3f(1.0f,1.0f,0.0f); // Set The Color To Yellow glVertex3f( 1.0f,-1.0f,-1.0f); // Top Right Of The Quad (Back)glVertex3f(-1.0f,-1.0f,-1.0f); // Top Left Of The Quad (Back)glVertex3f(-1.0f, 1.0f,-1.0f); // Bottom Left Of The Quad (Back)glVertex3f( 1.0f, 1.0f,-1.0f); // Bottom Right Of The Quad (Back)glColor3f(0.0f,0.0f,1.0f); // Set The Color To BlueglVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Left)glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Left)glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Left)glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Left)glColor3f(1.0f,0.0f,1.0f); // Set The Color To Violet glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Right)glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Right)glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Right)glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Right)glEnd(); // Done Drawing The Quadrtri+=0.2f; // Increase The Rotation Variable For The Triangle ( NEW )rquad-=0.15f; // Decrease The Rotation Variable For The Quad ( NEW )return TRUE; // Keep Going}GLvoid KillGLWindow(GLvoid) // Properly Kill The Window{if (fullscreen) // Are We In Fullscreen Mode?{ChangeDisplaySettings(NULL,0); // If So Switch Back To The DesktopShowCursor(TRUE); // Show Mouse Pointer }if (hRC) // Do We Have A Rendering Context?{if (!wglMakeCurrent(NULL,NULL)) // Are We Able To Release The DC And RC Contexts?{MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);}if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC?{MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);}hRC=NULL; // Set RC To NULL }if (hDC && !ReleaseDC(hWnd,hDC)) // Are We Able To Release The DC{MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);hDC=NULL; // Set DC To NULL }if (hWnd && !DestroyWindow(hWnd)) // Are We Able To Destroy The{MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);hWnd=NULL; // Set hWnd To NULL }if (!UnregisterClass("OpenGL",hInstance)) // Are We Able To Unregister Class{MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);hInstance=NULL; // Set hInstance To NULL }}/* This Code Creates Our OpenGL Window. Parameters Are: ** title - Title To Appear At The Top Of The Window ** width - Width Of The GL Window Or Fullscreen Mode ** height - Height Of The GL Window Or Fullscreen Mode ** bits - Number Of Bits To Use For Color (8/16/24/32) ** fullscreenflag - Use Fullscreen Mode (TRUE) Or Windowed Mode (FALSE) */BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag) {GLuint PixelFormat; // Holds The Results After Searching For A Match WNDCLASS wc; // Windows Class StructureDWORD dwExStyle; // Window Extended StyleDWORD dwStyle; // Window StyleRECT WindowRect; // Grabs Rectangle Upper Left / Lower Right Values WindowRect.left=(long)0; // Set Left Value To 0WindowRect.right=(long)width; // Set Right Value To Requested WidthWindowRect.top=(long)0; // Set Top Value To 0WindowRect.bottom=(long)height; // Set Bottom Value To Requested Heightfullscreen=fullscreenflag; // Set The Global Fullscreen FlaghInstance = GetModuleHandle(NULL); // Grab An Instance For Our Windowwc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Size, And Own DC For Window.wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc Handles Messageswc.cbClsExtra = 0; // No Extra Windowwc.cbWndExtra = 0; // No Extra Window Datawc.hInstance = hInstance; // Set The Instancewc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load The Default Iconwc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load The Arrow Pointerwc.hbrBackground = NULL; // No Background Required For GLwc.lpszMenuName = NULL; // We Don't Want A Menuwc.lpszClassName = "OpenGL"; // Set The Class Nameif (!RegisterClass(&wc)) // Attempt To Register The Window Class{MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE; // Return FALSE }if (fullscreen) // Attempt Fullscreen Mode?{DEVMODE dmScreenSettings; // Device Modememset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes Sure Memory's CleareddmScreenSettings.dmSize=sizeof(dmScreenSettings); // Size Of The Devmode StructuredmScreenSettings.dmPelsWidth = width; // Selected Screen WidthdmScreenSettings.dmPelsHeight = height; // Selected Screen HeightdmScreenSettings.dmBitsPerPel = bits; // Selected Bits Per PixeldmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;// Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.if(ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) {// If The Mode Fails, Offer Two Options. Quit Or Use Windowed Mode.if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not SupportedBy\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES){fullscreen=FALSE; // Windowed Mode Selected. Fullscreen = FALSE}else{// Pop Up A Message Box Letting User Know The Program Is Closing.MessageBox(NULL,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP);return FALSE; // Return FALSE }}}if (fullscreen) // Are We Still In Fullscreen Mode?{dwExStyle=WS_EX_APPWINDOW; // Window Extended StyledwStyle=WS_POPUP; // Windows StyleShowCursor(FALSE); // Hide Mouse Pointer}else{dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended StyledwStyle=WS_OVERLAPPEDWINDOW; // Windows Style }AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requested Size// Create The Windowif (!(hWnd=CreateWindowEx( dwExStyle, // Extended Style For The Window"OpenGL", // Class Nametitle, // Window TitledwStyle | // Defined Window StyleWS_CLIPSIBLINGS | // Required Window StyleWS_CLIPCHILDREN, // Required Window Style0, 0, // Window PositionWindowRect.right-WindowRect.left, // Calculate Window WidthWindowRect.bottom-WindowRect.top, // Calculate Window HeightNULL, // No Parent WindowNULL, // No MenuhInstance, // InstanceNULL))) // Dont Pass Anything To WM_CREATE{KillGLWindow(); // Reset The DisplayMessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE; // Return FALSE }static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be{sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor1, // Version NumberPFD_DRAW_TO_WINDOW | // Format Must Support WindowPFD_SUPPORT_OPENGL | // Format Must Support OpenGLPFD_DOUBLEBUFFER, // Must Support Double BufferingPFD_TYPE_RGBA, // Request An RGBA Formatbits, // Select Our Color Depth0, 0, 0, 0, 0, 0, // Color Bits Ignored0, // No Alpha Buffer0, // Shift Bit Ignored0, // No Accumulation Buffer0, 0, 0, 0, // Accumulation Bits Ignored16, // 16Bit Z-Buffer (Depth Buffer)0, // No Stencil Buffer0, // No Auxiliary BufferPFD_MAIN_PLANE, // Main Drawing Layer0, // Reserved0, 0, 0 // Layer Masks Ignored };if (!(hDC=GetDC(hWnd))) // Did We Get A Device Context?{KillGLWindow(); // Reset The DisplayMessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE; // Return FALSE }if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd))) // Did Windows Find A Matching Pixel Format?{KillGLWindow(); // Reset The DisplayMessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE; // Return FALSE }if(!SetPixelFormat(hDC,PixelFormat,&pfd)) // Are We Able To Set The Pixel Format?{KillGLWindow(); // Reset The DisplayMessageBox(NULL,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE; // Return FALSE }if (!(hRC=wglCreateContext(hDC))) // Are We Able To Get A Rendering Context?{KillGLWindow(); // Reset The DisplayMessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE; // Return FALSE }if(!wglMakeCurrent(hDC,hRC)) // Try To Activate The Rendering Context{KillGLWindow(); // Reset The DisplayMessageBox(NULL,"Can't Activate The GL RenderingContext.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE; // Return FALSE }ShowWindow(hWnd,SW_SHOW); // Show The WindowSetForegroundWindow(hWnd); // Slightly Higher Priority SetFocus(hWnd); // Sets Keyboard Focus To The WindowReSizeGLScene(width, height); // Set Up Our Perspective GL Screenif (!InitGL()) // Initialize Our Newly Created GL Window{KillGLWindow(); // Reset The DisplayMessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE; // Return FALSE }return TRUE; // Success}LRESULT CALLBACK WndProc( HWND hWnd, // Handle For This WindowUINT uMsg, // Message For This WindowWPARAM wParam, // Additional Message InformationLPARAM lParam) // Additional Message Information{switch (uMsg) // Check For Windows Messages {case WM_ACTIVATE: // Watch For Window Activate Message{// LoWord Can Be WA_INACTIVE, WA_ACTIVE, WA_CLICKACTIVE,// The High-Order Word Specifies The Minimized State Of The Window Being Activated Or Deactivated.// A NonZero Value Indicates The Window Is Minimized.if ((LOWORD(wParam) != WA_INACTIVE) && !((BOOL)HIWORD(wParam)))active=TRUE; // Program Is Activeelseactive=FALSE; // Program Is No Longer Activereturn 0; // Return To The Message Loop }case WM_SYSCOMMAND: // Intercept System Commands{switch (wParam) // Check System Calls{case SC_SCREENSAVE: // Screensaver Trying To Start?case SC_MONITORPOWER: // Monitor Trying To Enter Powersave?return 0; // Prevent From Happening }break; // Exit}case WM_CLOSE: // Did We Receive A Close Message?{PostQuitMessage(0); // Send A Quit Messagereturn 0; // Jump Back}case WM_KEYDOWN: // Is A Key Being Held Down?{keys[wParam] = TRUE; // If So, Mark It As TRUEreturn 0; // Jump Back}case WM_KEYUP: // Has A Key Been Released?{keys[wParam] = FALSE; // If So, Mark It As FALSEreturn 0; // Jump Back}case WM_SIZE: // Resize The OpenGL Window{ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // LoWord=Width, HiWord=Heightreturn 0; // Jump Back}}// Pass All Unhandled Messages To DefWindowProcreturn DefWindowProc(hWnd,uMsg,wParam,lParam);}int WINAPI WinMain( HINSTANCE hInstance, // InstanceHINSTANCE hPrevInstance, // Previous InstanceLPSTR lpCmdLine, // Command Line Parametersint nCmdShow) // Window Show State{MSG msg; // Windows Message StructureBOOL done=FALSE; // Bool Variable To Exit Loop// Ask The User Which Screen Mode They Preferif (MessageBox(NULL,"Would You Like To Run In Fullscreen Mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO){fullscreen=FALSE; // Windowed Mode }// Create Our OpenGL Windowif (!CreateGLWindow("NeHe's Solid Object Tutorial",640,480,16,fullscreen)){return 0; // Quit If Window Was Not Created}while(!done) // Loop That Runs While done=FALSE {if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Is There A Message Waiting?{if (msg.message==WM_QUIT) // Have We Received A Quit Message?{done=TRUE; // If So done=TRUE}else // If Not, Deal With Window Messages{TranslateMessage(&msg); // Translate The MessageDispatchMessage(&msg); // Dispatch The Message }}else // If There Are No Messages{// Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene()if ((active && !DrawGLScene()) || keys[VK_ESCAPE]) // Active? Was There A Quit Received?{done=TRUE; // ESC or DrawGLSceneSignalled A Quit}else // Not Time To Quit, Update Screen{SwapBuffers(hDC); // Swap Buffers (Double Buffering)}if (keys[VK_F1]) // Is F1 Being Pressed?{keys[VK_F1]=FALSE; // If So Make Key FALSEKillGLWindow(); // Kill Our Current Windowfullscreen=!fullscreen; // Toggle Fullscreen / Windowed Mode// Recreate Our OpenGL Windowif (!CreateGLWindow("NeHe's Solid Object Tutorial",640,480,16,fullscreen)){return 0; // Quit If Window Was Not Created}}}}// ShutdownKillGLWindow(); // Kill The Windowreturn (msg.wParam); // Exit The Program}。
OpenGL入门学习——第五课三维的空间变换今天要讲的是三维变换的内容,课程比较枯燥。
主要是因为很多函数在单独使用时都不好描述其效果,我只好在最后举一个比较综合的例子。
希望大家能一口气看到底了。
只看一次可能不够,如果感觉到迷糊,不妨多看两遍。
有疑问可以在下面跟帖提出。
我也使用了若干图形,希望可以帮助理解。
在前面绘制几何图形的时候,大家是否觉得我们绘图的范围太狭隘了呢?坐标只能从-1到1,还只能是X轴向右,Y轴向上,Z轴垂直屏幕。
这些限制给我们的绘图带来了很多不便。
我们生活在一个三维的世界——如果要观察一个物体,我们可以:1、从不同的位置去观察它。
(视图变换)2、移动或者旋转它,当然了,如果它只是计算机里面的物体,我们还可以放大或缩小它。
(模型变换)3、如果把物体画下来,我们可以选择:是否需要一种“近大远小”的透视效果。
另外,我们可能只希望看到物体的一部分,而不是全部(剪裁)。
(投影变换)4、我们可能希望把整个看到的图形画下来,但它只占据纸张的一部分,而不是全部。
(视口变换)这些,都可以在OpenGL中实现。
OpenGL变换实际上是通过矩阵乘法来实现。
无论是移动、旋转还是缩放大小,都是通过在当前矩阵的基础上乘以一个新的矩阵来达到目的。
关于矩阵的知识,这里不详细介绍,有兴趣的朋友可以看看线性代数(大学生的话多半应该学过的)。
OpenGL可以在最底层直接操作矩阵,不过作为初学,这样做的意义并不大。
这里就不做介绍了。
1、模型变换和视图变换从“相对移动”的观点来看,改变观察点的位置与方向和改变物体本身的位置与方向具有等效性。
在OpenGL中,实现这两种功能甚至使用的是同样的函数。
由于模型和视图的变换都通过矩阵运算来实现,在进行变换前,应先设置当前操作的矩阵为“模型视图矩阵”。
设置的方法是以GL_MODELVIEW为参数调用glMatrixMode函数,像这样:glMatrixMode(GL_MODELVIEW);通常,我们需要在进行变换前把当前矩阵设置为单位矩阵。
旋转的立方体通过本例学习,应掌握三维图层、“摄像机”图层、“空白”图层的建立,图层素材“替换”、“父源”属性设置的方法,以及“位置”和立体“旋转”设置方法。
1.建立一个新的合成图像“旋转的立方体”,参数:宽640,高480,30帧/秒,长度为10秒。
2.建立一个固态层,参数:宽200,高200,正方形像素,颜色为255,0,0。
3.选择固态层,按<Ctrl+D>组合键5次,复制出5个图层,分别改变5个固态层的颜色为不同的颜色经。
(选择某个固态层,选择“图层/固态层设置”命令)。
4.单击三维图层按钮,将6个固态层转换为三维图层。
5.创建摄像机层。
在时间线窗口中单击右键,在弹出的快捷菜单中选择“新建/摄像机”命令。
然后在弹出的对话框设置参数:预置50MM,其他不变。
6.为便于观察立方体,按<C>键切换到图层旋转工具,在预览窗口中拖动鼠标旋转视图。
7.制作立方体。
同时选择6个固态层,按<R>键打开旋转参数设置,6个固态层的“方向”值依次是:90,0,0/0,90,0/0,0,90/270,0,0/0,0,0/0,270,0。
(在调整过程中可不断旋转视图,以便观察各面的位置)8.按<P>键打开位置参数设置,依次是:320,340,100/220,240,100/320,240,200/320,240,100/320,240,0/420,240,100。
9.用图片替换不同颜色的固态层。
在“项目”窗口中选择一个固态层,然后右击,在弹出的快捷菜单中选择“替换素材/文件”命令,接着在弹出的对话框中选择需要替换的图片文件。
(切记:把对话框左下方的“序列不可用”取消钩选)10.制作立方体旋转着飞入场景画面。
要时间线窗口的空白处单击右键,从弹出的快捷菜单中选择“新建/空白对象”命令,新建一个“空白1”层。
目录1.课程设计介绍 (1)1.1.内容 (1)1.2.目的 (1)1.3.取得的成果 (1)2.程序分析 (2)2.1. 程序原理 (2)2.1. 程序流程 (3)2.3. 数据结构 (8)2.4. 重要函数用法分析 (8)3.结果演示与程序分析 (9)3.1. 成果演示 (9)3.2. 程序分析 (11)4.编程中遇到的问题 (12)5.课程设计小结 (13)参考文献 (14)基于OpenGL的3D旋转魔方实现1.课程设计介绍1.1目的当今计算机技术流行,引领了各行各业。
而程序是计算机的灵魂,因此编程能力对当今的学生而言至关重要。
虽然我们在前期已经学习了C语言,但是还只对程序有一些简单的认识,说实话,是很浅显的认识。
通过本软件课程设计的学习,可以从整体上对软件工程和项目有全面的认识。
通过此次课程设计,可以锻炼编程能力,激发对编程的兴趣,同时也能培养良好的编程习惯。
这对于个人今后的学习,今后的工作乃至今后的生活都会产生重要的影响。
对于国家而言,极大的推动了计算机普及教育,提高了大学生的计算机使用水平,具有重大的意义。
1.2内容(1)通过此次项目掌握软件开发模式,模块化结构分析以及程序设计流程(2)学会使用VC++6.0进行编程(3)掌握有关程序设计的思想,数据结构的知识,掌握C语言算法,掌握OpenGL 编程知识如贴图与键盘控制(4)掌握win32编程知识,了解windows程序内部运行机制(5)初步培养需求分析、软件测试、调试的能力(6)在2X2魔方的基础上,尝试编写3X3的魔方,并实现其旋转1.3取得的成果在理解Magic2D例子程序的基础上,借助了Win32平台进行了一系列调试和学习。
在此次项目中,学习了Visual C++6.0软件开发环境,熟练掌握了Win32 Application开发流程。
同时也学习了OpenGL的基本知识,掌握了一些OpenGL的重要技术与重要函数的使用,编写了一些简单的OpenGL程序。
XXXXXXXX大学(计算机图形学)实验报告实验名称利用OpenGL实现图形的平移、旋转、缩放实验时间年月日专业姓名学号预习操作座位号教师签名总评一、实验目的:1.了解OpenGL下简单图形的平移、旋转、缩放变换的编程的基本思想;2.掌握OpenGL下简单图形的平移、旋转、缩放变换的编程的基本步骤;二、实验原理:在OpenGL中,可以使用下面三个函数便捷地实现简单图形平移、旋转、缩放变换的功能:glRotatef(theta, vx, vy, vz);glTranslatef(dx, dy, dz);glScalef(sx,sy,sz);三、实验内容:// 1.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include "glut.h"#include "math.h"void display(){glClear( GL_COLOR_BUFFER_BIT); // Clear the frame bufferglColor3f( 0.0, 1.0, 1.0); // Set current color to greenglBegin( GL_POL YGON); // Draw the triangleglVertex2f( 0.0, -0.2);glVertex2f( 0.2, 0.0);glVertex2f( 0.0, 0.0);glEnd();glFlush();}void dsp()glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // Clear the frame bufferglColor3f( 0.0, 1.0, 1.0); // Set current color to greendisplay();//-------------------------- //平移glPushMatrix();glTranslatef(0.5,0.5,0.0);display();glPopMatrix();//-------------------------- //缩放glPushMatrix();glScalef(0.5,0.5,0.0);display();glPopMatrix();//-------------------------- //旋转glPushMatrix();glRotatef(60,0.0,0.0,1.0);display();glPopMatrix();}void init(){glClearColor( 0.0, 0.0, 0.0, 0.0); // Set the clear color to black// Specify the boundaries of the viewing windowglMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(-1.0, 1.0, -1.0, 1.0); // The para are: (left, right, bottom, top)glMatrixMode(GL_MODELVIEW);}int main(int argc, char* argv[]){glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);glEnable(GL_DEPTH_TEST);glutCreateWindow("simple");glutDisplayFunc(dsp);init();glutMainLoop();return 0;原图:平移:缩放:旋转:四、实验总结:1.在分别查看图像的平移、缩放、旋转中的其中一个功能时,需要将其他两个的代码注释掉,否则只会显示旋转一个功能。
华中科技大学电子科学与技术系课程设计报告( 2010-- 2011年度第2 学期)名称:软件课程设计题目:基于OpenGL的3D旋转魔方实现院系:班级:学号:学生姓名:指导教师:设计周数:成绩:日期:年月日目录1.课程设计介绍............................................................................................ (2)1.1目的.............................................................................................................. (2)1.2内容.............................................................................................................. (2)1.3取得的成果 (2)2.程序分析..................................................................................................... (3)2.1 程序原理 (3)2.2 程序流程 (4)2.3 数据结构 (13)2.4 重要函数 (13)3.程序分析与结果演示 (16)3.1 成果演示 (16)3.2 程序分析 (17)4.出现过的问题 (18)5.心得和小节 (19)1.课程设计介绍1.1目的21世纪是高科技时代,是信息技术时代,而计算机技术无疑会引领各行各业,为我们带来一个全新的时代。
作为新世纪的接班人,我们必须拥有良好的计算机应用能力,才能跟上世界发展的大流,不至于在激烈的竞争中被淘汰。
而程序作为计算机的灵魂,因此编程能力对当代大学生来说至关重要。
/*******/基于openGl的三维旋转魔方源代码This Code Was Created By Jeff Molofee 2000A HUGE Thanks To Fredric Echols For Cleaning UpAnd Optimizing The Base Code, Making It More Flexible!If You've Found This Code Useful, Please Let Me Know.// Header File For Standard Input/Output#include "MoFang.h"HDCHGLRCHWNDboolkeys[256];boolactive=TRUE;GLfloatGLfloatGLfloatGLfloat RX;GLfloat RY;GLuintGLboolean b_RX,b_RY;LRESULTAUX_RGBImageRec *LoadBMP(char *Filename){if (!Filename)// Make Sure A Filename Was GivenFILE *File=NULL;// File Handle// Loads A Bitmap ImageCALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);// Declaration For WndProctexture[24];// Storage For One Texture ( NEW )xrot;yrot;zrot;// X Rotation ( NEW )// Y Rotation ( NEW )// Z Rotation ( NEW )// Array Used For The Keyboard Routine// Window Active Flag Set To TRUE By DefaulthDC=NULL;hRC=NULL;hWnd=NULL;// Private GDI Device Context// Permanent Rendering Context// Holds Our Window HandleHINSTANCEhInstance;// Holds The Instance Of The Applicationboolfullscreen=TRUE; // Fullscreen Flag Set To Fullscreen Mode By Default}{}File=fopen(Filename,"r");if (File){}return NULL;// If Load Failed Return NULLfclose(File);// Close The Handle// Load The Bitmap And Return A Pointerreturn auxDIBImageLoad(Filename);// Check To See If The File Exists// Does The File Exist?return NULL;// If Not Return NULLint LoadGLTextures(){if (TextureImage[0]){}int Status=FALSE;// Load Bitmaps And Convert To Textures// Status Indicator// Create Storage Space For The TextureAUX_RGBImageRec *TextureImage[1];memset(TextureImage,0,sizeof(void *)*1);// Set The Pointer To NULL// Load The Bitmap, Check For Errors, If Bitmap's Not Found Quitif (TextureImage[0]=LoadBMP("Data/NeHe.bmp")){Status=TRUE;// Set The Status To TRUEglGenTextures(1, &texture[0]);// Create The Texture// Typical Texture Generation Using Data From The BitmapglBindTexture(GL_TEXTURE_2D, texture[0]);glTexImage2D(GL_TEXTURE_2D,0,3,TextureImage[0]->sizeX,TextureImage[0]->si zeY,0,GL_RGB,glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEA R);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);GL_UNSIGNED_BYTE, TextureImage[0]->data);// If Texture Exists// If Texture Image Exists// Free The Texture Image Memoryif (TextureImage[0]->data){}free(TextureImage[0]->data);}int LoadGLTextures(char*file,int index)Convert To Textures{}int Status=FALSE;AUX_RGBImageRec *TextureImage[1];memset(TextureImage,0,sizeof(void *)*1);// Set The Pointer To NULL// Load The Bitmap, Check For Errors, If Bitmap's Not Found Quitif (TextureImage[0]=LoadBMP(file)){}if (TextureImage[0]){}return Status;// Return The Statusif (TextureImage[0]->data){}free(TextureImage[0]);// Free The ImageStructurefree(TextureImage[0]->data);// Free The Texture Image Memory// If Texture Image Exists// If Texture ExistsStatus=TRUE;glGenTextures(1, &texture[index]);// Typical Texture Generation Using Data From The BitmapglBindTexture(GL_TEXTURE_2D, texture[index]);glTexImage2D(GL_TEXTURE_2D,0,3,TextureImage[0]->sizeX,TextureImage[0]->si zeY,0,GL_RGB,glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEA R);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);// Create The Texture// Set The Status To TRUE// Create Storage Space For The Texture// Status Indicator//LoadBitmapsAndreturn Status;// Return The Status}free(TextureImage[0]);// Free The Image StructureGL_UNSIGNED_BYTE, TextureImage[0]->data);GLvoid ReSizeGLScene(GLsizei width, GLsizei height){}int InitGL(GLvoid){if (!LoadGLTextures("Data/y3."bmp",2)){}if (!LoadGLTextures("Data/y4."bmp",3)){}if (!LoadGLTextures("Data/y5."bmp",4))return FALSE;return FALSE;if (!LoadGLTextures("Data/y2."bmp",1)){}return FALSE;if (!LoadGLTextures("Data/y1."bmp",0)){}return FALSE;glMatrixMode(GL_MODELVIEW);glLoadIdentity();// Calculate The Aspect Ratio Of The WindowglMatrixMode(GL_PROJECTION);glLoadIdentity();glViewport(0,0,width,height);if (height==0){}height=1;// Resize And Initialize The GL Window// Prevent A Divide By Zero By// Making Height Equal One// Reset The Current Viewport// Select The Projection Matrix// Reset The Projection MatrixgluPerspective(45."0f,(GLfloat)width/(GLfloat)height,0."1f,100."0f);// Select The Modelview Matrix// Reset The Modelview Matrix// All Setup For OpenGL Goes Here// Jump To Texture LoadingRoutine ( NEW )// If Texture Didn't Load Return FALSE// Jump To Texture LoadingRoutine ( NEW )// If Texture Didn't Load Return FALSE// Jump To Texture LoadingRoutine ( NEW )// If Texture Didn't Load Return FALSE// Jump To Texture LoadingRoutine ( NEW )// If Texture Didn't Load Return FALSE// Jump To Texture LoadingRoutine ( NEW )}void DrawObject1(GLfloat X,GLfloat Y,GLfloat Z){glBegin(GL_QUADS);// Front FaceglTexCoord2f(0."0f,0."0f); glVertex3f(-1."0f + X, -1."0f + Y,1."0f + Z);glTexCoord2f(1."0f,0."0f); glVertex3f(1."0f + Y,1."0f + Z); glTexCoord2f( 1."0f,1."0f); glVertex3f( 1."0f + X,1."0f + Y,1."0f + Z); glTexCoord2f(0."0f,1."0f); glVertex3f(- 1."0f + X,1."0f + Y,1."0f + Z);// Back Face glTexCoord2f( 1."0f,0."0f); glVertex3f(-1."0f + X, - 1."0f + Y, -glTexCoord2f(1."0f,1."0f); glVertex3f(-1."0f + X,1."0f + Y, -1."0f + Z);glTexCoord2f(0."0f,1."0f); glVertex3f(1."0f + X,1."0f + Y, -1."0f + Z);glTexCoord2f(0."0f,0."0f); glVertex3f(1."0f + X, -1."0f + Y, -1."0f + Z);{}if (!LoadGLTextures("Data/y 6."bmp",5)){}if (!LoadGLTextures("Data/y7."bmp",6)){}if (!LoadGLTextures("Data/y8."bmp",7)){}glEnable(GL_TEXTURE_2D);glShadeModel(GL_SMOOTH);glClearDepth(1."0f);// Enable Texture Mapping ( NEW )// Enable Smooth Shading// Depth Buffer Setup// The Type Of Depth Testing To Do// Initialization Went OKreturn FALSE;// If Texture Didn't Load Return FALSE// Jump To Texture Loadingreturn FALSE;// If Texture Didn't Load Return FALSE// Jump To Texture Loadingreturn FALSE;// If Texture Didn't Load Return FALSE// Jump To Texture Loadingreturn FALSE;// If Texture Didn't Load Return FALSERoutine ( NEW )Routine ( NEW )Routine ( NEW )glClearColor(0."0f,0."0f,0."0f,0."5f);glEnable(GL_DEPTH_TEST);glDepthFunc(GL_LEQUAL);return TRUE;// Black Background// Enables Depth TestingglHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);// Really Nice Perspective Calculations}// Top FaceglTexCoord2f(0."0f,1."0f); glVertex3f(-1."0f + X,1."0f + Y, -1."0f + Z);glTexCoord2f(0."0f,0."0f); glVertex3f(-1."0f + X,1."0f + Y,1."0f + Z);glTexCoord2f(1."0f,0."0f); glVertex3f(1."0f + X,1."0f + Y,1."0f + Z);glTexCoord2f( 1."0f,1."0f); glVertex3f( 1."0f + X,1."0f + Y, - 1."0f + Z);// Bottom Face glTexCoord2f( 1."0f,1."0f); glVertex3f(- 1."0f + X, - 1."0f + Y, - 1."0f + Z); glTexCoord2f(0."0f,1."0f); glVertex3f( 1."0f + X, - 1."0f + Y, - 1."0f + Z); glTexCoord2f( 0."0f,0."0f); glVertex3f(1."0f + X, - 1."0f + Y,1."0f + Z); glTexCoord2f( 1."0f,0."0f); glVertex3f(-1."0f + X, - 1."0f + Y,1."0f + Z);// Right face glTexCoord2f( 1."0f,0."0f); glVertex3f(1."0f + X, - 1."0f + Y, - 1."0f + Z); glTexCoord2f( 1."0f,1."0f); glVertex3f( 1."0f + X,1."0f + Y, - 1."0f + Z); glTexCoord2f(0."0f,1."0f); glVertex3f( 1."0f + X,1."0f + Y,1."0f + Z); glTexCoord2f( 0."0f,0."0f); glVertex3f(1."0f + X, - 1."0f + Y,1."0f + Z);// Left Face glTexCoord2f( 0."0f,0."0f); glVertex3f(-1."0f + X, - 1."0f + Y, - 1."0f + Z);1."0f,0."0f); glVertex3f(-1."0f + X, -1."0f + Y,1."0f + Z);glTexCoord2f(1."0f,1."0f); glVertex3f(-1."0f + X,1."0f + Y,1."0f + Z);glTexCoord2f(0."0f,1."0f); glVertex3f(-1."0f + X,1."0f + Y, -1."0f + Z);glEnd();void DrawObject(int ID){glBegin(GL_QUADS); // Front Face0."0f,0."0f); glVertex3fv( CubePoint[0].p); glTexCoord2f(1."0f,0."0f); glVertex3fv( CubePoint[1].p); glTexCoord2f(1."0f,1."0f); glVertex3fv( CubePoint[2].p); glTexCoord2f(0."0f,1."0f); glVertex3fv( CubePoint[3].p); // Back FaceglTexCoord2f(1."0f,0."0f); glVertex3fv( CubePoint[4].p); glTexCoord2f(1."0f,1."0f); glVertex3fv( CubePoint[5].p); glTexCoord2f(0."0f,glTexCoord2f(0."0f,0."0f); glVertex3fv( CubePoint[7].p);// Top FaceglTexCoord2f(0."0f,1."0f); glVertex3fv( CubePoint[5].p); glTexCoord2f(0."0f,0."0f); glVertex3fv( CubePoint[3].p); stPoint *CubePoint = Cube[ID].CubePoint; glTexCoord2f(1."0f,0."0f); glVertex3fv( CubePoint[2].p); glTexCoord2f(1."0f,1."0f); glVertex3fv( CubePoint[6].p);// Bottom FaceglTexCoord2f(1."0f,glTexCoord2f(0."0f,1."0f); glVertex3fv( CubePoint[7].p); glTexCoord2f(0."0f,0."0f); glVertex3fv( CubePoint[1].p); glTexCoord2f(1."0f,0."0f); glVertex3fv( CubePoint[0].p); // Right faceglTexCoord2f(1."0f,0."0f); glVertex3fv( CubePoint[7].p); glTexCoord2f(1."0f,1."0f); glVertex3fv( CubePoint[6].p); glTexCoord2f(0."0f,1."0f); glVertex3fv( CubePoint[2].p); glTexCoord2f(0."0f); glVertex3fv( CubePoint[1].p);// Left FaceglTexCoord2f(0."0f,0."0f); glVertex3fv( CubePoint[4].p);glTexCoord2f(1."0f,0."0f); glVertex3fv( CubePoint[0].p);glTexCoord2f(1."0f,1."0f); glVertex3fv( CubePoint[3].p);glTexCoord2f(0."0f,1."0f); glVertex3fv( CubePoint[5].p);glEnd();}int DrawGLScene(GLvoid)Drawing{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity();glTranslatef(0."0f,0."0f,-glTranslatef(RX,0."0f,0."0f);glTranslatef(0."0,RY,0."0);glRotatef(xrot,1."0f,0."0f,0."0f);glRotatef(yrot,0."0f,1."0f,0."0f);glRotatef(zrot,0."0f,0."0f,1."0f);//glBindTexture(GL_TEXTURE_2D, texture[0]);DrawObject(0);glBindTexture(GL_TEXTURE_2D, texture[1]);//Here'sWhereWeDoAllThe// Clear The Screen And The Depth Buffer// Reset The ViewDrawObject(1);glBindTexture(GL_TEXTURE_2D, texture[2]);DrawObject(2);glBindTexture(GL_TEXTURE_2D, texture[3]);DrawObject(3);glBindTexture(GL_TEXTURE_2D, texture[4]);DrawObject(4);glBindTexture(GL_TEXTURE_2D, texture[5]);DrawObject(5);glBindTexture(GL_TEXTURE_2D, texture[6]);DrawObject(6);glBindTexture(GL_TEXTURE_2D, texture[7]);DrawObject(7);/**/xrot+=0."15f;yrot+=0."1f;zrot+=0."2f;return TRUE;}GLvoid KillGLWindow(GLvoid){if(fullscreen){ChangeDisplaySettings(NULL,0);ShowCursor(TRUE);}if (hRC){if (!wglMakeCurrent(NULL,NULL))Contexts?{MessageBox(NULL,"ReleaseOfDCMB_ICONINFORMATION);// Keep Going// Properly Kill The Window// Are We In Fullscreen Mode?// If So Switch Back To The Desktop// Show Mouse Pointer// Do We Have A RenderingContext?//AreWeAbleToReleaseTheDCAndRCFailed.","SHUTDOWNERROR",MB_OK|} if(!wglDeleteContext(hRC)){MessageBox(NULL,"ReleaseRenderingContextFailed.","SH UTDOWNERROR",MB_OK|// Are We Able To Delete TheRC?MB_ICONINFORMATION);}hRC=NULL;// Set RC To NULL}if (hDC&& !ReleaseDC(hWnd,hDC))// Are We Able To Release The DC{MessageBox(NULL,"ReleaseDeviceContextFailed.","SHUTDOWNERROR",MB_OK MB_ICONINFORMATION);hDC=NULL;// Set DC To NULL}if (hWnd && !DestroyWindow(hWnd))// Are We Able To Destroy The Window?{MessageBox(NULL,"CouldNotReleasehWnd.","SHUTDOWNERROR",MB_OKMB_I CONINFORMATION);hWnd=NULL;// Set hWnd To NULL}if (!UnregisterClass("OpenGL",hInstance))// Are We Able To UnregisterClass{MessageBox(NULL,"CouldNotUnregisterClass.","SHUTDOWNERROR",MB_OKM B_ICONINFORMATION);hInstance=NULL;// Set hInstance To NULL}}/*This Code Creates Our OpenGL Window.Parameters Are:**title- Title To Appear At The Top Of The Window**width- Width Of The GL Window Or Fullscreen Mode**height- Height Of The GL Window Or Fullscreen Mode**bits- Number Of Bits To Use For Color (/)**fullscreenflag- Use Fullscreen Mode (TRUE) Or Windowed Mode (FALSE)*/BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag){GLuintPixelFormat;// Holds The Results After Searching For A MatchWNDCLASSwc;// Windows Class StructureDWORDdwExStyle;// Window Extended Style|||DWORDRECTdwStyle;// Window Style// Grabs Rectangle Upper Left / Lower Right ValuesWindowRect;WindowRect.left=(long)0;WindowRect.top=(long)0;// Set Left Value To 0// Set Right Value To Requested Width// Set Top Value To 0// Set Bottom Value To Requested HeightWindowRect.right=(long)width;WindowRect.bottom=(long)height;fullscreen=fullscreenflag;hInstancewc.style// Set The Global Fullscreen Flag// Grab An Instance For Our Window// Redraw On Size, And Own DC// WndProc Handles Messages// No Extra Window Data// No Extra Window Data// Set The Instance= GetModuleHandle(NULL);= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;= (WNDPROC) WndProc;= 0;= 0;For Window.wc.lpfnWndProcwc.cbClsExtrawc.hInstancewc.hIconwc.hCursorwc.cbWndExtra= hInstance;= LoadIcon(NULL, IDI_WINLOGO);= LoadCursor(NULL, IDC_ARROW);= NULL;// Load The Default Icon// Load The Arrow Pointer// No Background Required//WeDon'tWantAwc.hbrBackgroundwc.lpszMenuNamewc.lpszClassNameFor GL= NULL;Menu= "OpenGL";// Set The Class Nameif (!RegisterClass(&wc)){}if (fullscreen){//AttemptToRegisterTheWindow ClassMessageBox(NULL,"Failedreturn FALSE;ToRegisterThe// Return FALSEWindowClass.","ERROR",MB_OK|MB_ICONEXCLAMATION);//AttemptFullscreenMode?DEVMODE dmScreenSettings;// DeviceModemset(&dmScreenSettings,0,sizeof(dmScreenSettings));dmScreenSettings.dmSize=sizeof(dmScreenSettings);dmScreenSettings.dmPelsWidth= width;dmScreenSettings.dmBitsPerPel= bits;dmScreenSettings.dmPelsHeight= height;// Makes Sure Memory's Cleared// Size Of The Devmode Structure// Selected Screen Width// Selected Screen Height// Selected Bits PerPixeldmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGH T;// Try To Set Selected Mode And Get Results.NOTE:CDS_FULLSCREEN Gets Rid Of Start Bar.StyleStyleStyle}if(ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUC CESSFUL){}// If The Mode Fails, Offer Two Options.Quit Or Use Windowed Mode.if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not SupportedBy\nYour Video Card.{}else{}// Pop Up A Message Box Letting User Know The Program Is Closing.MessageBox(NULL,"Program Will NowClose.","ERROR",MB_OK|MB_ICONSTOP);return FALSE;// Return FALSEfullscreen=FALSE;// Windowed Mode Selected.Fullscreen = FALSEUse Windowed Mode Instead?","NeHeGL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)if (fullscreen){}else{}// Are We Still In FullscreenMode?dwExStyle=WS_EX_APPWINDOW;dwStyle=WS_POPUP;ShowCursor(FALSE);// Window Extended Style// Windows Style// Hide Mouse PointerdwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;dwStyle=WS_OVERLAPPEDWINDOW;// Window Extended Style// Windows StyleAdjustWindowRectEx(&WindowRect, dwStyle, FALSE,dwExStyle);//AdjustWindowToTrueRequested Size// Create The Windowif (!(hWnd=CreateWindowEx(dwExStyle,//ExtendedStyleForThe// Class Name// Window Title//DefinedWindow//RequiredWindow//RequiredWindow"OpenGL",title,dwStyle |WS_CLIPSIBLINGS |WS_CLIPCHILDREN,{}0, 0,// Window PositionCalculateWindowRect.right-WindowRect.left,// Calculate Window WidthWindowRect.bottom-WindowRect.top,//NULL,NULL,NULL)))Height//NoParent// No Menu//DontPassWindowhInstance,// InstanceAnything To WM_CREATEKillGLWindow();return FALSE;// Reset The Display// Return FALSEMessageBox(NULL,"Window CreationError.","ERROR",MB_OK|MB_ICONEXCLAMATION);static PIXELFORMATDESCRIPTOR pfd={};if (!(hDC=GetDC(hWnd))){}KillGLWindow();return FALSE;sizeof(PIXELFORMATDESCRIPTOR),1,PFD_DRAW_TO_WINDOW |PFD_SUPPORT_OPENGL |PFD_DOUBLEBUFFER,PFD_TYPE_RGBA,bits,0,0,0,0, 0, 0, 0, 0, 0,// pfd Tells Windows How We Want Things To Be// Size Of This Pixel Format Descriptor// Version Number// Format Must Support Window// Format Must Support OpenGL// Must Support Double Buffering// Request An RGBA Format// Select Our Color Depth// No Alpha Buffer// Shift Bit Ignored// No Accumulation Buffer// 16Bit Z-Buffer (Depth Buffer)// No Stencil Buffer// No Auxiliary Buffer// Main Drawing Layer// Reserved// Layer Masks Ignored// Color Bits Ignored0, 0, 0, 0,16,0,0,0,// Accumulation Bits IgnoredPFD_MAIN_PLANE,0, 0, 0// Did We Get A Device Context?// Reset The Display// Return FALSEMessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);if (!InitGL()){KillGLWindow();return FALSE;// Reset The Display// Return FALSEMessageBox(NULL,"InitializationFailed.","ERROR",MB_OK|MB_ICONEXCLAMATION);// Initialize Our Newly Created GL Windowreset_model();ShowWindow(hWnd,SW_SHOW);SetForegroundWindow(hWnd);SetFocus(hWnd);ReSizeGLScene(width, height);// Show The Window// Slightly Higher Priority// Sets Keyboard Focus To TheWindowif(!wglMakeCurrent(hDC,hRC)){}KillGLWindow();// Reset The DisplayThe// Return FALSEGLRenderingMessageBox(NULL,"Can'treturn FALSE;Activate// Try To Activate The Rendering Contextif(!(hRC=wglCreateContext(hDC))){}KillGLWindow();// Reset The DisplayA// Return FALSEGLRenderingMessageBox(NULL,"Can'treturn FALSE;Create// Are We Able To Get A RenderingContext?if(!SetPixelFormat(hDC,PixelFormat,&pfd)){}KillGLWindow();return FALSE;// Reset The Display// Return FALSEMessageBox(NULL,"Can't Set ThePixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);// Are We Able To Set The Pixel Format?if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))// Did Windows Find A Matching Pixel Format?{}KillGLWindow();return FALSE;// Reset The Display// Return FALSEMessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);Context.","ERROR",MB_OK |MB_ICONEXCLAMATION);Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);// Set Up Our Perspective GL Screen}}return TRUE;// Successstatic int iii=0;LRESULT CALLBACK WndProc(HWNDhWnd,// Handle For This Window// Message For This Window// Additional Message InformationUINT uMsg,WPARAMwParam,LPARAMlParam){switch (uMsg){case WM_ACTIVATE:{if (!HIWORD(wParam)){active=TRUE;}else{active=FALSE;}return 0;}caseWM_SYSCOMMAND:{switch (wParam){case SC_SCREENSAVE:case SC_MONITORPOWER:return 0;}break;}case WM_CLOSE:{PostQuitMessage(0);return 0;}case WM_KEYDOWN:// Additional Message Information// Check For Windows Messages// Watch For Window Activate Message// Check Minimization State// Program Is Active// Program Is No Longer Active// Return To The Message Loop// Intercept System Commands// Check System Calls// Screensaver Trying To Start?// Monitor Trying To Enter Powersave?// Prevent From Happening// Exit// Did We Receive A Close Message?// Send A Quit Message// Jump Back// Is A Key Being Held Down?}}{}case WM_KEYUP:{}case WM_SIZE:{}case WM_TIMER:{}if(rotAngle != 0){}if(rotZ)Rotate_ZM();if(rotY)Rotate_YM();if(rotX)Rotate_XM();ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));// LoWord=Width, HiWord=Heightreturn 0;// Jump Back// Resize The OpenGL Windowkeys[wParam] = FALSE;return 0;// If So, Mark It As FALSE// Jump Back// Has A Key Been Released?keys[wParam] = TRUE;return 0;// If So, Mark It As TRUE// Jump Back// Pass All Unhandled Messages To DefWindowProcreturn DefWindowProc(hWnd,uMsg,wParam,lParam);VOID CALLBACK TimerProc(HWND hwnd,// handle of window for timer messagesUINT uMsg,// WM_TIMER messageUINT idEvent,// timer identifier{DWORD dwTime// current system time)if( idEvent==2){}}VOID CALLBACK CubeWalk({if( idEvent==3){/*int i = RX*100;if( i==560)Vx = -0."02;Vx =0."02;else if( i==-560)HWND hwnd,// handle of window for timer messagesUINT uMsg,// WM_TIMER messageUINT idEvent,// timer identifierDWORD dwTime// current system time)else if( r%6==2)else if( r%6==4)else if( r%6==5)enable_Z_roate(-1);enable_Y_roate(-1);enable_Z_roate(1);enable_X_roate(-1);else if( r%6==3)else if( r%6==1)enable_Y_roate(1);if( r%6==0)enable_X_roate(1);srand(dwTime);intr = rand();}}// Instance// Previous Instance// Command Line Parameters // Window Show StateRX += Vx;*/int WINAPI WinMain(HINSTANCEhInstance,{MSGmsg;LPSTRintHINSTANCEhPrevInstance,lpCmdLine,nCmdShow)// Windows Message Structure// Bool Variable To Exit LoopBOOLdone=FALSE;// Ask The User Which Screen Mode They Prefer(MessageBox(NULL,"WouldYouLikeToRunInFullscreenMode?","Startif{}FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO)fullscreen=FALSE;// Windowed Mode// Create Our OpenGL Windowif (!CreateGLWindow("3D MagicCube-杨文涛",1280,768,16,fullscreen)){}::SetTimer(hWnd,1,10,NULL);::SetTimer(hWnd,2,1500,Ti merProc);::SetTimer(hWnd,3,10,CubeWalk);while(!done){if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)){if(msg.message==WM_QUIT){}else{TranslateMessage(&msg);DispatchMessage(&msg);// Translate The Message// Dispatch The Message// If Not, Deal With Window Messagesdone=TRUE;// If So done=TRUE// Have We Received A Quit Message?// Is There A Message Waiting?// Loop That Runs While done=FALSEreturn 0;// Quit If Window Was Not CreatedQuit}}// If There Are No Messageselse{// Draw The Scene.Watch For ESC Key And Quit Messages From DrawGLScene()if ((active && !DrawGLScene()) || keys[VK_ESCAPE]){}else{}if (keys[VK_F1]){}if(keys[VK_LEFT]){}if(keys[VK_RIGHT]){}keys[VK_RIGHT]=FALSE;RX +=0."05f;b_RY = true;keys[VK_LEFT]=FALSE;RX -=0."05f;b_RY = true;keys[VK_F1]=FALSE;KillGLWindow();// If So Make Key FALSE// Kill Our Current Window// Is F1 Being Pressed?SwapBuffers(hDC);// Swap Buffers (Double Buffering)// Not Time To Quit, UpdateScreendone=TRUE;//ESCorDrawGLSceneSignalledA//Active?WasThereAQuitReceived ?fullscreen=!fullscreen;// Toggle Fullscreen / Windowed Mode// Recreate Our OpenGL Windowif (!CreateGLWindow("NeHe's Texture MappingTutorial",640,480,16,fullscreen)){}return 0;// Quit If Window Was Not Created}}enable_Z_roate(1);}if(keys[VK_F4]) //control Z direction{keys[VK_F4] = FALSE;}enable_Y_roate(1);if(keys[VK_F3]){keys[VK_F3] = FALSE;enable_X_roate(1);}if(keys[VK_F2]){keys[VK_F2] = FALSE;}b_RX = true;if(keys[VK_DOWN]){keys[VK_DOWN]=FALSE;RY -=0."05f;}b_RX = true;if(keys[VK_UP]){keys[VK_UP]=FALSE;RY +=0."05f;}// ShutdownKillGLWindow();// Kill The Windowreturn (msg.wParam);// Exit The Program。
opengl 立方体纹理顶点索引定义问题的开发过程。
标题:通过OpenGL绘制立方体纹理:顶点和索引定义详解导言:OpenGL是一种跨平台的图形编程接口,可用于绘制复杂的图形和对象。
在本文中,我们将重点讨论如何使用OpenGL绘制一个带有纹理的立方体。
我们将从顶点和索引的定义开始,逐步详细介绍每个步骤。
第一步:导入所需的库和资源首先,我们需要导入OpenGL库和一些必要的资源。
在C++中,我们可以使用如下方式导入头文件:#include <GL/gl.h>#include <GL/glut.h>同时,我们还需要准备一个纹理图像。
这里我们假设已经有一个名为"texture.jpg"的纹理图像。
第二步:顶点定义一个立方体有六个面,每个面有两个三角形,每个三角形有三个顶点。
因此,我们总共需要定义36个顶点。
每个顶点由三个坐标和两个纹理坐标组成。
在OpenGL中,我们可以使用GLfloat类型定义顶点坐标。
顶点坐标数据GLfloat vertices[] = {前面-0.5f, -0.5f, 0.5f, 左下0.5f, -0.5f, 0.5f, 右下-0.5f, 0.5f, 0.5f, 左上0.5f, 0.5f, 0.5f, 右上后面-0.5f, -0.5f, -0.5f, 左下0.5f, -0.5f, -0.5f, 右下-0.5f, 0.5f, -0.5f, 左上0.5f, 0.5f, -0.5f, 右上左边-0.5f, -0.5f, 0.5f, 左下-0.5f, -0.5f, -0.5f, 右下-0.5f, 0.5f, 0.5f, 左上-0.5f, 0.5f, -0.5f, 右上右边0.5f, -0.5f, 0.5f, 左下0.5f, -0.5f, -0.5f, 右下0.5f, 0.5f, 0.5f, 左上0.5f, 0.5f, -0.5f, 右上上面-0.5f, 0.5f, 0.5f, 左下0.5f, 0.5f, 0.5f, 右下-0.5f, 0.5f, -0.5f, 左上0.5f, 0.5f, -0.5f, 右上下面-0.5f, -0.5f, 0.5f, 左下0.5f, -0.5f, 0.5f, 右下-0.5f, -0.5f, -0.5f, 左上0.5f, -0.5f, -0.5f, 右上};第三步:纹理坐标定义除了顶点坐标,我们还需要为每个顶点定义纹理坐标。
旋转3D立方体——《计算机图形学》Project2文档俞晨光0830*******复旦大学2011.12.11 1.功能说明本程序实现了一个3D立方体的屏幕投影功能,立方体的每个面用不同颜色标识,可以任意旋转观察角度。
程序运行的界面如下图:坐标系:如上图所示,空间直角坐标系的原点O在立方体中心,屏幕向右为X轴正方向,屏幕向上为Y轴正方向,垂直屏幕平面向外为Z轴正方向。
观察采用正投影,即面向Z轴正方向观察立方体在xOy平面的投影。
操作方法:利用键盘WS, AD, QE, R七个按键控制旋转立方体:W:绕X轴顺时针旋转S:绕X轴逆时针旋转A:绕Y轴顺时针旋转D:绕Y轴逆时针旋转E:绕Z轴顺时针旋转Q:绕Z轴逆时针旋转R:立方体回到初始位置2.开发与运行环境说明本项目使用C++开发,使用OpenGL的库函数(只用绘单独像素点的函数),并利用GLUT工具包显示窗口和接受键盘输入。
具体如下:操作系统:Windows XP SP3C++编译器:MinGW-5.1.6GLUT版本:glut-3.7.6IDE:Eclipse Indigo for JavaEE + CDT可执行程序位于/Release 和/Debug目录下,双击RotateCube.exe文件即可运行。
请确保动态链接库文件glut32.dll与可执行文件在同一目录下。
3.程序说明设计类图如下:绘制立方体的算法步骤:1)将立方体缩放和移位到适合屏幕显示的坐标位置2)用Z缓冲区算法,绘制立方体的每一表面:1.对该表面在xOy平面上的投影部分进行扫描转换,先利用Bresenham画线算法绘制四边形,再用种子填充法填充该四边形。
2.求出该平面的平面方程(利用平面的法向量)3.对填充完的四边形内的每一个像素,使用Z缓冲区算法进行可见面的判别,并将其写入帧缓存4.参考资料1.《Computer Graphics with OpenGL》(Third Edition)Donald Hearn, M Pauline Baker2.《计算机图形学》(第三版)孙家广等。
OpenGL总结OpenGL学习总结一.OpenGL是做什么的一种图形硬件的接口。
而不是像C和C++一样的编程语言,更像是一个运行库,提供一些预先封装的函数。
二.OpenGL的主要功能是什么建模,变换,颜色模式设置,光照和材质设置,纹理映射,位图显示和图像。
三.OpenGL的体系结构是什么最底层为图形硬件,第二层为操作系统,第三层为窗口系统,第四层为OpenGL,第五层为应用软件。
四.怎么样利用OpenGL来实现我们想要做的事情首先要明白一点,OpenGL是一个与平台无关的三维图形接口,操作系统必须提供像素格式管理和渲染环境管理。
因此要使用OpenGL来做我们想做的事情的时候,一定要先为OpenGL 搭建一个窗口环境。
在这个窗口环境中,我们才能够使用OpenGL来实现我们自己的目的。
另外要注意的是OpenGL应用的不是保留模式,而是直接模式。
即我们去操作的并非是已经封装好的一些建好的图形信息,而仅是相当于操作一个图形界面。
也就是说如果我们要画一个复杂的形体,我们要把这个形体的几何信息,包括点、线和面的一些信息包括进去,然后使用一定的方法,把这些基本的信息合起来,构成我们要创建的那个物体。
五.绘制图元能干什么此处我们当明白,OpenGL能够绘制复杂和有趣的图形,但这些图形都是由几个为数不多的基本图形元素构建而成的。
所以,能够绘制图元是我们构建一个复杂有趣图形的一个基础。
这些基本的图元,包括点、线和面。
glBegin();glEnd();六.变换能干什么当我们绘制出一个复杂或者简单图形的时候,我们要把这个图形显示到我们的电脑屏幕上。
这个时候我们可能会需要用到变换,变换的目的是让我们能够从一个合适的角度,观察到我们对图形中所关注的那部分。
变换包括,视图变换,模型变换,投影变换。
经过这几个变换中的一个变换、几个变换或者几种变换的相互组合,我们可以得到我们想要达到的效果。
七.光照能干什么我们绘制图形的时候要深切地知道一个事情。
⼏个opengl⽴⽅体绘制案例⼀ OpenGL 绘制⼀个⽴⽅体代码#include<GL/glut.h>// 绘制⽴⽅体// 将⽴⽅体的⼋个顶点保存到⼀个数组⾥⾯static const float vertex_list[][3] ={-0.5f, -0.5f, -0.5f,0.5f, -0.5f, -0.5f,-0.5f, 0.5f, -0.5f,0.5f, 0.5f, -0.5f,-0.5f, -0.5f, 0.5f,0.5f, -0.5f, 0.5f,-0.5f, 0.5f, 0.5f,0.5f, 0.5f, 0.5f,};// 将要使⽤的顶点的序号保存到⼀个数组⾥⾯static const GLint index_list[][2] ={{0, 1},{2, 3},{4, 5},{6, 7},{0, 2},{1, 3},{4, 6},{5, 7},{0, 4},{1, 5},{7, 3},{2, 6}};// 绘制⽴⽅体void DrawCube(void){int i,j;glBegin(GL_LINES);for(i=0; i<12; ++i) // 12 条线段{for(j=0; j<2; ++j) // 每条线段 2个顶点{glVertex3fv(vertex_list[index_list[i][j]]);}}glEnd();}static float rotate = 0;static int times = 0;void renderScene(void){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glMatrixMode(GL_MODELVIEW);glLoadIdentity();glPushMatrix();//glTranslatef(-0.2, 0, 0); // 平移//glScalef(2, 1, 1); // 缩放times++;if(times > 100){times = 0;}if(times % 100 == 0){rotate += 0.3;}glRotatef(rotate, 0, 1, 0);glRotatef(rotate, 1, 0, 0);glColor3f(0, 0, 1);DrawCube();glPopMatrix();glutSwapBuffers();}void main(int argc, char **argv){glutInit(&argc, argv);glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);glutInitWindowPosition(100,100);glutInitWindowSize(500, 500);glutCreateWindow("GLDemo");glutDisplayFunc(renderScene);glutIdleFunc(renderScene);glutMainLoop();}效果。
Android OpenGL ES 案例总结3D旋转立方体彩色立方体package com.spl.canvasdemo31.renderer;import android.opengl.GLSurfaceView.Renderer;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.IntBuffer;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;/*** Cube渲染器类* @author spl**/public class CubeRenderer implements Renderer {public class MyCube {private IntBuffer vertexBuffer;private IntBuffer colorBuffer;private ByteBuffer indexBuffer;public MyCube(){int one = 65535;//每个顶点的坐标值(x,y,z)int vertex[] = {-one, -one, -one,one, -one, -one,one, one, -one,-one, one, -one,-one, -one, one,one, -one, one,one, one, one,-one, one, one};//立方体每个顶点的颜色值,格式为RRGGBBAA0, 0, 0, one,one, 0, 0, one,one, one, 0, one,0, one, 0, one,0, 0, one, one,one, 0, one, one,one, one, one, one,0, one, one, one};//三角形顶点绘制顺序byte index[] = {0, 4, 5, 0, 5, 1,1, 5, 6, 1, 6, 2,2, 6, 7, 2, 7, 3,3, 7, 4, 3, 4, 0,4, 7, 6, 4, 6, 5,3, 0, 1, 3, 1, 2};ByteBuffer vbb = ByteBuffer.allocateDirect(vertex.length*4);vbb.order(ByteOrder.nativeOrder());vertexBuffer = vbb.asIntBuffer();vertexBuffer.put(vertex);vertexBuffer.position(0);ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);cbb.order(ByteOrder.nativeOrder());colorBuffer = cbb.asIntBuffer();colorBuffer.put(colors);colorBuffer.position(0);indexBuffer = ByteBuffer.allocateDirect(index.length);indexBuffer.put(index);indexBuffer.position(0);}public void draw(GL10 gl){gl.glFrontFace(GL10.GL_CW);gl.glV ertexPointer(3, GL10.GL_FIXED, 0, vertexBuffer);gl.glColorPointer(4, GL10.GL_FIXED, 0, colorBuffer);gl.glDrawElements(GL10.GL_TRIANGLES, 36, GL10.GL_UNSIGNED_BYTE, indexBuffer);}}private MyCube myCube;private float roate;public CubeRenderer() {myCube = new MyCube();}public void onDrawFrame(GL10 gl) {// 填充屏幕gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);// 设置模型视景矩阵为当前操作矩阵gl.glMatrixMode(GL10.GL_MODELVIEW);// 将坐标原点移动到屏幕中心gl.glLoadIdentity();// 移动坐标系gl.glTranslatef(0, 0, -6.0f);// 在Y轴方向旋转坐标系gl.glRotatef(roate, 0, 1, 0);// 在X轴方向旋转坐标系gl.glRotatef(roate * 0.25f, 1, 0, 0);gl.glRotatef(roate, 0, 0, 1);/////////////////////////////////////gl.glScalef(1.2f, 1.2f, 1.2f);//**********大小///////////////////////////////////// 开启顶点坐标gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);// 开启颜色gl.glEnableClientState(GL10.GL_COLOR_ARRAY);myCube.draw(gl);roate += 0.3f;//********设置旋转角度的增量}public void onSurfaceChanged(GL10 gl, int width, int height) {gl.glViewport(0, 0, width, height);float ratio = (float) width / height;gl.glMatrixMode(GL10.GL_PROJECTION);gl.glLoadIdentity();gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);}public void onSurfaceCreated(GL10 gl, EGLConfig config) {gl.glEnable(GL10.GL_CULL_FACE);gl.glClearColor(0.5F, 0.5F, 0.5F, 1.0F);}}纯色立方体package com.spl.canvasdemo31.renderer;import android.opengl.GLSurfaceView.Renderer;import android.opengl.GLU;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10;/*** 立方体(纯色)*/public class OpenGL3DRenderer implements Renderer { FloatBuffer _mCubeVertexBuffer;//立方体顶点坐标private float box[] = {// FRONT-0.5f, -0.5f, 0.5f,0.5f, -0.5f, 0.5f,-0.5f, 0.5f, 0.5f,0.5f, 0.5f, 0.5f,// BACK-0.5f, -0.5f, -0.5f,-0.5f, 0.5f, -0.5f,0.5f, -0.5f, -0.5f,0.5f, 0.5f, -0.5f,// LEFT-0.5f, -0.5f, 0.5f,-0.5f, 0.5f, 0.5f,-0.5f, -0.5f, -0.5f,-0.5f, 0.5f, -0.5f,// RIGHT0.5f, -0.5f, -0.5f,0.5f, 0.5f, -0.5f,0.5f, -0.5f, 0.5f,0.5f, 0.5f, 0.5f,// TOP-0.5f, 0.5f, 0.5f,0.5f, 0.5f, 0.5f,-0.5f, 0.5f, -0.5f,0.5f, 0.5f, -0.5f,// BOTTOM-0.5f, -0.5f, 0.5f,-0.5f, -0.5f, -0.5f,0.5f, -0.5f, 0.5f,0.5f, -0.5f, -0.5f};private float rotx;private float roty;private float rotz;public void onDrawFrame(GL10 gl) {//清除屏幕gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);//重置模型矩阵gl.glLoadIdentity();/***************这里设置颜色*********************/gl.glColor4f(1f, 0f, 0f, 1f);//纯色的**************** //开启顶点坐标功能gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _mCubeVertexBuffer);//保存matrix当前状态gl.glPushMatrix();//向屏幕移入5个单位gl.glTranslatef(0.0f, 0.0f, -5.0f);//设置旋转轴,以x轴旋转gl.glRotatef(rotx, 1, 0, 0);//设置旋转轴,以y轴旋转gl.glRotatef(roty, 0, 1, 0);//设置旋转轴,以z轴旋转gl.glRotatef(rotz, 0, 0, 1);//绘制第一个立方体面gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);//绘制第二个立方体面gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 4, 4);//绘制第三个立方体面gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 8, 4);//绘制第四个立方体面gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 12, 4);//绘制第五个立方体面gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 16, 4);//绘制第六个立方体面gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 20, 4);//将matrix回复成上面push时的 matrixgl.glPopMatrix();//关闭设置顶点功能gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);//使旋转角度不断变化rotx+=0.2f;roty+=0.3f;rotz+=0.4f;}public void onSurfaceChanged(GL10 gl, int width, int height) { //设置场景大小gl.glViewport(0, 0, width, height);//设置投影矩阵gl.glMatrixMode(GL10.GL_PROJECTION);//重置模型矩阵gl.glLoadIdentity();//设置窗口比例和透视图GLU.gluPerspective(gl, 45.0f, (float)width/(float)height, 0.1f, 100.0f);//设置模型矩阵gl.glMatrixMode(GL10.GL_MODELVIEW);//重置模型矩阵}public void onSurfaceCreated(GL10 gl, EGLConfig config) { //将顶点坐标转换为native类型的数据_mCubeVertexBuffer=createFloatBuffer(box);//平滑着色gl.glShadeModel(GL10.GL_SMOOTH);//设置黑色背景gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);//设置深度缓存gl.glClearDepthf(1.0f);//启动深度测试gl.glEnable(GL10.GL_DEPTH_TEST);//深度测试的类型gl.glDepthFunc(GL10.GL_LEQUAL);//告诉系统对透视进行修正gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);}//转换为Native类型的浮点缓存public static FloatBuffer createFloatBuffer(float data[]){ByteBuffer vbb=ByteBuffer.allocateDirect(data.length*4);vbb.order(ByteOrder.nativeOrder());FloatBuffer outBuffer=vbb.asFloatBuffer();outBuffer.put(data).position(0);return outBuffer;}}贴图立方体package com.spl.canvasdemo31.renderer;import android.content.Context;import android.graphics.Bitmap;import android.opengl.GLSurfaceView.Renderer;import android.opengl.GLU;import android.opengl.GLUtils;import com.spl.canvasdemo31.R;import com.spl.canvasdemo31.util.Utility;import java.nio.FloatBuffer;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;/*** 立方体(贴图)*/public class OpenGL3DRendererTex implements Renderer {FloatBuffer _mCubeTexBuffer;Context _context;public OpenGL3DRendererTex(Context context) {_context=context;}//立方体顶点坐标private float box[] = {// FRONT-0.5f, -0.5f, 0.5f,0.5f, -0.5f, 0.5f,-0.5f, 0.5f, 0.5f,0.5f, 0.5f, 0.5f,// BACK-0.5f, -0.5f, -0.5f,-0.5f, 0.5f, -0.5f,0.5f, -0.5f, -0.5f,0.5f, 0.5f, -0.5f,// LEFT-0.5f, -0.5f, 0.5f,-0.5f, 0.5f, 0.5f,-0.5f, -0.5f, -0.5f,-0.5f, 0.5f, -0.5f,// RIGHT0.5f, -0.5f, -0.5f,0.5f, 0.5f, -0.5f,0.5f, -0.5f, 0.5f,0.5f, 0.5f, 0.5f,// TOP-0.5f, 0.5f, 0.5f,0.5f, 0.5f, 0.5f,-0.5f, 0.5f, -0.5f,0.5f, 0.5f, -0.5f,// BOTTOM-0.5f, -0.5f, 0.5f,-0.5f, -0.5f, -0.5f,0.5f, -0.5f, 0.5f,0.5f, -0.5f, -0.5f};//立方体纹理坐标private float texCoords[] = {// FRONT0.0f, 0.0f,1.0f, 0.0f,0.0f, 1.0f,// BACK1.0f, 0.0f,1.0f, 1.0f,0.0f, 0.0f,0.0f, 1.0f,// LEFT1.0f, 0.0f,1.0f, 1.0f,0.0f, 0.0f,0.0f, 1.0f,// RIGHT1.0f, 0.0f,1.0f, 1.0f,0.0f, 0.0f,0.0f, 1.0f,// TOP0.0f, 0.0f,1.0f, 0.0f,0.0f, 1.0f,1.0f, 1.0f,// BOTTOM1.0f, 0.0f,1.0f, 1.0f,0.0f, 0.0f,0.0f, 1.0f};private float rotx;private float roty;private float rotz;public void onDrawFrame(GL10 gl) {// TODO Auto-generated method stub//清除屏幕gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT); //重置模型矩阵gl.glLoadIdentity();//开启顶点坐标功能gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);//设置顶点坐标gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _mCubeVertexBuffer);gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, _mCubeTexBuffer);//保存matrix当前状态gl.glPushMatrix();//向屏幕移入5个单位gl.glTranslatef(0.0f, 0.0f, -5.0f);//设置旋转轴,以x轴旋转gl.glRotatef(rotx, 1, 0, 0);//设置旋转轴,以y轴旋转gl.glRotatef(roty, 0, 1, 0);//设置旋转轴,以z轴旋转gl.glRotatef(rotz, 0, 0, 1);/***************************************/float fscale = 1.0f;gl.glScalef(fscale, fscale, fscale);//大小//----------------------------------------////绘制第一个立方体面gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);//绘制第二个立方体面gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 4, 4);//绘制第三个立方体面gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 8, 4);//绘制第四个立方体面gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 12, 4);//绘制第五个立方体面gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 16, 4);//绘制第六个立方体面gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 20, 4);//将matrix回复成上面push时的 matrixgl.glPopMatrix();//关闭设置顶点功能gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);//使旋转角度不断变化rotx+=0.2f;roty+=0.3f;rotz+=0.4f;}public void onSurfaceChanged(GL10 gl, int width, int height) {// TODO Auto-generated method stub//设置场景大小gl.glViewport(0, 0, width, height);//设置投影矩阵gl.glMatrixMode(GL10.GL_PROJECTION);//重置模型矩阵gl.glLoadIdentity();//设置窗口比例和透视图GLU.gluPerspective(gl, 45.0f, (float)width/(float)height, 0.1f, 100.0f); //设置模型矩阵gl.glMatrixMode(GL10.GL_MODELVIEW);//重置模型矩阵gl.glLoadIdentity();}public void onSurfaceCreated(GL10 gl, EGLConfig config) {// TODO Auto-generated method stub//将顶点坐标转换为native类型的数据_mCubeVertexBuffer= Utility.createFloatBuffer(box);_mCubeTexBuffer=Utility.createFloatBuffer(texCoords);//开启纹理功能gl.glEnable(GL10.GL_TEXTURE_2D);//加载纹理 ********************************************loadBitmapTex(gl, R.raw.ic_bird);//平滑着色gl.glShadeModel(GL10.GL_SMOOTH);//设置黑色背景gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);//设置深度缓存gl.glClearDepthf(1.0f);//启动深度测试gl.glEnable(GL10.GL_DEPTH_TEST);//深度测试的类型gl.glDepthFunc(GL10.GL_LEQUAL);//告诉系统对透视进行修正gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);}private void loadBitmapTex(GL10 gl,int res){//将图片资源转换为位图资源Bitmap bmp=Utility.getTextureFromBitmapResource(_context, res);//定义1个长度的数组int mTextureID []=new int[1];//将纹理号保存到mTextureIDgl.glGenTextures(1, mTextureID,0);//绑定纹理号到纹理目标gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID[0]);//创建纹理GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);//设定纹理过滤器gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST); bmp.recycle();return;}}MainActivitypublic class MainActivity extends Activity {GLSurfaceView glview;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 全屏显示requestWindowFeature(Window.FEATURE_NO_TITLE);getWindow().setFlags(youtParams.FLAG_FULLSCREEN,youtParams.FLAG_FULLSCREEN);getWindow().setFlags(youtParams.FLAG_KEEP_SCREEN_ON,youtParams.FLAG_KEEP_SCREEN_ON);//setContentView(new MySurfaceView(this));glview = new GLSurfaceView(this);int index = getIntent().getIntExtra("index",0);// 这里可以加载不同的renderer对象if(index == 0) {glview.setRenderer(new OpenGlRender2(null));}if(index == 1) {glview.setRenderer(new SimpleRenderer());}if(index == 2) {glview.setRenderer(new TriangleRenderer());}if(index == 3) {glview.setRenderer(new ColoredTriangleRenderer());}if(index == 4) {glview.setRenderer(new TextedTriangleRenderer(this,glview)); }if(index == 9) {glview.setRenderer(new CubeRenderer());}if(index == 10) {glview.setRenderer(new OpenGL3DRenderer());}if(index == 11) {glview.setRenderer(new OpenGL3DRendererTex(this)); }setContentView(glview);}@Overrideprotected void onPause() {glview.onPause();super.onPause();}@Overrideprotected void onResume() {super.onResume();glview.onResume();}}渲染单一背景色package spl.example.opengldemo;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import android.opengl.GLSurfaceView.Renderer;import android.util.Log;/*** 渲染单一背景色* @author**/public class SimpleRenderer implements Renderer{@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) { // TODO 表面层创建(只有一次)Log.i("spl", "surface create");}@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) { // 表面层改变(多次)Log.i("spl", "width="+width +",height="+height);}@Overridepublic void onDrawFrame(GL10 gl) {// 表面层的绘制(每秒调用多次)gl.glClearColor(0, 1, 0, 1);// 设置清屏颜色gl.glClear(GL10.GL_COLOR_BUFFER_BIT);// 清空颜色缓冲区}}颜色渐变@Overridepublic void onDrawFrame(GL10 gl) {// 表面层的绘制(每秒调用多次)changeColor();gl.glClearColor(0, r, g, b);// 设置清屏颜色gl.glClear(GL10.GL_COLOR_BUFFER_BIT);// 清空颜色缓冲区}float r=1,g=0,b=1;private void changeColor(){if (r>1){r=0;}r += 0.01f;if (g>1){g=0;}g += 0.01f;if (b>1){b=0;}b += 0.01f;}纯色三角形package spl.gl.test;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import android.app.Activity;import android.content.Context;import android.opengl.GLSurfaceView;import android.opengl.GLSurfaceView.Renderer;import android.os.Bundle;import android.os.PowerManager;import android.os.PowerManager.WakeLock;import android.util.Log;import android.view.Window;import android.view.WindowManager;public class GLTestActivity extends Activity {/** Called when the activity is first created. */GLSurfaceView glView;long count = 0;WakeLock wakeLock;FloatBuffer vertices;// 储存3个顶点private Renderer renderer = new Renderer() {@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) {// 当创建GLSurfaceView时被调用,只调用一次.//在这个方法中执行只发生一次的动作,比如设置OpenGL环境参数或初始化OpenGL图形对象Log.i("spl", "surface created");// 在主机的堆内存中(而不是虚拟机的堆内存中)分配一段字节缓存区ByteBuffer byteBuffer = ByteBuffer.allocateDirect(3 * 2 * 4);byteBuffer.order(ByteOrder.nativeOrder());// 确保字节顺序等于CPU的字节顺序vertices = byteBuffer.asFloatBuffer();//// 将字节转化为浮点vertices.put(new float[]{140, 300,// 左下角 // 注意:这里只有x,y OpenGL会自动设置z=0340, 300,//右下角240, 500});vertices.flip();//初始化位置和长度Log.i("spl", "surfacecreated:glWiew="+glView.getWidth()+"x"+glView.getHeight());gl.glViewport(0, 0, glView.getWidth(), glView.getHeight());gl.glMatrixMode(GL10.GL_PROJECTION);// 设置投影矩阵(平行,透视)gl.glLoadIdentity();gl.glOrthof(0, glView.getWidth(), 0, glView.getHeight(), 1, -1);//设置gl.glColor4f(0, 1, 0, 1);gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);// 通知GL所有绘制的顶点都有位置(废话)//告诉GL从何处取得顶点的位置以及其他信息://2代表x,y(3代表x,y,z);每个点由两个坐标组成//GL10.GL_FLOAT告知所使用的数据类型//0 代表步长,是位置与位置之间的字节距离//vertices 是浮点缓冲区gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertices);// 把顶点位置传输到GPU并储存}@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) {// 几何体改变时系统调用此方法,比如GLSurfaceView的大小改变或设备屏幕的方向改变.//使用此方法来响应GLSurfaceView容器的变化.Log.i("spl", "surface changed: " + width + "x" + height);}@Overridepublic void onDrawFrame(GL10 gl) {// 系统在每次重绘GLSurfaceView时调用此方法.此方法是绘制图形对象的主要的执行点.//count++;//Log.i("spl", "surface draw:"+count);gl.glClearColor(1, 1, 1, 1);// 清空像素的帧缓冲区gl.glClear(GL10.GL_COLOR_BUFFER_BIT);//GL10.GL_TRIANGLES 绘制类型//0 代表顶点偏移量, 也就是从第一个顶点开始画起//3 顶点数量gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);// 它将绘制三角形 // 必须}};// 渲染者@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);getWindow().setFlags(youtParams.FLAG_FULLSCREEN,youtParams.FLAG_FULLSCREEN);glView = new GLSurfaceView(this);glView.setRenderer(renderer);setContentView(glView);// 打开屏幕锁PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "GLTestActivity"); }@Overrideprotected void onResume() {// TODO Auto-generated method stubsuper.onResume();glView.onResume();wakeLock.acquire();Log.i("spl", "onResume");}@Overrideprotected void onPause() {// TODO Auto-generated method stubwakeLock.release();glView.onPause();super.onPause();Log.i("spl", "onPause");}}彩色三角形package spl.gl.test;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import android.app.Activity;import android.content.Context;import android.opengl.GLSurfaceView;import android.opengl.GLSurfaceView.Renderer;import android.os.Bundle;import android.os.PowerManager;import android.os.PowerManager.WakeLock;import android.util.Log;import android.view.Window;import android.view.WindowManager;public class GLTestActivity extends Activity {/** Called when the activity is first created. */GLSurfaceView glView;long count = 0;WakeLock wakeLock;FloatBuffer vertices;// 储存3个顶点private Renderer renderer = new Renderer() {final int VERTEX_SIZE = (2 + 4) * 4;@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) {// 当创建GLSurfaceView时被调用,只调用一次.//在这个方法中执行只发生一次的动作,比如设置OpenGL环境参数或初始化OpenGL图形对象Log.i("spl", "surface created");// 在主机的堆内存中(而不是虚拟机的堆内存中)分配一段字节缓存区ByteBuffer byteBuffer = ByteBuffer.allocateDirect(3 * VERTEX_SIZE);byteBuffer.order(ByteOrder.nativeOrder());// 确保字节顺序等于CPU的字节顺序vertices = byteBuffer.asFloatBuffer();//// 将字节转化为浮点vertices.put(new float[]{140, 300,1, 0, 0, 1,//添加颜色信息// 左下角 // 注意:这里只有x,y OpenGL会自动设置z=0340, 300,0, 1, 0, 1,//右下角240, 500,0, 0, 1, 1});vertices.flip();//初始化位置和长度Log.i("spl", "surfacecreated:glWiew="+glView.getWidth()+"x"+glView.getHeight());gl.glViewport(0, 0, glView.getWidth(), glView.getHeight());gl.glMatrixMode(GL10.GL_PROJECTION);// 设置投影矩阵(平行,透视)gl.glLoadIdentity();gl.glOrthof(0, glView.getWidth(), 0, glView.getHeight(), 1, -1);//设置gl.glColor4f(0, 1, 0, 1);// 默认颜色gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);// 通知GL所有绘制的顶点都有位置(废话)gl.glEnableClientState(GL10.GL_COLOR_ARRAY);// 告知GL 顶点包含颜色信息, 取代默认色//gl.glDisableClientState(GL10.GL_COLOR_ARRAY);// 关闭颜色vertices.position(0);gl.glVertexPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices);// 把顶点位置传输到GPU 并储存vertices.position(2);gl.glColorPointer(4, GL10.GL_FLOAT, VERTEX_SIZE, vertices);// 告知GL颜色在缓冲区的位置//告诉GL从何处取得顶点的位置以及其他信息://2代表x,y(3代表x,y,z);每个点由两个坐标组成//GL10.GL_FLOAT告知所使用的数据类型//0 代表步长,是位置与位置之间的字节距离//vertices 是浮点缓冲区//gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertices);// 把顶点位置传输到GPU并储存}@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) {// 几何体改变时系统调用此方法,比如GLSurfaceView的大小改变或设备屏幕的方向改变.//使用此方法来响应GLSurfaceView容器的变化.Log.i("spl", "surface changed: " + width + "x" + height);}@Overridepublic void onDrawFrame(GL10 gl) {// 系统在每次重绘GLSurfaceView时调用此方法.此方法是绘制图形对象的主要的执行点.//count++;//Log.i("spl", "surface draw:"+count);gl.glClearColor(1, 1, 1, 1);// 清空像素的帧缓冲区gl.glClear(GL10.GL_COLOR_BUFFER_BIT);//GL10.GL_TRIANGLES 绘制类型//0 代表顶点偏移量, 也就是从第一个顶点开始画起//3 顶点数量gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);// 它将绘制三角形 // 必须}};// 渲染者@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);getWindow().setFlags(youtParams.FLAG_FULLSCREEN,youtParams.FLAG_FULLSCREEN);glView = new GLSurfaceView(this);glView.setRenderer(renderer);setContentView(glView);// 打开屏幕锁PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "GLTestActivity"); }@Overrideprotected void onResume() {// TODO Auto-generated method stubsuper.onResume();glView.onResume();wakeLock.acquire();Log.i("spl", "onResume");}@Overrideprotected void onPause() {// TODO Auto-generated method stubwakeLock.release();glView.onPause();super.onPause();Log.i("spl", "onPause");}}对三角形加载纹理(贴图)package spl.gl.test;import java.io.IOException;import java.io.InputStream;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10;import android.app.Activity;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.opengl.GLSurfaceView;import android.opengl.GLUtils;import android.opengl.GLSurfaceView.Renderer;import android.os.Bundle;import android.os.PowerManager;import android.os.PowerManager.WakeLock;import android.util.Log;import android.view.Window;import android.view.WindowManager;public class GLTestActivity extends Activity { /** Called when the activity is first created. */ GLSurfaceView glView;long count = 0;WakeLock wakeLock;FloatBuffer vertices;// 储存3个顶点public Bitmap getBitmap(String path){Bitmap bitmap = null;InputStream is = null;try {is = getAssets().open(path);bitmap = BitmapFactory.decodeStream(is);} catch (Exception e) {// TODO: handle exception}finally{if (is != null) {try {is.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}return bitmap;}private Renderer renderer = new Renderer() {final int VERTEX_SIZE = (2 + 2) * 4;int textureId ;@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) {// 当创建GLSurfaceView时被调用,只调用一次.//在这个方法中执行只发生一次的动作,比如设置OpenGL环境参数或初始化OpenGL图形对象Log.i("spl", "surface created");// 在主机的堆内存中(而不是虚拟机的堆内存中)分配一段字节缓存区ByteBuffer byteBuffer = ByteBuffer.allocateDirect(3 * VERTEX_SIZE);byteBuffer.order(ByteOrder.nativeOrder());// 确保字节顺序等于CPU的字节顺序vertices = byteBuffer.asFloatBuffer();//// 将字节转化为浮点vertices.put(new float[]{140, 300, 0.0f, 1.0f,//添加颜色信息// 左下角 // 注意:这里只有x,y OpenGL会自动设置z=0340, 300, 1.0f, 1.0f,//右下角240, 500, 0.5f, 0.0f});vertices.flip();//初始化位置和长度Log.i("spl", "surfacecreated:glWiew="+glView.getWidth()+"x"+glView.getHeight());gl.glViewport(0, 0, glView.getWidth(), glView.getHeight());gl.glMatrixMode(GL10.GL_PROJECTION);// 设置投影矩阵(平行,透视)gl.glLoadIdentity();gl.glOrthof(0, glView.getWidth(), 0, glView.getHeight(), 1, -1);//设置剪裁空间(正交矩形)textureId = loadTexture(gl, "desktop.png");gl.glEnable(GL10.GL_TEXTURE_2D);// 启用纹理gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);// 绑定纹理//gl.glColor4f(0, 1, 0, 1);// 默认颜色gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);// 通知GL所有绘制的顶点都有位置(废话)gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);// 告知GL 顶点包含纹理坐标信息, 取代默认色//gl.glDisableClientState(GL10.GL_COLOR_ARRAY);// 关闭颜色vertices.position(0);gl.glVertexPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices);// 把顶点位置传输到GPU 并储存vertices.position(2);gl.glTexCoordPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices);// 告知GL纹理坐标在缓冲区的位置//告诉GL从何处取得顶点的位置以及其他信息://2代表x,y(3代表x,y,z);每个点由两个坐标组成//GL10.GL_FLOAT告知所使用的数据类型//0 代表步长,是位置与位置之间的字节距离//vertices 是浮点缓冲区//gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertices);// 把顶点位置传输到GPU并储存}public int loadTexture(GL10 gl,String path){Bitmap bitmap = getBitmap(path);// 创建纹理对象int textureIds[] = new int[1];gl.glGenTextures(1, textureIds, 0);// 参数1:要创建多少纹理对象;参数2:纹理id在其中;保存id的起始点int textureId = textureIds[0];// 无法返回java对象,所以返回id// 纹理上传gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId); // 绑定纹理对象// 参数1:文理类型//参数2:多纹理映射层次// 参数3:位图// 参数4:永远是0GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);// 上传纹理图片(android框架)// 设置过滤类型,(需要放大和缩小)//GL_NEAREST是一种过滤器类型,他和GL_LINEAR的区别是不做平滑过渡gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);// 取消绑定,释放资源,节省内存gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);bitmap.recycle();return textureId;}@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) {// 几何体改变时系统调用此方法,比如GLSurfaceView的大小改变或设备屏幕的方向改变.//使用此方法来响应GLSurfaceView容器的变化.Log.i("spl", "surface changed: " + width + "x" + height);}@Overridepublic void onDrawFrame(GL10 gl) {// 系统在每次重绘GLSurfaceView时调用此方法.此方法是绘制图形对象的主要的执行点.//count++;//Log.i("spl", "surface draw:"+count);gl.glClearColor(1, 1, 1, 1);// 清空像素的帧缓冲区gl.glClear(GL10.GL_COLOR_BUFFER_BIT);//GL10.GL_TRIANGLES 绘制类型//0 代表顶点偏移量, 也就是从第一个顶点开始画起//3 顶点数量gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);// 它将绘制三角形 // 必须}};// 渲染者@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);getWindow().setFlags(youtParams.FLAG_FULLSCREEN,youtParams.FLAG_FULLSCREEN);glView = new GLSurfaceView(this);glView.setRenderer(renderer);setContentView(glView);// 打开屏幕锁PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "GLTestActivity"); }@Overrideprotected void onResume() {// TODO Auto-generated method stubsuper.onResume();glView.onResume();wakeLock.acquire();Log.i("spl", "onResume");}@Overrideprotected void onPause() {// TODO Auto-generated method stubwakeLock.release();glView.onPause();super.onPause();Log.i("spl", "onPause");}}绘制两个纹理三角形package spl.gl.test;import java.io.IOException;import java.io.InputStream;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import java.nio.ShortBuffer;import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10;import android.app.Activity;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.opengl.GLSurfaceView;import android.opengl.GLUtils;import android.opengl.GLSurfaceView.Renderer;import android.os.Bundle;import android.os.PowerManager;import android.os.PowerManager.WakeLock;import android.util.Log;import android.view.Window;import android.view.WindowManager;public class GLTestActivity extends Activity { /** Called when the activity is first created. */ GLSurfaceView glView;long count = 0;WakeLock wakeLock;public Bitmap getBitmap(String path){Bitmap bitmap = null;InputStream is = null;try {is = getAssets().open(path);bitmap = BitmapFactory.decodeStream(is);} catch (Exception e) {// TODO: handle exception}finally{if (is != null) {try {is.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();。
opengl学习手记(三) 旋转的三维立方体
注意:
1. 在onInit函数中加入了,开启深度测试的代码。
2. glClear清屏的时候多个参数GL_DEPTH_BUFFER_BIT,因为开启了深度测试,
所以要清除深度缓存。
尝试:
1. 你可以先注释onInit函数中的代码,并且不使用GL_DEPTH_BUFFER_BIT看下
效果。
2. 再试下,启用onInit函数中的代码,但不使用GL_DEPTH_BUFFER_BIT看下效
果。
说明:
使用左右方向键,可以旋转立方体。
// 包含windows的头文件
#include
// 包含opengl需要用到的头文件(完整的vs编辑器中会自带这些文件)
#include
#include
#include
// 设置链接时的库文件
#pragma comment(lib, "OPENGL32.LIB")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "glaux.lib")
// 所有的初始化都放这个函数
bool onInit()
{
glClearDepth(1.0f); // 设置深度缓存
glEnable(GL_DEPTH_TEST); // 启用深度测试
return true;
}
// 当窗口大小改变时的处理函数
void CALLBACK onSize(GLint w, GLint h)
{
// 防止h为0时,后面计算w/h时出现除法错误
if (h == 0) h = 1;
// 指定视口的位置和大小(可以自己改下参数看下效果)
glViewport(0, 0, w, h);
// 切换当前矩阵到投影矩阵
glMatrixMode(GL_PROJECTION);
// 设置投影矩阵为一个单位矩阵
glLoadIdentity();
// 设置45度角的投影矩阵,aspect一般都是设置成宽/高(是视景体的宽
高比)
gluPerspective(45.0, (GLdouble)w/(GLdouble)h, 1.0, 100.0);
// 切换当前矩形到模型视景矩阵
glMatrixMode(GL_MODELVIEW);
// 设置模型视景矩阵为一个单位矩阵
glLoadIdentity();
}
// 渲染一个立方体
void DrawBox()
{
glBegin(GL_QUADS);
// 前面
glColor3f(1,0,0);
glVertex3f(-1.0f, -1.0f, 1.0f); // 四边形的左下
glVertex3f( 1.0f, -1.0f, 1.0f); // 四边形的右下
glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的右上
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的左上
// 后面
glColor3f(0,1,0);
glVertex3f(-1.0f, -1.0f, -1.0f); // 四边形的右下
glVertex3f(-1.0f, 1.0f, -1.0f); // 四边形的右上
glVertex3f( 1.0f, 1.0f, -1.0f); // 四边形的左上
glVertex3f( 1.0f, -1.0f, -1.0f); // 四边形的左下
// 顶面
glColor3f(0,0,1);
glVertex3f(-1.0f, 1.0f, -1.0f); // 四边形的左上
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的左下
glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的右下
glVertex3f( 1.0f, 1.0f, -1.0f); // 四边形的右上
// 底面
glColor3f(1,1,0);
glVertex3f(-1.0f, -1.0f, -1.0f); // 四边形的右上
glVertex3f( 1.0f, -1.0f, -1.0f); // 四边形的左上
glVertex3f( 1.0f, -1.0f, 1.0f); // 四边形的左下
glVertex3f(-1.0f, -1.0f, 1.0f); // 四边形的右下
// 右面
glColor3f(0,1,1);
glVertex3f( 1.0f, -1.0f, -1.0f); // 四边形的右下
glVertex3f( 1.0f, 1.0f, -1.0f); // 四边形的右上
glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的左上
glVertex3f( 1.0f, -1.0f, 1.0f); // 四边形的左下
// 左面
glColor3f(1,0,1);
glVertex3f(-1.0f, -1.0f, -1.0f); // 四边形的左下
glVertex3f(-1.0f, -1.0f, 1.0f); // 四边形的右下
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的右上
glVertex3f(-1.0f, 1.0f, -1.0f); // 四边形的左上
glEnd();
}
float ratX = 60;
float ratY = 60;
float ratZ = 60;
// 这个函数是渲染循环的回调函数
void CALLBACK onRender(void)
{
// 设置清屏颜色
glClearColor(0, 0, 0, 0);
// 用glClearColor设置的颜色来清除屏幕
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0, 0, -6.0f);
// 绕x,y,z轴旋转
glRotatef(ratX, 1.0f, 0.0f, 0.0f);
glRotatef(ratY, 0.0f, 1.0f, 0.0f);
glRotatef(ratZ, 0.0f, 0.0f, 1.0f);
DrawBox();
// 渲染到后备缓冲
// 注意auxInitDisplayMode中不是AUX_AUX_SINGLE,而是AUX_DOUBLE
// 这个例子里使用了双缓冲机制,所以glFlush只渲染到后缓冲,不画到
窗口上了
// 使用双缓冲是为了解决闪屏的问题
glFlush();
// 把后缓冲中的渲染结果一次性渲染到窗口
auxSwapBuffers();
}
void CALLBACK leftKeyProc()
{
ratX += 2;
ratY += 2;
ratZ += 2;
}
void CALLBACK rightKeyProc()
{
ratX -= 2;
ratY -= 2;
ratZ -= 2;
}
void main()
{
// 调用glaux.h中的设置显示模式的接口
auxInitDisplayMode(AUX_DOUBLE|AUX_RGBA);
// 调用glaux.h中的设置窗口位置和大小
auxInitPosition(512,300,250,200);
// 调用glaux.h中的创建窗口
auxInitWindow("sample");
// 注册left键的处理函数
auxKeyFunc(AUX_LEFT, leftKeyProc);
// 注册right键的处理函数
auxKeyFunc(AUX_RIGHT, rightKeyProc);
// 注册窗口大小改变时的处理函数
auxReshapeFunc(onSize);
// 自定义初始化
onInit();
// 注册主渲染循环(注册了这个以后)
auxMainLoop(onRender);
}