zoukankan      html  css  js  c++  java
  • OpenGL之路(八)加入�光照效果和键盘控制

    在opengl中加入�光照的效果,可用键盘控制放大缩小

    w键放大 s键缩小 d键开关灯

    预览效果例如以下:


    源代码例如以下:

    #include <gl/glut.h>
    #include <gl/glaux.h>
    #include <stdio.h>
    #pragma comment(lib, "opengl32.lib")
    #pragma comment(lib, "glut32.lib")
    #pragma comment(lib, "glu32.lib")
    #pragma comment(lib, "glut.lib")
    #pragma comment(lib, "glaux.lib")
    
    UINT g_bmp[1];//贴图编号
    
    GLfloat LightAmbient[] = { 0.5f, 0.5f, 0.5f, 1.0f }; //环境光參数,半亮白色
    GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f }; //漫射光參数,
    GLfloat LightPosition[] = { 0.0f, 0.0f, 0.0f, 1.0f }; //光源位置
    
    void Box(float x, float y, float z) //长方体
    {
    	glPushMatrix();
    	glScalef(x, y, z);
    	glEnable(GL_TEXTURE_2D); //贴图有效
    	glBegin(GL_QUADS);
    	glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);// 前
    	glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f);
    	glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, 1.0f);
    	glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
    	glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);// 后
    	glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
    	glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f);
    	glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, -1.0f);
    	glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);// 上
    	glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
    	glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, 1.0f, 1.0f);
    	glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f);
    	glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);// 下
    	glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, -1.0f, -1.0f);
    	glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f);
    	glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
    	glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, -1.0f, -1.0f);// 左
    	glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f);
    	glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, 1.0f, 1.0f);
    	glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f);
    	glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);// 右
    	glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
    	glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
    	glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
    	glEnd();
    	glDisable(GL_TEXTURE_2D);//取消贴图
    	glPopMatrix();
    }
    bool LoadTexture(char *filename, GLuint &texture)
    {
    	AUX_RGBImageRec *pImage = auxDIBImageLoadA(filename); //装入位图
    	if (pImage == NULL) return false;
    	glGenTextures(1, &texture); //生成贴图
    	glBindTexture(GL_TEXTURE_2D, g_bmp[0]); //贴图生效
    	gluBuild2DMipmaps(GL_TEXTURE_2D, 4, pImage->sizeX, pImage->sizeY, GL_RGB, GL_UNSIGNED_BYTE, pImage->data); //贴图数据
    	return true;
    }
    void init()
    {
    	LoadTexture("i:\4.bmp", g_bmp[0]);
    	glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); //设置环境光
    	glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); //设置漫射光
    	glLightfv(GL_LIGHT1, GL_POSITION, LightPosition); //设置光源位置
    	glEnable(GL_LIGHT1); //启用一号光源
    	glEnable(GL_LIGHTING); //开光
    }
    
    float s = 1, r = 0; //放大缩小的倍数和旋转參数
    void renderScene(void)
    {
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Clear The Screen And The Depth Buffer
    	glLoadIdentity();									// Reset The View
    	glTranslatef(0.0f, 0.0f, -5);
    	glRotatef(r, 1.0f, 1.0f, 0.0f);
    	glScalef(s, s, s);
    
    	Box(1, 1, 1);
    
    	r += 0.01;//旋转
    	glutSwapBuffers();
    }
    void changeSize(int w, int h)
    {
    	if (h == 0) h = 1;
    	float ratio = 1.0* w / h;
    	glMatrixMode(GL_PROJECTION);// 单位化投影矩阵。
    	glLoadIdentity();
    	glViewport(0, 0, w, h);// 设置视口大小为整个窗体大小
    	gluPerspective(45, ratio, 1, 1000);// 设置正确的投影矩阵
    	glMatrixMode(GL_MODELVIEW);//以下是设置模型视图矩阵
    	glLoadIdentity();
    	gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, -1.0, 0.0f, 1.0f, 0.0f);//设置观測点
    }
    int light = 1, bp = 0;
    void keyfunc(unsigned char ch, int x, int y)
    {
    	if (ch == 'w') //发大缩小
    		s += 0.1;
    	else if (ch == 's')
    		s -= 0.1;
    	if (ch == 'd')//d键开关灯
    	{
    		if (light)
    		{
    			light = 0;
    			glDisable(GL_LIGHTING);
    			printf("off
    ");
    		}
    		else
    		{
    			light = 1;
    			glEnable(GL_LIGHTING);
    			printf("on
    ");
    		}
    	}
    }
    int main(int argc, char * argv[])
    {
    	glutInit(&argc, argv);
    	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    	glutInitWindowPosition(100, 100);
    	glutInitWindowSize(320, 320);
    	glutCreateWindow("Hello OpenGL");
    	init();
    	glutDisplayFunc(renderScene);
    	glutIdleFunc(renderScene); //指定程序空暇时调用函数
    	glutReshapeFunc(changeSize); //指定窗体形状变化时的回调函数
    	glEnable(GL_DEPTH_TEST);
    	glutKeyboardFunc(keyfunc);//键盘回调函数
    	glutMainLoop();
    	return 0;
    }


    所用贴图例如以下:


  • 相关阅读:
    反射 动态导入 元类
    面向对象的继承
    面向对象基础总结
    面向对象基础
    包 logging hashlib copy模块
    os random sys json 模块
    【1012 | Day 43】前端之CSS(下)
    【1011 | Day 42】灵魂拷问:数据放在服务端和客户端的利与弊?
    【1011 | Day 42】socket实现ftp文件的上传和下载
    【1011 | Day 42】前端之CSS(上)
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/4069155.html
Copyright © 2011-2022 走看看