【BumpMap】凹凸贴图绘制简单图形
来源:互联网 发布:双向冒泡排序算法 编辑:程序博客网 时间:2024/04/29 18:19
BumpMap 的主要思想就是通过 (x + dx, y), (x - dx, y), (x, y + dy), (x, y - dy) 这四个点的高度计算出(x, y) 点法向量的改变量:
if (i != XMAX)normal[i][j] = normal[i][j] - (position[i][j] - position[i + 1][j]).Unitization() * (height[i][j] - height[i + 1][j]);if (i != 0)normal[i][j] = normal[i][j] - (position[i][j] - position[i - 1][j]).Unitization() * (height[i][j] - height[i - 1][j]);if (j != YMAX)normal[i][j] = normal[i][j] - (position[i][j] - position[i][j + 1]).Unitization() * (height[i][j] - height[i][j + 1]);if (j != 0)normal[i][j] = normal[i][j] - (position[i][j] - position[i][j - 1]).Unitization() * (height[i][j] - height[i][j - 1]);在实现过程中我们取 dx, dx 为相邻的格点就可以方便计算啦!其中 Unitization() 是单位化操作。
尝试理解一下第二行的运算,如果 (i + 1, j) 的高度要低于 (i, j),显然 (i, j) 点的法向量应该偏向 (i + 1, j) 的方向。
(position[i][j] - position[i + 1][j]).Unitization()是从 (i + 1, j) 指向 (i, j) 的单位向量,如果
(height[i][j] - height[i + 1][j])是一个正值,那么
- (position[i][j] - position[i + 1][j]).Unitization() * (height[i][j] - height[i + 1][j])就会沿着 (i, j) 到 (i + 1, j) 的方向,也就是normal应有的改变量。
还有一个小难点是建立球体的模型,我选择了使用三角片去贴满球体的表面,这里涉及到了球坐标到直角坐标的变换。
float theta = i * 2.0 * PI / XMAX, fai = j * PI / YMAX;position[i][j].x = 1.0 * sin(fai) * sin(theta);position[i][j].y = 1.0 * cos(fai);position[i][j].z = 1.0 * sin(fai) * cos(theta);而直角坐标的优点就是,(i, j) 的法线和 (i, j) 的坐标是一致的。
normal[i][j] = position[i][j];
剩下的就是用OpenGL绘制三角形和设置光照属性啦!就很简单~
附完整代码【当然可能有错咯】:
#include <GL/freeglut.h>#include <iostream>#include <iomanip>#include <algorithm>#include <cmath>#include "MyMath.h"using namespace std;const int XINIT = 800, YINIT = 800;const int XMAX = 1600, YMAX = 800;float height[XMAX + 1][YMAX + 1];int XCURR = XINIT, YCURR = YINIT;const int MY_POLYGON = 0, MY_SPHERE = 1;const int MY_MODE = MY_SPHERE;Vector3f position[XMAX + 1][YMAX + 1], normal[XMAX + 1][YMAX + 1];void InitNormal() {for (int i = 0; i <= XMAX; i++)for (int j = 0; j <= YMAX; j++) {if (MY_MODE == MY_POLYGON) {normal[i][j].x = 0.0;normal[i][j].y = 0.0;normal[i][j].z = 1.0;}if (MY_MODE == MY_SPHERE) {normal[i][j] = position[i][j];}if (i != XMAX)normal[i][j] = normal[i][j] - (position[i][j] - position[i + 1][j]).Unitization() * (height[i][j] - height[i + 1][j]);if (i != 0)normal[i][j] = normal[i][j] - (position[i][j] - position[i - 1][j]).Unitization() * (height[i][j] - height[i - 1][j]);if (j != YMAX)normal[i][j] = normal[i][j] - (position[i][j] - position[i][j + 1]).Unitization() * (height[i][j] - height[i][j + 1]);if (j != 0)normal[i][j] = normal[i][j] - (position[i][j] - position[i][j - 1]).Unitization() * (height[i][j] - height[i][j - 1]);normal[i][j].Unitization();}}void RenderScene() {glClearColor(0.0, 0.0, 0.0, 1.0);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glPointSize(10.0f);glLineWidth(1.0f);glPushMatrix();{GLfloat sunLightPosition[] = {1.0f, 1.0f, 1.0f, 0.0f};GLfloat sunLightAmbient[] = {0.6f, 0.6f, 0.6f, 1.0f};GLfloat sunLightDiffuse[] = {0.6f, 0.6f, 0.6f, 1.0f};GLfloat sunLightSpecular[] = {1.0f, 1.0f, 1.0f, 1.0f};glLightfv(GL_LIGHT0, GL_POSITION, sunLightPosition);glLightfv(GL_LIGHT0, GL_AMBIENT, sunLightAmbient); glLightfv(GL_LIGHT0, GL_DIFFUSE, sunLightDiffuse);glLightfv(GL_LIGHT0, GL_SPECULAR, sunLightSpecular);glEnable(GL_LIGHT0);glEnable(GL_LIGHTING);}/*static float rotateTheta = 0.0;glRotated(-23.5, 0.0, 0.0, 1.0);glRotated(rotateTheta, 0.0, 1.0, 0.0);rotateTheta += 1;*/{GLfloat triangleMatAmbient[] = {0.6f, 0.6f, 0.6f, 1.0f};GLfloat triangleMatDiffuse[] = {0.6f, 0.6f, 0.6f, 1.0f};GLfloat triangleMatSpecular[] = {1.0f, 1.0f, 1.0f, 1.0f};GLfloat triangleMatEmission[] = {0.1f, 0.1f, 0.3f, 1.0f};GLfloat triangleMatShininess = 100.0f;glMaterialfv(GL_FRONT, GL_AMBIENT, triangleMatAmbient);glMaterialfv(GL_FRONT, GL_DIFFUSE, triangleMatDiffuse);glMaterialfv(GL_FRONT, GL_SPECULAR, triangleMatSpecular);glMaterialfv(GL_FRONT, GL_EMISSION, triangleMatEmission);glMaterialf(GL_FRONT, GL_SHININESS, triangleMatShininess);}glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);glBegin(GL_TRIANGLES);{for (int i = 0; i < XMAX; i++)for (int j = 0; j < YMAX; j++) {glNormal3fv(normal[i][j]());glVertex3fv(position[i][j]());glNormal3fv(normal[i + 1][j]());glVertex3fv(position[i + 1][j]());glNormal3fv(normal[i][j + 1]());glVertex3fv(position[i][j + 1]());}for (int i = 0; i < XMAX; i++)for (int j = 0; j < YMAX; j++) {glNormal3fv(normal[i + 1][j]());glVertex3fv(position[i + 1][j]());glNormal3fv(normal[i + 1][j + 1]());glVertex3fv(position[i + 1][j + 1]());glNormal3fv(normal[i + 1][j + 1]());glVertex3fv(position[i][j + 1]());}}glEnd();glPopMatrix();glutSwapBuffers();}void ReshapeWindow(int w, int h) {glViewport(0, 0, w, h);XCURR = w;YCURR = h;glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(2 * atan(h / (YINIT * 5.0)) / PI * 180, 1.0 * w / h, 0.5, 18);glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0f, 1.0f, 0.0);}void MouseMotion(int x, int y) {float xFloat = (x - XCURR * 0.5f) / (YINIT * 0.5);float yFloat = (YCURR * 0.5f - y) / (YINIT * 0.5);if (xFloat < -1.0 || xFloat > 1.0 || yFloat < -1.0 || yFloat > 1.0)return;int xInt = floor((xFloat + 1.0) * 0.5 * XMAX);int yInt = floor((yFloat + 1.0) * 0.5 * YMAX);height[xInt + 0][yInt + 0] = -3;height[xInt + 1][yInt + 0] = -3;height[xInt + 0][yInt + 1] = -3;height[xInt + 1][yInt + 1] = -3;}void MyInit() {for (int i = 0; i <= XMAX; i++)for (int j = 0; j <= YMAX; j++) {{if (i % 80 >= 20 && i % 80 < 60 && j % 80 >= 20 && j % 80 < 60)height[i][j] = 2.0;elseheight[i][j] = 0.0;}if (MY_MODE == MY_POLYGON) {position[i][j].x = i * 2.0 / XMAX - 1.0;position[i][j].y = j * 2.0 / YMAX - 1.0;position[i][j].z = 0.0;}if (MY_MODE == MY_SPHERE) {float theta = i * 2.0 * PI / XMAX, fai = j * PI / YMAX;position[i][j].x = 1.0 * sin(fai) * sin(theta);position[i][j].y = 1.0 * cos(fai);position[i][j].z = 1.0 * sin(fai) * cos(theta);}}InitNormal();}int main(int argc, char** argv) {glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);glutInitWindowPosition(800, 40);glutInitWindowSize(XINIT, YINIT);glutCreateWindow("OpenGL");glEnable(GL_POINT_SMOOTH);glEnable(GL_LINE_SMOOTH);glEnable(GL_DEPTH_TEST);glutDisplayFunc(RenderScene);glutReshapeFunc(ReshapeWindow);//glutIdleFunc(RenderScene);//glutMotionFunc(MouseMotion);MyInit();glutMainLoop();}
这个程序还有一些别的功能哦!
以下是用到的数据结构【其实只有一个】:
#pragma once#include <math.h>#include <iostream>using namespace std;const float PI = 3.1415926f;class Vector3f {public:float x, y, z, *array;Vector3f(float x = 0.0, float y = 0.0, float z = 0.0): x(x), y(y), z(z) {array = new float[3];}Vector3f operator * (const float lambda) {return Vector3f(x * lambda, y * lambda, z * lambda);}Vector3f operator + (const Vector3f & tempVector3f) {return Vector3f(x + tempVector3f.x, y + tempVector3f.y,z + tempVector3f.z);}Vector3f operator - (const Vector3f & tempVector3f) {return Vector3f(x - tempVector3f.x, y - tempVector3f.y,z - tempVector3f.z);}Vector3f operator * (const Vector3f & tempVector3f) {return Vector3f(y * tempVector3f.z - z * tempVector3f.y,z * tempVector3f.x - x * tempVector3f.z,x * tempVector3f.y - y * tempVector3f.x);}Vector3f & operator = (const Vector3f & tempVector3f) {x = tempVector3f.x;y = tempVector3f.y;z = tempVector3f.z;return (*this);}~Vector3f() {delete[] array;}float Modulus() {return sqrt(x * x + y * y + z * z);}Vector3f & Unitization() {float modulus = Modulus();x /= modulus;y /= modulus;z /= modulus;return (*this);}float * operator () () {array[0] = x;array[1] = y;array[2] = z;return array;}friend ostream & operator << (ostream & out, const Vector3f & vec) {return out << vec.x << " " << vec.y << " " << vec.z;}};
0 0
- 【BumpMap】凹凸贴图绘制简单图形
- 制作简单的法线贴图,使图片有凹凸感
- 凹凸贴图(bump mapping)
- modelview与凹凸贴图
- unity3d 凹凸贴图、法线贴图、置换贴图
- 凹凸贴图、法线贴图、置换贴图
- opengl 绘制简单图形
- 图形简单绘制擦除
- Android 简单图形绘制
- OpenGL绘制简单图形
- Android绘制简单图形
- 简单绘制图形
- OpenGL简单图形绘制
- 简单图形绘制
- OpenGL---绘制简单图形
- CSS绘制简单图形
- svg绘制简单图形
- CSS绘制简单图形
- scroller与scrollto使用(二)
- kafka部署与简单使用
- 使WordPress改域名后网站正常运行的方法
- 5.host 命令
- UNITY 2D学习笔记(二):C#脚本编写
- 【BumpMap】凹凸贴图绘制简单图形
- 去普吉岛旅游都带啥_普吉岛旅游行前准备
- Java 中的静态内部类
- py2、py3的如何导入Queue对象
- solr5.2.1查询参数说明
- 正则表达式
- visual studio 2015 无法启动服务,原因可能是已被禁用或与其相关联的设备没有启动
- Java 中的方法内部类
- windows7 安装mysql_python 提示 unable to find vcvarsall.bat