6.在屏幕上绘制一条贝塞尔曲线和一个贝塞尔曲面

#define GLUT_DISABLE_ATEXIT_HACK

#include "windows.h"
#include <stdio.h>
#include <gl/glut.h>
#include "math.h"

/** 控制点数组 */
GLfloat points[4][3] = {
	   { -4.0f,  -2.0f,  0.0f }, { -2.0f,  3.0f,  2.0f},
	   {  2.0f,  -3.0f, -2.0f }, {  4.0f,  2.0f,  0.0f} };


GLfloat      rot=0;                                   /**< 用于旋转物体 */
GLboolean    light=false;                                 /**< 用于开启/关闭光源 */
GLboolean    lp = false;                                  /**< 判断L键是否释放 */
GLboolean    sp = false;                                      /**< 判断空格键是否释放 */

/** 绘制模式 */
GLint renderMode[] = { GL_FILL,GL_LINE };
GLuint mode = 0;  /**< 绘制模式索引 */

/** 用于输出信息 */
const char* RenderMode[] =
{
	"GL_FILL",
	"GL_LINE",
};

/** 定义光源的属性值 */
GLfloat LightAmbient[] = { 0.5f, 0.5f, 0.5f, 1.0f }; 	/**< 环境光参数 */
GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };		/**< 漫射光参数 */
GLfloat LightSpecular[] = { 1.0f, 1.0f, 1.0f, 1.0f };	/**< 镜面光参数 */
GLfloat LightPosition[] = { 0.0f, 0.0f, 2.0f, 1.0f };	/**< 光源位置 */

/** 定义材质属性值 */
GLfloat mat_diffuse[] = { 0.4, 0.5, 0.6, 1.0 };         /**< 漫射光参数 */
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };        /**< 镜面光参数 */
GLfloat mat_shinness[] = { 50.0 };                      /**< 镜面反射指数 */

/** 定义曲面的控制点 */
GLfloat ctrlpoints[4][4][3] = {
	{{ -0.8f, -0.6f, 0.8f },{ -0.2f, -0.6f, 1.6f },{  0.2f, -0.6f, -0.4f },{ 0.6f, -0.6f,  0.8f }},
	{{ -0.6f, -0.2f, 0.8f },{ -0.2f, -0.2f, 1.6f },{  0.2f, -0.2f, -0.4f },{ 0.6f, -0.2f,  0.8f }},
	{{ -0.6f,  0.2f, 0.8f },{ -0.2f, -0.2f, 0.4f },{  0.2f,  0.2f,  0.0f },{ 0.3f,  0.2f, -0.4f }},
	{{ -0.6f,  0.6f, 0.8f },{ -0.2f,  0.6f, 0.4f },{ -0.8f,  0.6f,  0.0f },{ 0.8f,  0.6f, -0.4f }}
};

GLfloat texpts[2][2][2] = { {{0.0, 0.0}, {0.0, 1.0}}, {{1.0, 0.0}, {1.0, 1.0}} };

BYTE* gltReadBMPBits(const char* szFileName, int* nWidth, int* nHeight)
{
	HANDLE hFileHandle;
	BITMAPINFO* pBitmapInfo = NULL;
	unsigned long lInfoSize = 0;
	unsigned long lBitSize = 0;
	BYTE* pBits = NULL;					// Bitmaps bits
	BITMAPFILEHEADER	bitmapHeader;
	DWORD dwBytes;

	// Open the Bitmap file
	hFileHandle = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ,
		NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);

	// Check for open failure (most likely file does not exist).
	if (hFileHandle == INVALID_HANDLE_VALUE)
		return NULL;

	// File is Open. Read in bitmap header information
	ReadFile(hFileHandle, &bitmapHeader, sizeof(BITMAPFILEHEADER),
		&dwBytes, NULL);

	// Check for a couple of simple errors	
	if (dwBytes != sizeof(BITMAPFILEHEADER))
		return FALSE;

	// Check format of bitmap file
	if (bitmapHeader.bfType != 'MB')
		return FALSE;

	// Read in bitmap information structure
	lInfoSize = bitmapHeader.bfOffBits - sizeof(BITMAPFILEHEADER);
	pBitmapInfo = (BITMAPINFO*)malloc(sizeof(BYTE) * lInfoSize);
	ReadFile(hFileHandle, pBitmapInfo, lInfoSize, &dwBytes, NULL);

	if (dwBytes != lInfoSize)
	{
		free(pBitmapInfo);
		CloseHandle(hFileHandle);
		return FALSE;
	}

	// Save the size and dimensions of the bitmap
	*nWidth = pBitmapInfo->bmiHeader.biWidth;
	*nHeight = pBitmapInfo->bmiHeader.biHeight;
	lBitSize = pBitmapInfo->bmiHeader.biSizeImage;

	// If the size isn't specified, calculate it anyway	
	if (pBitmapInfo->bmiHeader.biBitCount != 24)
	{
		free(pBitmapInfo);
		return FALSE;
	}

	if (lBitSize == 0)
		lBitSize = (*nWidth *
			pBitmapInfo->bmiHeader.biBitCount + 7) / 8 *
		abs(*nHeight);

	// Allocate space for the actual bitmap
	free(pBitmapInfo);
	pBits = (BYTE*)malloc(sizeof(BYTE) * lBitSize);

	// Read in the bitmap bits, check for corruption
	if (!ReadFile(hFileHandle, pBits, lBitSize, &dwBytes, NULL) ||
		dwBytes != (sizeof(BYTE) * lBitSize))
		pBits = NULL;

	// Close the bitmap file now that we have all the data we need
	CloseHandle(hFileHandle);

	return pBits;
}

void LoadTexture()
{
	// 获取位图数据
	BYTE* pBytes;
	int nWidth, nHeight;
	pBytes = gltReadBMPBits("D:\\image0.BMP", &nWidth, &nHeight);

	定义二维纹理
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, nWidth, nHeight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pBytes);

	//控制滤波
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	//说明映射方式
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

	glEnable(GL_TEXTURE_2D);
}

//初始化OpenGL
void init(void)
{
	/** 用户自定义的初始化过程 */
	glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
	glClearDepth(1.0f);
	glDepthFunc(GL_LEQUAL);
	glEnable(GL_DEPTH_TEST);
	glShadeModel(GL_SMOOTH);
	glEnable(GL_TEXTURE_2D);                       /**< 启用纹理映射 */
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

	/**启用并定义一维求值程序  */
	glEnable(GL_MAP1_VERTEX_3);
	glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &points[0][0]);

    /** 启用纹理映射 */
	LoadTexture();
	glEnable(GL_TEXTURE_2D);

	/** 设置光源的属性值 */
	glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);		/**< 设置环境光 */
	glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);		/**< 设置漫射光 */
	glLightfv(GL_LIGHT1, GL_SPECULAR, LightSpecular);	    /**< 设置漫射光 */
	glLightfv(GL_LIGHT1, GL_POSITION, LightPosition);	    /**< 设置光源位置 */

	/** 设置材质属性值 */
	glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
	glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
	glMaterialfv(GL_FRONT, GL_SHININESS, mat_shinness);

	/** 启用光源 */
	glEnable(GL_LIGHT1);

	/*启用求值程序*/
	glEnable(GL_MAP2_VERTEX_3);
	glEnable(GL_MAP2_TEXTURE_COORD_2);
	glEnable(GL_AUTO_NORMAL);

	glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, &ctrlpoints[0][0][0]);
	glMap2f(GL_MAP2_TEXTURE_COORD_2, 0, 1, 2, 2, 0, 1, 4, 2, &texpts[0][0][0]);
	glMapGrid2f(20, 0.0, 1.0, 20, 0.0, 1.0);
}
//主要的绘制过程
void display(void)
{
	/** 用户自定义的绘制过程 */
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	  /**< 清除缓存 */

	glLoadIdentity();


	glShadeModel(GL_FLAT);
	glLoadIdentity();
	glTranslatef(0, 0, -13.0);
	//求值
	glBegin(GL_LINE_STRIP);
	for (int i = 0; i < 100; i++)
	{
		/** 执行求值程序 */
		glEvalCoord1f((float)i / 100.0f);
	}
	glEnd();
//	glMapGrid1f(100, 0.0, 1.0);
//	glEvalMesh1(GL_LINE, 0, 100);

//绘制控制点	
	glPointSize(4.0);
	glBegin(GL_POINTS);
	for (int j = 0; j < 4; j++)
		glVertex3fv(&points[j][0]);
	glEnd();

	glFlush();				      /**< 强制执行所有的OpenGL命令 */
	glutSwapBuffers();


	/** 绘制过程 */
	glTranslatef(0.0f, 0.0f, -13.0f);
	glRotatef(rot, 1.0, 1.0, 1.0);
	glScalef(3.0f, 3.0f, 3.0f);
	glEvalMesh2(renderMode[mode], 0, 20, 0, 20);
	glFlush();			
	/**< 强制执行所有的OpenGL命令 */
}
//在窗口改变大小时调用
void reshape(int w, int h) {
	glViewport(0, 0, w, h);//设置视口
	glMatrixMode(GL_PROJECTION);//设置当前为投影变换模式
	glLoadIdentity();//用单位矩阵替换当前变换矩阵
	gluPerspective(45, (float)w / h, 4, 100.0);//设置正交投影视图体
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}
void TimerFunction(int value)
{
	rot += 10;
	if (rot == 360)
		rot = 0;
	// Redraw the scene with new coordinates
	glutPostRedisplay();
	glutTimerFunc(500, TimerFunction, 1);
}
//处理键盘
void keyboard(unsigned char key, int x, int y) {
	switch (key) {
	case 27://esc键退出
		exit(0);
		break;
	case 'a':
	case 'A':
		lp = TRUE;						      /**< lp 设为 TRUE */
		light = !light;					      /**< 切换光源的 TRUE/FALSE */
		if (!light)						      /**< 如果没有光源 */
		{
			glDisable(GL_LIGHTING);		      /**< 禁用光源 */
		}
		else
		{
			glEnable(GL_LIGHTING);		      /**< 启用光源 */
		}
		break;
	case 'd':
	case 'D':
		sp = TRUE;						      /**< lp 设为 TRUE */
		mode += 1;
		if (mode > 1)
			mode = 0;
		break;
	default:
		break;
	}
}
int main(int argc, char* argv[])							//主函数: 参数数量&参数值
{
	glutInit(&argc, argv);
	glutInitWindowSize(640, 480);
	glutCreateWindow("Basic");//设置窗口标题
	init();//初始化OpenGL
	glutDisplayFunc(display);//设置显示回调函数 
	glutReshapeFunc(reshape);//设置reshape回调函数
	glutKeyboardFunc(keyboard);//设置键盘回调函数
	glutTimerFunc(500, TimerFunction, 1);
	glutMainLoop();//进入主循环	
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值