📄 lesson22.cpp
字号:
if (Image=auxDIBImageLoad("Data/multi_on_alpha.bmp")) {
alpha=new char[4*Image->sizeX*Image->sizeY]; // Create Memory For RGBA8-Texture
for (int a=0; a<Image->sizeX*Image->sizeY; a++)
alpha[4*a+3]=Image->data[a*3]; // Pick Only Red Value As Alpha!
if (!(Image=auxDIBImageLoad("Data/multi_on.bmp"))) status=false;
for (a=0; a<Image->sizeX*Image->sizeY; a++) {
alpha[4*a]=Image->data[a*3]; // R
alpha[4*a+1]=Image->data[a*3+1]; // G
alpha[4*a+2]=Image->data[a*3+2]; // B
}
glGenTextures(1, &multiLogo); // Create One Textures
// Create Linear Filtered RGBA8-Texture
glBindTexture(GL_TEXTURE_2D, multiLogo);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Image->sizeX, Image->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, alpha);
delete alpha;
}
else status=false;
if (Image) { // If Texture Exists
if (Image->data) delete Image->data; // If Texture Image Exists
delete Image;
Image=NULL;
}
return status; // Return The Status
}
GLvoid ReSizeGLScene(GLsizei width, GLsizei height) { // Resize And Initialize The GL Window
if (height==0) // Prevent A Divide By Zero By
height=1; // Making Height Equal One
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 doCube (void) {
int i;
glBegin(GL_QUADS);
// Front Face
glNormal3f( 0.0f, 0.0f, +1.0f);
for (i=0; i<4; i++) {
glTexCoord2f(data[5*i],data[5*i+1]);
glVertex3f(data[5*i+2],data[5*i+3],data[5*i+4]);
}
// Back Face
glNormal3f( 0.0f, 0.0f,-1.0f);
for (i=4; i<8; i++) {
glTexCoord2f(data[5*i],data[5*i+1]);
glVertex3f(data[5*i+2],data[5*i+3],data[5*i+4]);
}
// Top Face
glNormal3f( 0.0f, 1.0f, 0.0f);
for (i=8; i<12; i++) {
glTexCoord2f(data[5*i],data[5*i+1]);
glVertex3f(data[5*i+2],data[5*i+3],data[5*i+4]);
}
// Bottom Face
glNormal3f( 0.0f,-1.0f, 0.0f);
for (i=12; i<16; i++) {
glTexCoord2f(data[5*i],data[5*i+1]);
glVertex3f(data[5*i+2],data[5*i+3],data[5*i+4]);
}
// Right face
glNormal3f( 1.0f, 0.0f, 0.0f);
for (i=16; i<20; i++) {
glTexCoord2f(data[5*i],data[5*i+1]);
glVertex3f(data[5*i+2],data[5*i+3],data[5*i+4]);
}
// Left Face
glNormal3f(-1.0f, 0.0f, 0.0f);
for (i=20; i<24; i++) {
glTexCoord2f(data[5*i],data[5*i+1]);
glVertex3f(data[5*i+2],data[5*i+3],data[5*i+4]);
}
glEnd();
}
int InitGL(GLvoid) // All Setup For OpenGL Goes Here
{
multitextureSupported=initMultitexture();
if (!LoadGLTextures()) return false; // Jump To Texture Loading Routine
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
initLights(); // Initialize OpenGL Light
return true; // Initialization Went OK
}
// Calculates v=vM, M Is 4x4 In Column-Major, v Is 4dim. Row (i.e. "Transposed")
void VMatMult(GLfloat *M, GLfloat *v) {
GLfloat res[3];
res[0]=M[ 0]*v[0]+M[ 1]*v[1]+M[ 2]*v[2]+M[ 3]*v[3];
res[1]=M[ 4]*v[0]+M[ 5]*v[1]+M[ 6]*v[2]+M[ 7]*v[3];
res[2]=M[ 8]*v[0]+M[ 9]*v[1]+M[10]*v[2]+M[11]*v[3];;
v[0]=res[0];
v[1]=res[1];
v[2]=res[2];
v[3]=M[15]; // Homogenous Coordinate
}
/* Okay, Here Comes The Important Stuff:
On http://www.nvidia.com/marketing/Developer/DevRel.nsf/TechnicalDemosFrame?OpenPage
You Can Find A Demo Called GL_BUMP That Is A Little Bit More Complicated.
GL_BUMP: Copyright Diego T醨tara, 1999.
- diego_tartara@ciudad.com.ar -
The Idea Behind GL_BUMP Is, That You Compute The Texture-Coordinate Offset As Follows:
0) All Coordinates Either In Object Or In World Space.
1) Calculate Vertex v From Actual Position (The Vertex You're At) To The Lightposition
2) Normalize v
3) Project This v Into Tangent Space.
Tangent Space Is The Plane "Touching" The Object In Our Current Position On It.
Typically, If You're Working With Flat Surfaces, This Is The Surface Itself.
4) Offset s,t-Texture-Coordinates By The Projected v's x And y-Component.
* This Would Be Called Once Per Vertex In Our Geometry, If Done Correctly.
* This Might Lead To Incoherencies In Our Texture Coordinates, But Is Ok As Long As You Did Not
* Wrap The Bumpmap.
Basically, We Do It The Same Way With Some Exceptions:
ad 0) We'll Work In Object Space All Time. This Has The Advantage That We'll Only
Have To Transform The Lightposition From Frame To Frame. This Position Obviously
Has To Be Transformed Using The Inversion Of The Modelview Matrix. This Is, However,
A Considerable Drawback, If You Don't Know How Your Modelview Matrix Was Built, Since
Inverting A Matrix Is Costly And Complicated.
ad 1) Do It Exactly That Way.
ad 2) Do It Exactly That Way.
ad 3) To Project The Lightvector Into Tangent Space, We'll Support The Setup-Routine
With Two Directions: One Of Increasing s-Texture-Coordinate Axis, The Other In
Increasing t-Texture-Coordinate Axis. The Projection Simply Is (Assumed Both
texCoord Vectors And The Lightvector Are Normalized) The Dotproduct Between The
Respective texCoord Vector And The Lightvector.
ad 4) The Offset Is Computed By Taking The Result Of Step 3 And Multiplying The Two
Numbers With MAX_EMBOSS, A Constant That Specifies How Much Quality We're Willing To
Trade For Stronger Bump-Effects. Just Temper A Little Bit With MAX_EMBOSS!
WHY THIS IS COOL:
* Have A Look!
* Very Cheap To Implement (About One Squareroot And A Couple Of MULs)!
* Can Even Be Further Optimized!
* SetUpBump Doesn't Disturb glBegin()/glEnd()
* THIS DOES ALWAYS WORK - Not Only With XY-Tangent Spaces!!
DRAWBACKS:
* Must Know "Structure" Of Modelview-Matrix Or Invert It. Possible To Do The Whole Thing
* In World Space, But This Involves One Transformation For Each Vertex!
*/
void SetUpBumps(GLfloat *n, GLfloat *c, GLfloat *l, GLfloat *s, GLfloat *t) {
GLfloat v[3]; // Vertex From Current Position To Light
GLfloat lenQ; // Used To Normalize
// Calculate v From Current Vector c To Lightposition And Normalize v
v[0]=l[0]-c[0];
v[1]=l[1]-c[1];
v[2]=l[2]-c[2];
lenQ=(GLfloat) sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
v[0]/=lenQ; v[1]/=lenQ; v[2]/=lenQ;
// Project v Such That We Get Two Values Along Each Texture-Coordinat Axis.
c[0]=(s[0]*v[0]+s[1]*v[1]+s[2]*v[2])*MAX_EMBOSS;
c[1]=(t[0]*v[0]+t[1]*v[1]+t[2]*v[2])*MAX_EMBOSS;
}
void doLogo(void) { // MUST CALL THIS LAST!!!, Billboards The Two Logos.
glDepthFunc(GL_ALWAYS);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glDisable(GL_LIGHTING);
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D,glLogo);
glBegin(GL_QUADS);
glTexCoord2f(0.0f,0.0f); glVertex3f(0.23f, -0.4f,-1.0f);
glTexCoord2f(1.0f,0.0f); glVertex3f(0.53f, -0.4f,-1.0f);
glTexCoord2f(1.0f,1.0f); glVertex3f(0.53f, -0.25f,-1.0f);
glTexCoord2f(0.0f,1.0f); glVertex3f(0.23f, -0.25f,-1.0f);
glEnd();
if (useMultitexture) {
glBindTexture(GL_TEXTURE_2D,multiLogo);
glBegin(GL_QUADS);
glTexCoord2f(0.0f,0.0f); glVertex3f(-0.53f, -0.4f,-1.0f);
glTexCoord2f(1.0f,0.0f); glVertex3f(-0.33f, -0.4f,-1.0f);
glTexCoord2f(1.0f,1.0f); glVertex3f(-0.33f, -0.3f,-1.0f);
glTexCoord2f(0.0f,1.0f); glVertex3f(-0.53f, -0.3f,-1.0f);
glEnd();
}
glDepthFunc(GL_LEQUAL);
}
bool doMesh1TexelUnits(void) {
GLfloat c[4]={0.0f,0.0f,0.0f,1.0f}; // Holds Current Vertex
GLfloat n[4]={0.0f,0.0f,0.0f,1.0f}; // Normalized Normal Of Current Surface
GLfloat s[4]={0.0f,0.0f,0.0f,1.0f}; // s-Texture Coordinate Direction, Normalized
GLfloat t[4]={0.0f,0.0f,0.0f,1.0f}; // t-Texture Coordinate Direction, Normalized
GLfloat l[4]; // Holds Our Lightposition To Be Transformed Into Object Space
GLfloat Minv[16]; // Holds The Inverted Modelview Matrix To Do So.
int i;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
// Build Inverse Modelview Matrix First. This Substitutes One Push/Pop With One glLoadIdentity();
// Simply Build It By Doing All Transformations Negated And In Reverse Order.
glLoadIdentity();
glRotatef(-yrot,0.0f,1.0f,0.0f);
glRotatef(-xrot,1.0f,0.0f,0.0f);
glTranslatef(0.0f,0.0f,-z);
glGetFloatv(GL_MODELVIEW_MATRIX,Minv);
glLoadIdentity();
glTranslatef(0.0f,0.0f,z);
glRotatef(xrot,1.0f,0.0f,0.0f);
glRotatef(yrot,0.0f,1.0f,0.0f);
// Transform The Lightposition Into Object Coordinates:
l[0]=LightPosition[0];
l[1]=LightPosition[1];
l[2]=LightPosition[2];
l[3]=1.0f; // Homogenous Coordinate
VMatMult(Minv,l);
/* PASS#1: Use Texture "Bump"
No Blend
No Lighting
No Offset Texture-Coordinates */
glBindTexture(GL_TEXTURE_2D, bump[filter]);
glDisable(GL_BLEND);
glDisable(GL_LIGHTING);
doCube();
/* PASS#2: Use Texture "Invbump"
Blend GL_ONE To GL_ONE
No Lighting
Offset Texture Coordinates
*/
glBindTexture(GL_TEXTURE_2D,invbump[filter]);
glBlendFunc(GL_ONE,GL_ONE);
glDepthFunc(GL_LEQUAL);
glEnable(GL_BLEND);
glBegin(GL_QUADS);
// Front Face
n[0]=0.0f; n[1]=0.0f; n[2]=1.0f;
s[0]=1.0f; s[1]=0.0f; s[2]=0.0f;
t[0]=0.0f; t[1]=1.0f; t[2]=0.0f;
for (i=0; i<4; i++) {
c[0]=data[5*i+2];
c[1]=data[5*i+3];
c[2]=data[5*i+4];
SetUpBumps(n,c,l,s,t);
glTexCoord2f(data[5*i]+c[0], data[5*i+1]+c[1]);
glVertex3f(data[5*i+2], data[5*i+3], data[5*i+4]);
}
// Back Face
n[0]=0.0f; n[1]=0.0f; n[2]=-1.0f;
s[0]=-1.0f; s[1]=0.0f; s[2]=0.0f;
t[0]=0.0f; t[1]=1.0f; t[2]=0.0f;
for (i=4; i<8; i++) {
c[0]=data[5*i+2];
c[1]=data[5*i+3];
c[2]=data[5*i+4];
SetUpBumps(n,c,l,s,t);
glTexCoord2f(data[5*i]+c[0], data[5*i+1]+c[1]);
glVertex3f(data[5*i+2], data[5*i+3], data[5*i+4]);
}
// Top Face
n[0]=0.0f; n[1]=1.0f; n[2]=0.0f;
s[0]=1.0f; s[1]=0.0f; s[2]=0.0f;
t[0]=0.0f; t[1]=0.0f; t[2]=-1.0f;
for (i=8; i<12; i++) {
c[0]=data[5*i+2];
c[1]=data[5*i+3];
c[2]=data[5*i+4];
SetUpBumps(n,c,l,s,t);
glTexCoord2f(data[5*i]+c[0], data[5*i+1]+c[1]);
glVertex3f(data[5*i+2], data[5*i+3], data[5*i+4]);
}
// Bottom Face
n[0]=0.0f; n[1]=-1.0f; n[2]=0.0f;
s[0]=-1.0f; s[1]=0.0f; s[2]=0.0f;
t[0]=0.0f; t[1]=0.0f; t[2]=-1.0f;
for (i=12; i<16; i++) {
c[0]=data[5*i+2];
c[1]=data[5*i+3];
c[2]=data[5*i+4];
SetUpBumps(n,c,l,s,t);
glTexCoord2f(data[5*i]+c[0], data[5*i+1]+c[1]);
glVertex3f(data[5*i+2], data[5*i+3], data[5*i+4]);
}
// Right Face
n[0]=1.0f; n[1]=0.0f; n[2]=0.0f;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -