📄 drawglscene.cpp
字号:
//////////////////////////////////////////////////////////////////////
// scene.cpp: implementation of the scene class.
//
//////////////////////////////////////////////////////////////////////
#include "scene.h"
//////////////////////////////////////////////////////////////////////
void static DrawSphereBase(int del_uhol_x, int del_uhol_y);
inline static void SetCombineARB( unsigned int unit, unsigned int combiner=GL_MODULATE, \
unsigned int source0=GL_PREVIOUS_ARB, unsigned int operand0=GL_SRC_COLOR, \
unsigned int source1=GL_TEXTURE, unsigned int operand1=GL_SRC_COLOR, \
unsigned int source2=GL_TEXTURE, unsigned int operand2=GL_SRC_ALPHA )
{
glActiveTextureARB( GL_TEXTURE0_ARB + unit ); // aktivovanie jednotky
glEnable(GL_TEXTURE_2D);
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB ); // budeme kombinovat, t.j. pouzijeme rozsirenie GL_ARB_texture_env_combine
glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, combiner );
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, source0 );
glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, operand0 );
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, source1 );
glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, operand1 );
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, source2 );
glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, operand2 );
// nastavujeme sposob kombinovania medzi texturou a ostatnymi moznymi zdrojmi == combiner
// GL_REPLACE Arg0
// GL_MODULATE Arg0 * Arg1
// GL_ADD Arg0 + Arg1
// GL_ADD_SIGNED_ARB Arg0 + Arg1 - 0.5
// GL_SUBTRACT_ARB Arg0 - Arg1
// GL_INTERPOLATE_ARB Arg0 * (Arg2) + Arg1 * (1-Arg2)
// GL_DOT3_RGB_ARB 4*((Arg0_r-0.5)*(Arg1_r-0.5) + (Arg0_g-0.5)*(Arg1_g-0.5) + (Arg0_b-0.5)*(Arg1_b-0.5))
// GL_DOT3_RGBA_ARB vysledok je ulozeny aj v alpha ( r,g,b,a )
// zdroje source0, source1, source2: GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
// operandy operand0, operand1, operand2
// GL_PRIMARY_COLOR_ARB primarna farba prichadzajuceho fragmentu (vypocita sa z osvetlenia)
// GL_TEXTURE farba textury prisluchajuca korespondujecej texturovacej jednotke
// GL_CONSTANT_ARB konstantna farba (nastavena s glColor)
// GL_PREVIOUS_ARB vysledko predchadzajucej texturavacej jednotky na texturovacej jednotky 0, je to mapovane z PRIMARY_COLOR_ARB
}
inline static void DisableAllUnits()
{
for( unsigned int gl_texture = GL_TEXTURE1_ARB; gl_texture < (unsigned int)(GL_TEXTURE0_ARB + ext.max.max_texture_units); gl_texture++)
{
glActiveTextureARB( gl_texture );
glDisable(GL_TEXTURE_2D);
}
SetCombineARB( 0);
}
static inline void GetSphereMappingCoordinates( float *s, float *t, const CVector &vertex, const CVector &n, const CMatrix4 &m)
{
CVector r,v;
v = m*vertex;
v.Normalise();
r = ReflectedRay( v, n);
r.z +=1.f;
float mul = 0.5f/r.Length();
*s = r.x*mul + 0.5f;
*t = r.y*mul + 0.5f;
}
void static DrawSphereBaseSphereMapping(int del_uhol_x, int del_uhol_y )
{
float delta=0.002f;
CVector a,b,ay,by;
float dy=360.f/del_uhol_y;
float dx=180.f*PI180/del_uhol_x;
float s,t;
CVector r,vertex,n;
CMatrix4 m,m1;
m.glGetMatrix();
m1.glGetMatrix();
m1.m14 = 0; m1.m24 = 0; m1.m34 = 0; m1.m44 = 1;
for(int x=0; x<del_uhol_x; x++)
{
float tx = (float)x/(float)del_uhol_x;
float ang = tx*180.f*PI180-90.f*PI180;
a.set( 0, (float)sin(ang) , (float)cos(ang));
b.set( 0, (float)sin(ang+dx), (float)cos(ang+dx));
glBegin( GL_TRIANGLE_STRIP);
GetSphereMappingCoordinates( &s, &t, a, m1*a, m);
glMultiTexCoord2fARB( GL_TEXTURE1_ARB ,s-0.5f+delta ,t-0.5f+delta);
glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 0, tx);
glMultiTexCoord2fARB( GL_TEXTURE2_ARB, 0, tx);
glNormal3fv(a.v);
glVertex3fv(a.v);
GetSphereMappingCoordinates( &s, &t, b, m1*b, m);
glMultiTexCoord2fARB( GL_TEXTURE1_ARB ,s-0.5f+delta ,t-0.5f+delta);
glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 0, tx+1.f/del_uhol_x);
glMultiTexCoord2fARB( GL_TEXTURE2_ARB, 0, tx+1.f/del_uhol_x);
glNormal3fv(b.v);
glVertex3fv(b.v);
ay = a; by = b;
for(int y=1; y<del_uhol_y+1; y++)
{
float ty = (float)y/(float)del_uhol_y;
ay = a; ay.RotY( ty*360.f);
by = b; by.RotY( ty*360.f);
GetSphereMappingCoordinates( &s, &t, ay, m1*ay, m);
glMultiTexCoord2fARB( GL_TEXTURE1_ARB ,s-0.5f+delta ,t-0.5f+delta);
glMultiTexCoord2fARB( GL_TEXTURE0_ARB, ty, tx);
glMultiTexCoord2fARB( GL_TEXTURE2_ARB, ty, tx);
glNormal3fv(ay.v);
glVertex3fv(ay.v);
vertex = m*by; vertex.Normalise();
GetSphereMappingCoordinates( &s, &t, by, m1*by, m);
glMultiTexCoord2fARB( GL_TEXTURE1_ARB ,s-0.5f+delta ,t-0.5f+delta);
glMultiTexCoord2fARB( GL_TEXTURE0_ARB, ty, tx+1.f/del_uhol_x);
glMultiTexCoord2fARB( GL_TEXTURE2_ARB, ty, tx+1.f/del_uhol_x);
glNormal3fv(by.v);
glVertex3fv(by.v);
}
glEnd();
}
}
void static DrawPlaneBaseSphereMapping(int del_x=4, int del_y=4, CVector &p=CVector(-1,-1,0), CVector &n=CVector(0,0,1), CVector &ds=CVector(2,0,0), CVector &dt=CVector(0,2,0))
{
float delta=0.002f;
float t,s;
float dx=1.f/del_x;
float dy=1.f/del_y;
CMatrix4 m,m1;
CVector a,b,a1,b1;
m.glGetMatrix();
m1.glGetMatrix();
m1.m14 = 0; m1.m24 = 0; m1.m34 = 0; m1.m44 = 1;
glNormal3fv( n.v);
n = m1*n;
ds *= dx;
dt *= dy;
a = p;
b = p+dt;
for(float y=0; y<1.f; y+=dy, a+=dt, b+=dt)
{
float y1=y+dy;
glBegin(GL_TRIANGLE_STRIP);
GetSphereMappingCoordinates( &s, &t, a, n, m);
glMultiTexCoord2fARB( GL_TEXTURE1_ARB ,s-0.5f+delta ,t-0.5f+delta);
glMultiTexCoord2fARB( GL_TEXTURE0_ARB ,0 ,y);
glMultiTexCoord2fARB( GL_TEXTURE2_ARB ,0 ,y);
glVertex3fv(a.v);
GetSphereMappingCoordinates( &s, &t, b, n, m);
glMultiTexCoord2fARB( GL_TEXTURE1_ARB ,s-0.5f+delta ,t-0.5f+delta);
glMultiTexCoord2fARB( GL_TEXTURE0_ARB ,0 ,y1);
glMultiTexCoord2fARB( GL_TEXTURE2_ARB ,0 ,y1);
glVertex3fv(b.v);
a1 = a; b1=b;
for(float x=dx; x<1.f+dx; x+=dx)
{
a1+=ds;
b1+=ds;
GetSphereMappingCoordinates( &s, &t, a1, n, m);
glMultiTexCoord2fARB( GL_TEXTURE1_ARB ,s-0.5f+delta ,t-0.5f+delta);
glMultiTexCoord2fARB( GL_TEXTURE0_ARB ,x ,y);
glMultiTexCoord2fARB( GL_TEXTURE2_ARB ,x ,y);
glVertex3fv(a1.v);
GetSphereMappingCoordinates( &s, &t, b1, n, m);
glMultiTexCoord2fARB( GL_TEXTURE1_ARB ,s-0.5f+delta ,t-0.5f+delta);
glMultiTexCoord2fARB( GL_TEXTURE0_ARB ,x ,y1);
glMultiTexCoord2fARB( GL_TEXTURE2_ARB ,x ,y1);
glVertex3fv(b1.v);
}
glEnd();
}
}
void static DrawCubeBaseSphereMapping(int del_x=4, int del_y=4,float size=0.75)
{
CVector p,n,s,t;
// pozerame na +x
n.set(-1,0,0);
s.set(0,0,2*size);
t.set(0,2*size,0);
p = CVector(-size,0,0) -0.5*s -0.5*t;
DrawPlaneBaseSphereMapping(del_x, del_y, p, n, s, t);
// pozerame na -x
n.set(1,0,0);
s.set(0,0,-2*size);
t.set(0,2*size,0);
p = CVector(size,0,0) -0.5*s -0.5*t;
DrawPlaneBaseSphereMapping(del_x, del_y, p, n, s, t);
// pozerame na +y
n.set(0,-1,0);
s.set(2*size,0,0);
t.set(0,0,2*size);
p = CVector(0,-size,0) -0.5*s -0.5*t;
DrawPlaneBaseSphereMapping(del_x, del_y, p, n, s, t);
// pozerame na -y
n.set(0,1,0);
s.set(2*size,0,0);
t.set(0,0,-2*size);
p = CVector(0,size,0) -0.5*s -0.5*t;
DrawPlaneBaseSphereMapping(del_x, del_y, p, n, s, t);
// pozerame na +z
n.set(0,0,1);
s.set(-2*size,0,0);
t.set(0,2*size,0);
p = CVector(0,0,-size) -0.5*s -0.5*t;
DrawPlaneBaseSphereMapping(del_x, del_y, p, n, s, t);
// pozerame na -z
n.set(0,0,1);
s.set(2*size,0,0);
t.set(0,2*size,0);
p = CVector(0,0,size) -0.5*s -0.5*t;
DrawPlaneBaseSphereMapping(del_x, del_y, p, n, s, t);
}
// Tu je vsetko co sa kresli
void scene::DrawGLScene()
{
if(keys['L'] && keys[VK_CONTROL]){ english = !english; keys['L']=0; }
static int mode=ROTATE_WALK|ROTATE_ABOUT_POINT; // volba modu pre cameru
if(keys['V']) // menime mod
{
switch(mode)
{
case ROTATE_WALK: mode=ROTATE_WALK|ROTATE_ABOUT_POINT; break;
case ROTATE_WALK|ROTATE_ABOUT_POINT: mode=ROTATE_FLY|ROTATE_ABOUT_POINT; break;
case ROTATE_FLY|ROTATE_ABOUT_POINT: mode=ROTATE_WALK; break;
default: mode=ROTATE_WALK;
}
if(mode&ROTATE_ABOUT_POINT)c->set.k_remap_mouse_button_vd_vpd=1;
else c->set.k_remap_mouse_button_vd_vpd=0;
c->setKeys();
c->Reset(); // reset camery
keys['V']=0;
}
c->MoveWorld(fps, mode); // otoci svetom na zaklade vstupov od mysi a klavesnice
// VYTVORENIE SPHERE MAP
// sphere map je textura ktora, predsatavuje reflexnu gulu sfotenu rovnobeznymi lucmi
// mozme ju vytvorit pomocou vykreslenej gule pri zapnutom cube mapping
// viewport velkost sphere map, pravouhle premietanie,
// camera co najdalej od gule, pretoze reflesny luc sa pocita z luca iduceho od kamery k akt. vertex
glViewport(0,0,renderableTexture,renderableTexture); // Viewport (pohlad)
// glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //cisti buffer v aktualnom viewporte a to iba color a hlbkovy bit
// glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glMatrixMode(GL_PROJECTION); // projekcia
glLoadIdentity(); // Reset pohladu - nacita jednotkovu maticu
glOrtho(-1,1,-1,1,-1,200); // nastavuje standardne pravouhle premietanie
glMatrixMode(GL_MODELVIEW); // Modelview
CMatrix4 cam; // nastavyme kameru
cam.Translate(0,0,-200); // konstantne posunutie 200
cam.MakeMatrix( c->vr, c->vu, -c->vd); // vytvorenie matice z vektorov
cam.glSetMatrix(); // nastavime maticu
CubeMapBegin();
cubemap.glBindTextureCube();
DrawSphereBase(40,40);
CubeMapEnd();
spheremap.glBindTexture2D();
glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, renderableTexture, renderableTexture ); // skopirujeme do sphere map
if(keys[VK_F11]){ SaveScreen_BMP(0,0,renderableTexture,renderableTexture);keys[VK_F11]=0; }
ReSizeGLScene(sirka, vyska); // naspat nastavyme view port + projekciu
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //cisti buffer v aktualnom viewporte a to iba color a hlbkovy bit
c->SetTransform(); // nastavyme kameru
glEnable( GL_TEXTURE_2D);
/*
GL_ATI_envmap_bumpmap
- rozsirenie umoznuje environment mapped bump mapping (EMBM) - mapovanie okolia ma hrbolaty zrkadlovy povrch
- metoda pouziva zavisle citanie
- su pouzivane dve textury, jedna zakladna a druha vyjadrujuca posun texturovych suradnic (du,dv)
- texturove koordinacie pre zakladnu texturu su pocitane takto:
u' = u + du * Rot[00] + dv * Rot[01]
v' = v + du * Rot[10] + dv * Rot[11]
kde u,v su povodne texturove koordinacie zakladnej texturu, du,dv je hodnota z textury vyjadrujucej posuv
a Rot je uzivatemom definovana rotacna matica
pouzitie:
glActiveTextureARB(GL_TEXTURE2_ARB); // aktivovanie jednotky
glEnable(GL_TEXTURE_2D);
glBindTexture( GL_TEXTURE_2D, dudv); // nastavenie textury
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); // budeme kombinovat, t.j. pouzijeme rozsirenie GL_ARB_texture_env_combine
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_BUMP_ENVMAP_ATI); // tato jednotka vyjadruje posuv
glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE1_ARB); // posuv sa aplikuje na jednotku 1
glTexBumpParameterfvATI( GL_BUMP_ROT_MATRIX_ATI, rot); // definovanie rotacnej matice
pracuje takto:
jednotka s GL_BUMP_ENVMAP_ATI ma texturu, ktora obsahuje posunutia (du,dv)
(du,dv) je rotovany maticou:
du' = du * Rot[00] + dv * Rot[01]
dv' = du * Rot[10] + dv * Rot[11]
(du',dv') sa pouziju na posunutie (u,v) koordinacii pri citani z textury na jednotke GL_BUMP_TARGET_ATI:
u = u + du'
v = v + dv'
Funkcie a konstanty:
// definovanie rotacnej matice
glTexBumpParameterfvATI( GL_BUMP_ROT_MATRIX_ATI, GLfloat *param);
glTexBumpParameterivATI( GL_BUMP_ROT_MATRIX_ATI, GLint *param);
glGetTexBumpParameterivATI(GLenum pname, GLint *param);
glGetTexBumpParameterfvATI(GLenum pname, GLfloat *param);
pname:
GL_BUMP_ROT_MATRIX_ATI - vrati aktualnu rotacnu maticu (velkosti GL_BUMP_ROT_MATRIX_SIZE_ATI)
GL_BUMP_ROT_MATRIX_SIZE_ATI - vrati pocet poloziek v GL_BUMP_ROT_MATRIX_ATI
GL_BUMP_NUM_TEX_UNITS_ATI - vrati pocet jednotiek podporujucich bump mapping
GL_BUMP_TEX_UNITS_ATI - vrati pole jednotiek podporujucich bump mapping (velkost GL_BUMP_NUM_TEX_UNITS_ATI)
void glTexImage2D( GLenum target, GLint level, GLint components, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
format, components:
GL_DUDV_ATI
GL_DU8DV8_ATI
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -