您的位置:首页 > 编程语言

OpenGL实验(二三代码整理)桌子

2017-04-08 23:55 190 查看
终于把桌子都搞定了(虽然还是有点丑?)算是把一开始想做的都做了吧


table.h

//@author Birdy&C 2017.4.7
#pragma once
#define GLUT_DISABLE_ATEXIT_HACK
#include <stdio.h>
#include<windows.h>
#include <gL\GLAUX.H>
#include <gl\GLUT.H>

//函数声明

//===========main.cpp============//

void init();

//===========event.cpp============//
void timer(int p);
void mouse(int button, int state, int x, int y);
void motion(int x, int y);
void special(int key, int x, int y);
void keyboard(unsigned char key, int x, int y);
void setProjection(int width, int height);
void reshape(int w1, int h1);

//===========render.cpp============//
AUX_RGBImageRec *LoadBMP(CHAR *Filename);
int LoadGLTextures();
void Draw_Leg();
void Draw_Table();
void drawMain();
void renderScene();
void renderScenesw1();
void renderScenesw2();
void renderScenesw3();
void renderSceneAll();

//全局变量

extern bool mouseisdown, loopr;
extern int mainWindow, subWindow1, subWindow2, subWindow3, rx, ry, rz, tx, ty, w, h;
extern int time, state;
extern const int border;
extern float  mx, mz;
extern GLuint  texture[1];


render.cpp

// render.cpp : 绘制函数
//@author Birdy&C 2017.4.7

#include "table.h"

AUX_RGBImageRec *LoadBMP(CHAR *Filename)    // 载入位图图象
{
FILE *File = NULL;                      // 文件句柄
int check;
if (!Filename)                          // 确保文件名已提供
{
return NULL;                        // 如果没提供,返回 NULL
}
check = fopen_s(&File, Filename, "r");      // 尝试打开文件
if (check == 0)                             // 文件存在
{
fclose(File);                           // 关闭句柄
return auxDIBImageLoadA(Filename);      // 载入位图并返回指针
}
return NULL;                                // 如果载入失败,返回 NULL
}

int LoadGLTextures()         // 载入位图(调用上面的代码)并转换成纹理
{
int Status = FALSE;                             // 状态指示器
AUX_RGBImageRec *TextureImage[1];               // 创建纹理的存储空间
memset(TextureImage, 0, sizeof(void *) * 1);    // 将指针设为 NULL
TextureImage[0] = LoadBMP("wood.bmp");          // 载入位图,检查有无错误,如果位图没找到则退出

if (NULL != TextureImage[0])
{
Status = TRUE;                              // 将 Status 设为 TRUE
printf("LOAD SUCCESS\n");
glGenTextures(1, &texture[0]);              // 创建纹理

glBindTexture(GL_TEXTURE_2D, texture[0]);   // 使用来自位图数据生成 的典型纹理

// 生成纹理
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // 线形滤波
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 线形滤波
}

if (TextureImage[0])                    // 纹理是否存在
{
if (TextureImage[0]->data)          // 纹理图像是否存在
{
free(TextureImage[0]->data);    // 释放纹理图像占用的内存
}
free(TextureImage[0]);              // 释放图像结构
}
return Status;                          // 返回 Status
}

void Draw_Leg() // This function draws a triangle with RGB colors
{
//四面
glBegin(GL_QUADS);

glTexCoord2f(0.0f, 1.0f);   glVertex3f(-0.5f, 0
4000
.5f, 0.0f); // 纹理和四边形的左上
glTexCoord2f(0.0f, 0.0f);   glVertex3f(-0.5f, 0.5f, 3.0f); // 纹理和四边形的左下
glTexCoord2f(1.0f, 0.0f);   glVertex3f(0.5f, 0.5f, 3.0f); // 纹理和四边形的右下
glTexCoord2f(1.0f, 1.0f);   glVertex3f(0.5f, 0.5f, 0.0f); // 纹理和四边形的右上

glTexCoord2f(1.0f, 1.0f);   glVertex3f(-0.5f, -0.5f, 0.0f); // 纹理和四边形的右上
glTexCoord2f(0.0f, 1.0f);   glVertex3f(0.5f, -0.5f, 0.0f); // 纹理和四边形的左上
glTexCoord2f(0.0f, 0.0f);   glVertex3f(0.5f, -0.5f, 3.0f); // 纹理和四边形的左下
glTexCoord2f(1.0f, 0.0f);   glVertex3f(-0.5f, -0.5f, 3.0f); // 纹理和四边形的右下

glTexCoord2f(1.0f, 0.0f);   glVertex3f(0.5f, -0.5f, 0.0f); // 纹理和四边形的右下
glTexCoord2f(1.0f, 1.0f);   glVertex3f(0.5f, 0.5f, 0.0f); // 纹理和四边形的右上
glTexCoord2f(0.0f, 1.0f);   glVertex3f(0.5f, 0.5f, 3.0f); // 纹理和四边形的左上
glTexCoord2f(0.0f, 0.0f);   glVertex3f(0.5f, -0.5f, 3.0f); // 纹理和四边形的左下

glTexCoord2f(0.0f, 0.0f);   glVertex3f(-0.5f, 0.5f, 0.0f); // 纹理和四边形的左下
glTexCoord2f(1.0f, 0.0f);   glVertex3f(-0.5f, -0.5f, 0.0f); // 纹理和四边形的右下
glTexCoord2f(1.0f, 1.0f);   glVertex3f(-0.5f, -0.5f, 3.0f); // 纹理和四边形的右上
glTexCoord2f(0.0f, 1.0f);   glVertex3f(-0.5f, 0.5f, 3.0f); // 纹理和四边形的左上

//底边
glTexCoord2f(0.4f, 0.0f); glVertex3f(-0.5f, -0.5f, 0); // 纹理和四边形的右下
glTexCoord2f(0.4f, 0.4f); glVertex3f(-0.5f, 0.5f, 0); // 纹理和四边形的右上
glTexCoord2f(0.0f, 0.4f); glVertex3f(0.5f, 0.5f, 0); // 纹理和四边形的左上
glTexCoord2f(0.0f, 0.4f); glVertex3f(0.5f, -0.5f, 0); // 纹理和四边形的左下

glEnd();
}

void Draw_Table() // This function draws a triangle with RGB colors
{
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);            //空心
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);        //实心
glBindTexture(GL_TEXTURE_2D, texture[0]);      // 选择纹理
//glColor3f(1.0f, 1.0f, 1.0f);                      //选择颜色
//上下
glBegin(GL_QUADS);

glTexCoord2f(0.0f, 0.0f);   glVertex3f(-2.5f, 2.0f, 4.0f);// 纹理和四边形的左上
glTexCoord2f(1.0f, 0.0f);   glVertex3f(2.5f, 2.0f, 4.0f);// 纹理和四边形的右上
glTexCoord2f(1.0f, 1.0f);   glVertex3f(2.5f, -2.0f, 4.0f); // 纹理和四边形的右下
glTexCoord2f(0.0f, 1.0f);   glVertex3f(-2.5f, -2.0f, 4.0f);// 纹理和四边形的左下

glTexCoord2f(1.0f, 0.0f);   glVertex3f(-2.5f, -2.0f, 3.0f); // 纹理和四边形的右下
glTexCoord2f(1.0f, 1.0f);   glVertex3f(-2.5f, 2.0f, 3.0f);// 纹理和四边形的右上
glTexCoord2f(0.0f, 1.0f);   glVertex3f(2.5f, 2.0f, 3.0f); // 纹理和四边形的左上
glTexCoord2f(0.0f, 0.0f);   glVertex3f(2.5f, -2.0f, 3.0f); // 纹理和四边形的左下

//四面
glTexCoord2f(0.5f, 0.0f);   glVertex3f(2.5f, -2.0f, 4.0f); // 纹理和四边形的左下
glTexCoord2f(0.5f, 1.0f);   glVertex3f(2.5f, 2.0f, 3.0f); // 纹理和四边形的右下
glTexCoord2f(0.0f, 1.0f);   glVertex3f(2.5f, -2.0f, 3.0f); // 纹理和四边形的右上
glTexCoord2f(0.0f, 0.0f);   glVertex3f(2.5f, 2.0f, 4.0f); // 纹理和四边形的左上

glTexCoord2f(0.5f, 0.0f);   glVertex3f(-2.5f, 2.0f, 3.0f); // 纹理和四边形的左上
glTexCoord2f(1.0f, 0.0f);   glVertex3f(-2.5f, -2.0f, 3.0f);// 纹理和四边形的左下
glTexCoord2f(1.0f, 1.0f);   glVertex3f(-2.5f, -2.0f, 4.0f); // 纹理和四边形的右下
glTexCoord2f(0.5f, 1.0f);   glVertex3f(-2.5f, 2.0f, 4.0f); // 纹理和四边形的右上

glTexCoord2f(0.0f, 1.0f);   glVertex3f(-2.5f, 2.0f, 3.0f); // 纹理和四边形的左上
glTexCoord2f(0.0f, 0.5f);   glVertex3f(-2.5f, 2.0f, 4.0f); // 纹理和四边形的左下
glTexCoord2f(1.0f, 0.5f);   glVertex3f(2.5f, 2.0f, 4.0f); // 纹理和四边形的右下
glTexCoord2f(1.0f, 1.0f);   glVertex3f(2.5f, 2.0f, 3.0f); // 纹理和四边形的右上

glTexCoord2f(1.0f, 0.5f);   glVertex3f(-2.5f, -2.0f, 3.0f);// 纹理和四边形的右上
glTexCoord2f(0.0f, 0.5f);   glVertex3f(2.5f, -2.0f, 3.0f); // 纹理和四边形的左上
glTexCoord2f(0.0f, 0.0f);   glVertex3f(2.5f, -2.0f, 4.0f); // 纹理和四边形的左下
glTexCoord2f(1.0f, 0.0f);   glVertex3f(-2.5f, -2.0f, 4.0f); // 纹理和四边形的右下

glEnd();

//画桌子腿
glPushMatrix();
glTranslatef(1.5f, 1.0f, 0.0f);
Draw_Leg();
glPopMatrix();

glPushMatrix();
glTranslatef(1.5f, -1.0f, 0.0f);
Draw_Leg();
glPopMatrix();

glPushMatrix();
glTranslatef(-1.5f, 1.0f, 0.0f);
Draw_Leg();
glPopMatrix();

glPushMatrix();
glTranslatef(-1.5f, -1.0f, 0.0f);
Draw_Leg();
glPopMatrix();

glFlush();

}

void drawMain()
{
glPushMatrix();

if (loopr)
{
switch (state)
{
case 1:
mz = 0.1 * time;
state = 1;
break;
case 2:
rx = 12 * time;
break;
case 3:
glScalef(1 + 0.01*time, 1 + 0.01*time, 1 + 0.01*time);
break;
}
}
glTranslatef(mx, 0.0f, mz);     // 平移

//旋转
glRotatef(rx, 1, 0, 0);
glRotatef(ry, 0, 1, 0);
glRotatef(rz, 0, 0, 1);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存

Draw_Table();                       // Draw table

glPopMatrix();

}

// Display func for main window
void renderScene() {
glClearColor(1.0, 1.0,
f602
1.0, 0.0);
glutSwapBuffers();
glutSetWindow(mainWindow);
glClear(GL_COLOR_BUFFER_BIT);
glutPostRedisplay();
}

// Display func for sub window 1
void renderScenesw1() {

glutSetWindow(subWindow1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();
gluLookAt(0, 15.0f, 0, 0, 0, 0, 0.0f, 0.0f, 1.0f);
glPushMatrix();
drawMain();
glPopMatrix();
glutSwapBuffers();
glutPostRedisplay();

}

// Display func for sub window 2
void renderScenesw2() {

glutSetWindow(subWindow2);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();
gluLookAt(15.0f, 0, 0, 0, 0, 0, 0.0f, 0.0f, 1.0f);
glPushMatrix();
drawMain();
glPopMatrix();
glutSwapBuffers();
glutPostRedisplay();
}

// Display func for sub window 3
void renderScenesw3() {

glutSetWindow(subWindow3);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0, 0, 15.0f, 0, 0, 0, 0, -1, 0);
glPushMatrix();
drawMain();
glPopMatrix();
glutSwapBuffers();
glutPostRedisplay();

}

// Global render func
void renderSceneAll()
{
renderScene();
renderScenesw1();
renderScenesw2();
renderScenesw3();
}


event.cpp

// event.cpp : 处理事件
//@author Birdy&C 2017.4.7
#include "table.h"

void timer(int p)
{
time++;
if (time >= 30)
time = 0;
if (loopr)
{
glutTimerFunc(200, timer, 0);//循环
}
}

void mouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON)
{
if (state == GLUT_DOWN)
{
mouseisdown = true;
loopr = false;
tx = x;
ty = y;
}
else
{
mouseisdown = false;
}
}

if (button == GLUT_RIGHT_BUTTON)
if (state == GLUT_DOWN)
{
loopr = true;
glutTimerFunc(200, timer, 0);
}
}

void motion(int x, int y)
{
if (mouseisdown == true)        //如果是鼠标左键按下拖动
{
rz += x - tx;                   //偏移量记录
rx += y - ty;
tx = x;                         //更新坐标
ty = y;
glutPostRedisplay();
}
}

void special(int key, int x, int y)
{
//上下左右键盘控制xz坐标方向上的平移
switch (key)
{
case GLUT_KEY_LEFT:
mx += 0.2;
glutPostRedisplay();
break;
case GLUT_KEY_RIGHT:
mx -= 0.2;
glutPostRedisplay();
break;
case GLUT_KEY_UP:
mz += 0.2;
glutPostRedisplay();
break;

case GLUT_KEY_DOWN:
mz -= 0.2;
glutPostRedisplay();
break;
}
}

void keyboard(unsigned char key, int x, int y)
{
//123改变自动移动方式
//接收事件的时候改变坐标位置(使得满足作业要求)
switch (key)
{
case '1':
rx = ry = rz = 0;
mx = mz = 0;
mx = 5;
state = 1;
break;
case '2':
rx = ry = rz = 0;
mx = mz = 0;
state = 2;
break;
case '3':
rx = ry = rz = 0;
mx = mz = 0;
mx = -5;
state = 3;
break;
}
}

void setProjection(int width, int height)
{
glViewport(0, 0, width, height);                        // Reset The Current Viewport
glMatrixMode(GL_PROJECTION);                            // Select The Projection Matrix
glLoadIdentity();                                       // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);                             // Select The Modelview Matrix
glLoadIdentity();                                       // Reset The Modelview Matrix
}

void reshape(int w1, int h1) {

if (h1 == 0)
h1 = 1;

// we're keeping these values cause we'll need them latter
w = w1;
h = h1;

// set subwindow 1 as the active window
glutSetWindow(subWindow1);
// resize and reposition the sub window
glutPositionWindow(border, border);
glutReshapeWindow(w - 2 * border, h / 2 - border * 3 / 2);
setProjection(w - 2 * border, h / 2 - border * 3 / 2);

// set subwindow 2 as the active window
glutSetWindow(subWindow2);
// resize and reposition the sub window
glutPositionWindow(border, (h + border) / 2);
glutReshapeWindow(w / 2 - border * 3 / 2, h / 2 - border * 3 / 2);
setProjection(w / 2 - border * 3 / 2, h / 2 - border * 3 / 2);

// set subwindow 3 as the active window
glutSetWindow(subWindow3);
// resize and reposition the sub window
glutPositionWindow((w + border) / 2, (h + border) / 2);
glutReshapeWindow(w / 2 - border * 3 / 2, h / 2 - border * 3 / 2);
setProjection(w / 2 - border * 3 / 2, h / 2 - border * 3 / 2);
}


main.cpp

// main.cpp : 定义控制台应用程序的入口点。
//@author Birdy&C 2017.4.7

#include "table.h"

//子窗口
int mainWindow, subWindow1, subWindow2, subWindow3;
//旋转记录
int rx = 0;
int ry = 0;
int rz = 0;
//平移记录
float mx = 0;
float mz = 0;
//鼠标位置
int tx, ty;
//边界宽度
const int border = 6;
//主窗口大小
int w, h;
//自动事件控制
bool mouseisdown = false;
bool loopr = false;
int state = 1;
int time = 0;
//存储纹理
GLuint  texture[1];

//初始化
void init()
{
//纹理控制部分

//glCullFace(GL_BACK);              //背面裁剪(背面不可见)
//glEnable(GL_CULL_FACE);           //启用裁剪
glEnable(GL_DEPTH_TEST);            //深度测试
glEnable(GL_TEXTURE_2D);
LoadGLTextures();                   //载入纹理贴图

//事件处理部分
glutIgnoreKeyRepeat(0);             //确认是否忽略自动的连续击键
glutMouseFunc(mouse);               //鼠标点击事件
glutMotionFunc(motion);             //鼠标拖动事件
glutKeyboardFunc(keyboard);         //键盘事件
glutSpecialFunc(special);           //特殊键盘 没有ASCII值 如上下左右

//光照控制部分
GLfloat DiffuseLightn[] = { 1.0, 1.0, 1.0, 0.0 };
GLfloat light_position1[] = { 10.0, 20.0, 30.0, 0.0 };
GLfloat light_position2[] = { 10.0, 10.0, -30.0, 0.0 };

glLightfv(GL_LIGHT0,  GL_DIFFUSE, DiffuseLightn);
glLightfv(GL_LIGHT0, GL_POSITION, light_position1);
glLightfv(GL_LIGHT1, GL_DIFFUSE, DiffuseLightn);
glLightfv(GL_LIGHT1, GL_POSITION, light_position2);

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glDepthFunc(GL_LESS);

}

int main (int argc,  char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(640,480);
mainWindow = glutCreateWindow("Birdy");
LoadGLTextures();            //载入纹理贴图

glutDisplayFunc(renderSceneAll);
glutReshapeFunc(reshape);
init();

//子窗口建立
subWindow1 = glutCreateSubWindow(mainWindow, border, border, w - 2 * border, h / 2 - border * 3 / 2);
glutDisplayFunc(renderScenesw1);
init();

subWindow2 = glutCreateSubWindow(mainWindow, border, (h + border) / 2, w / 2 - border * 3 / 2, h / 2 - border * 3 / 2);
glutDisplayFunc(renderScenesw2);
init();

subWindow3 = glutCreateSubWindow(mainWindow, (w + border) / 2, (h + border) / 2, w / 2 - border * 3 / 2, h / 2 - border * 3 / 2);
glutDisplayFunc(renderScenesw3);
init();

glutMainLoop();

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  opengl