OpenGL 学习笔记(一)

#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
*/




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值