您的位置:首页 > 运维架构

OpenGL 学习笔记(一)

2012-05-24 12:09 309 查看
#include <stdio.h>

#include <stdlib.h>

#include <windows.h>

#include <GL/gl.h>

#include <GL/glu.h>

#include <math.h>

const int n = 50;

const GLfloat R = 0.5f;

const GLfloat Pi = 3.1415926536f;

const GLfloat factor = 0.1f;

LONG WINAPI WndProc(HWND,UINT,WPARAM,LPARAM);//Window procedure

HGLRC SetUpOpenGL(HWND hwnd);//Initialize OpenGL

void DrawOpenGLScene(void);//Actual Drawing code

//WinMain - the main window entry point

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)

{

static char szAppName[] = "OpenGL";

static char szTitle[]="Getting Started With OpenGL";

WNDCLASS wc; // windows class sruct

MSG msg; // message struct

HWND hWnd; // Main window handle.

// Fill in window class structure with parameters that

// describe the main window.

wc.style =

CS_HREDRAW | CS_VREDRAW;// Class style(s).

wc.lpfnWndProc =

(WNDPROC)WndProc; // Window Procedure

wc.cbClsExtra = 0; // No per-class extra data.

wc.cbWndExtra = 0; // No per-window extra data.

wc.hInstance =

hInstance; // Owner of this class

wc.hIcon = NULL; // Icon name

wc.hCursor =

LoadCursor(NULL, MAKEINTRESOURCE(32649));// Cursor

wc.hbrBackground =

(HBRUSH)(COLOR_WINDOW+1);// Default color

wc.lpszMenuName = NULL; // Menu from .RC

wc.lpszClassName =

szAppName; // Name to register as

// Register the window class

RegisterClass( &wc );

// Create a main window for this application instance.

hWnd = CreateWindow(

szAppName, // app name

szTitle, // Text for window title bar

WS_OVERLAPPEDWINDOW// Window style

// NEED THESE for OpenGL calls to work!

| WS_CLIPCHILDREN | WS_CLIPSIBLINGS,

CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,

NULL, // no parent window

NULL, // Use the window class menu.

hInstance,// This instance owns this window

NULL // We don't use any extra data

);

// If window could not be created, return zero

if ( !hWnd )

{

return( 0 );

}

// Make the window visible & update its client area

ShowWindow( hWnd, 1 );// Show the window

UpdateWindow( hWnd ); // Sends WM_PAINT message

// Enter the Windows message loop

// Get and dispatch messages until WM_QUIT

while (GetMessage(&msg, // message structure

NULL, // handle of window receiving

// the message

0, // lowest message id to examine

0)) // highest message id to examine

{

TranslateMessage( &msg ); // Translates messages

DispatchMessage( &msg ); // then dispatches

}

return( msg.wParam );

}

//WndProc

LONG WINAPI WndProc( HWND hWnd, UINT msg,

WPARAM wParam, LPARAM lParam )

{

HDC hDC;

static HGLRC hRC; // Note this is STATIC!

PAINTSTRUCT ps;

GLdouble gldAspect;

GLsizei glnWidth, glnHeight;

switch(msg)

{

case WM_CREATE:

// Select a pixel format and then

// create a rendering context from it.

hRC = SetUpOpenGL(hWnd);

return 0;

case WM_SIZE:

// Redefine the viewing volume and viewport

// when the window size changes.

// Make the RC current since we're going to

// make an OpenGL call here...

hDC = GetDC(hWnd);

wglMakeCurrent(hDC,hRC);

// get the new size of the client window

// note that we size according to the height,

// not the smaller of the height or width.

glnWidth = (GLsizei) LOWORD (lParam);

glnHeight = (GLsizei) HIWORD (lParam);

gldAspect =

(GLdouble)glnWidth/(GLdouble)glnHeight;

// set up a projection matrix to fill the

// client window

glMatrixMode( GL_PROJECTION );

glLoadIdentity();

// a perspective-view matrix...

gluPerspective(

30.0, // Field-of-view angle

gldAspect, // Aspect ratio of view volume

1.0, // Distance to near clipping plane

10.0 ); // Distance to far clipping plane

glViewport( 0, 0, glnWidth, glnHeight );

wglMakeCurrent( NULL, NULL );

ReleaseDC( hWnd, hDC );

return 0;

case WM_PAINT:

// Draw the scene.

// Get a DC, then make the RC current and

// associate with this DC

hDC = BeginPaint( hWnd, &ps );

wglMakeCurrent( hDC, hRC );

DrawOpenGLScene();

// we're done with the RC, so

// deselect it

// (note: This technique is not recommended!)

wglMakeCurrent( NULL, NULL );

EndPaint( hWnd, &ps );

return 0;

case WM_DESTROY:

// Clean up and terminate.

wglDeleteContext( hRC );

PostQuitMessage( 0 );

return 0;

}

// This function handles any messages that we didn't.

// (Which is most messages) It belongs to the OS.

return DefWindowProc( hWnd, msg, wParam, lParam );

}

/////////////////////////////////////////////////////////

// SetUpOpenGL sets the pixel format and a rendering

// context then returns the RC

/////////////////////////////////////////////////////////

HGLRC SetUpOpenGL( HWND hWnd )

{

static PIXELFORMATDESCRIPTOR pfd = {

sizeof (PIXELFORMATDESCRIPTOR), // strcut size

1, // Version number

PFD_DRAW_TO_WINDOW | // Flags, draw to a window,

PFD_SUPPORT_OPENGL, // use OpenGL

PFD_TYPE_RGBA, // RGBA pixel values

24, // 24-bit color

0, 0, 0, // RGB bits & shift sizes.

0, 0, 0, // Don't care about them

0, 0, // No alpha buffer info

0, 0, 0, 0, 0, // No accumulation buffer

32, // 32-bit depth buffer

0, // No stencil buffer

0, // No auxiliary buffers

PFD_MAIN_PLANE, // Layer type

0, // Reserved (must be 0)

0, // No layer mask

0, // No visible mask

0 // No damage mask

};

int nMyPixelFormatID;

HDC hDC;

HGLRC hRC;

hDC = GetDC( hWnd );

nMyPixelFormatID = ChoosePixelFormat( hDC, &pfd );

// catch errors here.

// If nMyPixelFormat is zero, then there's

// something wrong... most likely the window's

// style bits are incorrect (in CreateWindow() )

// or OpenGl isn't installed on this machine

SetPixelFormat( hDC, nMyPixelFormatID, &pfd );

hRC = wglCreateContext( hDC );

ReleaseDC( hWnd, hDC );

return hRC;

}

//////////////////////////////////////////////////////////

// DrawScene uses OpenGL commands to draw a triangle.

// This is where the OpenGL drawing commands live

//////////////////////////////////////////////////////////

void DrawOpenGLScene( )

{

//glEnable( GL_DEPTH_TEST );

//

// Define the modelview transformation.

//

glMatrixMode( GL_MODELVIEW );

glLoadIdentity();

// move the viewpoint out to where we can see everything

glTranslatef( 0.0f, 0.0f, -5.0f );

glClear(GL_COLOR_BUFFER_BIT);

glBegin(GL_TRIANGLES);

glColor3f(1.0,0.0,0.0);//red color for the triangle

glVertex3f(0.0,0.0,0);

glVertex3f(0.0,1.0,0);

glVertex3f(1.0,0.0,0);

glColor3f(0.0,1.0,0.0);//Green color for the triangle

glVertex3f(0.0,0.0,0);

glVertex3f(0.0,1.0,0);

glVertex3f(-1.0,0.0,0);

glColor3f(0.0,0.0,1.0);//Blue color for the triangle

glVertex3f(1.0,0.0,0);

glVertex3f(0.0,-1.0,0);

glVertex3f(-1.0,0.0,0);

glEnd();

int i;

//glClear(GL_COLOR_BUFFER_BIT);

glBegin(GL_POLYGON);

for(i=0; i<n; ++i)

{

glVertex2f((GLfloat)(R*cos(2*Pi/n*i)), (GLfloat)(R*sin(2*Pi/n*i)));

glColor3f(3.0,(GLfloat)(i),0.0);

}

glEnd();

GLfloat a = (GLfloat)(1 / (2-2*cos(72*Pi/180)));

GLfloat bx = (GLfloat)(a * cos(18 * Pi/180));

GLfloat by = (GLfloat)(a * sin(18 * Pi/180));

GLfloat cy = (GLfloat)(-a * cos(18 * Pi/180));

GLfloat

PointA[2] = { 0, a },

PointB[2] = { bx, by },

PointC[2] = { 0.5, cy },

PointD[2] = { -0.5, cy },

PointE[2] = { -bx, by };

// 按照A->C->E->B->D->A的顺序,可以一笔将五角星画出

glColor3f(0.0,1.0,0.0);

glLineWidth(5.0f);

glBegin(GL_LINE_LOOP);

glVertex2fv(PointA);

glVertex2fv(PointC);

glVertex2fv(PointE);

glVertex2fv(PointB);

glVertex2fv(PointD);

glEnd();

GLfloat x;

glColor3f(255.0,3.0,1.0);

glEnable(GL_LINE_STIPPLE);

glLineStipple(2, 0x0F0F);

glLineWidth(2.0f);

glBegin(GL_LINES);

glVertex2f(-1.0f, 0.0f);

glVertex2f(1.0f, 0.0f); // 以上两个点可以画x轴

glVertex2f(0.0f, -1.0f);

glVertex2f(0.0f, 1.0f); // 以上两个点可以画y轴

glEnd();

glDisable(GL_LINE_STIPPLE);

glBegin(GL_LINE_STRIP);

for(x=-1.0f/factor; x<1.0f/factor; x+=0.01f)

{

glVertex2f((GLfloat)(x*factor), (GLfloat)(sin(x)*factor));

}

glEnd();

//正反面

glClear(GL_COLOR_BUFFER_BIT);

glPolygonMode(GL_FRONT, GL_FILL); // 设置正面为填充模式

glPolygonMode(GL_BACK, GL_LINE); // 设置反面为线形模式

glFrontFace(GL_CCW); // 设置逆时针方向为正面

//glFrontFace(GL_CW); // 设置顺时针方向为正面

glBegin(GL_POLYGON); // 按逆时针绘制一个正方形,在左下方

glVertex2f(-0.5f, -0.5f);

glVertex2f(0.0f, -0.5f);

glVertex2f(0.0f, 0.0f);

glVertex2f(-0.5f, 0.0f);

glEnd();

//glFrontFace(GL_CW); // 设置顺时针方向为正面

glColor3f(0.0,1.0,0.0);

glBegin(GL_POLYGON); // 按顺时针绘制一个正方形,在右上方

glVertex2f(0.0f, 0.0f);

glVertex2f(0.0f, 0.5f);

glVertex2f(0.5f, 0.5f);

glVertex2f(0.5f, 0.0f);

glEnd();

//镂空

static GLubyte Mask[128];

FILE *fp;

fp = fopen("mask.bmp", "rb");

if( !fp )

exit(0);

if( fseek(fp, -(int)sizeof(Mask), SEEK_END) )

exit(0);

if( !fread(Mask, sizeof(Mask), 1, fp) )

exit(0);

fclose(fp);

glClear(GL_COLOR_BUFFER_BIT);

glEnable(GL_POLYGON_STIPPLE);

glPolygonStipple(Mask);

glRectf(-0.5f, -0.5f, 0.0f, 0.0f); // 在左下方绘制一个有镂空效果的正方形

glDisable(GL_POLYGON_STIPPLE);

glRectf(0.0f, 0.0f, 0.5f, 0.5f); // 在右上方绘制一个无镂空效果的正方形

glFlush();

}

/*////////////////////////////////////////////////////////////////////////

mask.bmp文件制作

用Windows自带的画笔程序新建一副图片,取名为mask.bmp,注意保存时,应该选择“单色位图”。在“图象”->“属性”对话框中,设置图片的高度和宽度均为32。

用放大镜观察图片,并编辑之。黑色对应二进制零(镂空),白色对应二进制一(不镂空),编辑完毕后保存。

然后,就可以使用以下代码来获得这个Mask数组了。

static GLubyte Mask[128];

FILE *fp;

fp = fopen("mask.bmp", "rb");

if( !fp )

exit(0);

// 移动文件指针到这个位置,使得再读sizeof(Mask)个字节就会遇到文件结束

// 注意-(int)sizeof(Mask)虽然不是什么好的写法,但这里它确实是正确有效的

// 如果直接写-sizeof(Mask)的话,因为sizeof取得的是一个无符号数,取负号会有问题

if( fseek(fp, -(int)sizeof(Mask), SEEK_END) )

exit(0);

// 读取sizeof(Mask)个字节到Mask

if( !fread(Mask, sizeof(Mask), 1, fp) )

exit(0);

fclose(fp);

在glBegin和glEnd之间,只有以下函数是有效的,其它函数全部会被忽略。

glVertex*

glColor*

glIndex*

glSecondaryColor*

glNormal*

glMaterial*

glFogCood*

glTexCood*

glMultiTexCood*

glEdgeFlag*

glArrayElement*

glEvalCoord*

glEvalPoint*

glCallList

glCallLists

////////////////////////////////////////////////////////////////////////*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  buffer winapi distance null fp