当前位置:网站首页>6.在屏幕上绘制一条贝塞尔曲线和一个贝塞尔曲面
6.在屏幕上绘制一条贝塞尔曲线和一个贝塞尔曲面
2022-07-24 05:16:00 【陌小呆^O^】
#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();//进入主循环
}
边栏推荐
猜你喜欢
随机推荐
你真的知道判断语句吗?
C语言入门篇 概述
【sklearn】PCA
Tips for using the built-in variable vars in BeanShell
Echo speaker pairing and operation method
C语言起步
【STL】Map &unordered_map
【【【递归】】】
Pointer learning diary (II)
MQTT学习
Create and delete databases using databases
JMeter FAQs
C语言进阶篇 六.文件的操作
Solutions to MySQL remote connection errors
MySQL insight
Introduction to threads
泛型和注解
C语言入门篇 二.函数
This is the first article
Ain 0722 sign in









