00001
00002
00003
00004
00005 #include "ps2gl/material.h"
00006 #include "ps2gl/glcontext.h"
00007 #include "ps2gl/dlist.h"
00008 #include "ps2gl/lighting.h"
00009
00010
00011
00012
00013
00014 CImmMaterial::CImmMaterial( CGLContext &context )
00015 : CMaterial(context),
00016 Ambient( 0.2f, 0.2f, 0.2f, 1.0f ),
00017 Diffuse( 0.8f, 0.8f, 0.8f, 1.0f ),
00018 Specular( 0.0f, 0.0f, 0.0f, 1.0f ),
00019 Emission( 0.0f, 0.0f, 0.0f, 1.0f ),
00020 Shininess(0.0f)
00021 {
00022 }
00023
00024 void
00025 CImmMaterial::SetSpecular( cpu_vec_xyzw specular )
00026 {
00027 TellRendererMaterialChanged();
00028 Specular = specular;
00029
00030 if ( Specular != cpu_vec_4(0,0,0,0) )
00031 GLContext.GetImmLighting().MaterialHasSpecular();
00032 else {
00033 GLContext.SpecularEnabledChanged();
00034 GLContext.GetImmGeomManager().GetVsmManager().SpecularEnabledChanged(false);
00035 }
00036 }
00037
00038 void
00039 CImmMaterial::LightsHaveSpecular()
00040 {
00041 if ( Specular != cpu_vec_4(0,0,0,0) ) {
00042 GLContext.SpecularEnabledChanged();
00043 GLContext.GetImmGeomManager().GetVsmManager().SpecularEnabledChanged(true);
00044 }
00045 }
00046
00047
00048
00049
00050
00051 class CSetMaterialPropCmd : public CDListCmd {
00052 cpu_vec_xyzw Value;
00053 GLenum Property;
00054 public:
00055 CSetMaterialPropCmd( GLenum prop, cpu_vec_xyzw value )
00056 : Value(value), Property(prop) {}
00057 CDListCmd* Play() {
00058 glMaterialfv( GL_FRONT, Property, reinterpret_cast<float*>(&Value) );
00059 return CDListCmd::GetNextCmd( this );
00060 }
00061 };
00062
00063 void
00064 CDListMaterial::SetAmbient( cpu_vec_xyzw ambient )
00065 {
00066 CDList &dlist = pGLContext->GetDListManager().GetOpenDList();
00067 dlist += CSetMaterialPropCmd( GL_AMBIENT, ambient );
00068 TellRendererMaterialChanged();
00069 }
00070
00071 void
00072 CDListMaterial::SetDiffuse( cpu_vec_xyzw diffuse )
00073 {
00074 CDList &dlist = pGLContext->GetDListManager().GetOpenDList();
00075 dlist += CSetMaterialPropCmd( GL_DIFFUSE, diffuse );
00076 TellRendererMaterialChanged();
00077 }
00078
00079 void
00080 CDListMaterial::SetSpecular( cpu_vec_xyzw specular )
00081 {
00082 CDList &dlist = pGLContext->GetDListManager().GetOpenDList();
00083 dlist += CSetMaterialPropCmd( GL_SPECULAR, specular );
00084 TellRendererMaterialChanged();
00085 GLContext.SpecularEnabledChanged();
00086 }
00087
00088 void
00089 CDListMaterial::SetEmission( cpu_vec_xyzw emission )
00090 {
00091 CDList &dlist = pGLContext->GetDListManager().GetOpenDList();
00092 dlist += CSetMaterialPropCmd( GL_EMISSION, emission );
00093 TellRendererMaterialChanged();
00094 }
00095
00096 void
00097 CDListMaterial::SetShininess( float shine )
00098 {
00099 CDList &dlist = pGLContext->GetDListManager().GetOpenDList();
00100 dlist += CSetMaterialPropCmd( GL_SHININESS, cpu_vec_xyzw(shine, 0, 0, 0) );
00101 TellRendererMaterialChanged();
00102 }
00103
00104
00105
00106
00107
00108 void
00109 CMaterialManager::Color( cpu_vec_xyzw color )
00110 {
00111 CurColor = color;
00112
00113 if ( UseColorMaterial ) {
00114 switch( ColorMaterialMode ) {
00115 case GL_EMISSION: CurMaterial->SetEmission( color ); break;
00116 case GL_AMBIENT: CurMaterial->SetAmbient( color ); break;
00117 case GL_DIFFUSE: CurMaterial->SetDiffuse( color ); break;
00118 case GL_SPECULAR: CurMaterial->SetSpecular( color ); break;
00119 case GL_AMBIENT_AND_DIFFUSE:
00120 CurMaterial->SetAmbient( color );
00121 CurMaterial->SetDiffuse( color );
00122 break;
00123 }
00124 }
00125 GLContext.CurMaterialChanged();
00126 }
00127
00128 class CSetUseColorMaterialCmd : public CDListCmd {
00129 bool UseCM;
00130 public:
00131 CSetUseColorMaterialCmd( bool use ) : UseCM(use) {}
00132 CDListCmd* Play() {
00133 pGLContext->GetMaterialManager().SetUseColorMaterial(UseCM);
00134 return CDListCmd::GetNextCmd(this);
00135 }
00136 };
00137
00138 void
00139 CMaterialManager::SetUseColorMaterial( bool yesNo )
00140 {
00141 if ( ! InDListDef ) {
00142 UseColorMaterial = yesNo;
00143 if ( yesNo ) Color( CurColor );
00144 GLContext.CurMaterialChanged();
00145 }
00146 else {
00147 CDList &dlist = GLContext.GetDListManager().GetOpenDList();
00148 dlist += CSetUseColorMaterialCmd(yesNo);
00149 GLContext.CurMaterialChanged();
00150 }
00151 }
00152
00153 class CSetColorMatModeCmd : public CDListCmd {
00154 GLenum Mode;
00155 public:
00156 CSetColorMatModeCmd( GLenum mode ) : Mode(mode) {}
00157 CDListCmd* Play() {
00158 pGLContext->GetMaterialManager().SetColorMaterialMode(Mode);
00159 return CDListCmd::GetNextCmd(this);
00160 }
00161 };
00162
00163 void
00164 CMaterialManager::SetColorMaterialMode( GLenum mode )
00165 {
00166 if ( ! InDListDef ) {
00167 ColorMaterialMode = mode;
00168 Color(CurColor);
00169 GLContext.CurMaterialChanged();
00170 }
00171 else {
00172 CDList &dlist = GLContext.GetDListManager().GetOpenDList();
00173 dlist += CSetColorMatModeCmd(mode);
00174 GLContext.CurMaterialChanged();
00175 }
00176 }
00177
00178
00179
00180
00181
00182
00183 void glMaterialfv( GLenum face, GLenum pname, const GLfloat *params )
00184 {
00185 CMaterial& material = pGLContext->GetMaterialManager().GetCurMaterial();
00186
00187 switch (face) {
00188 case GL_BACK:
00189 mNotImplemented( "GL_BACK - only front material is available" );
00190 break;
00191 case GL_FRONT_AND_BACK:
00192 mNotImplemented( "GL_FRONT_AND_BACK - only front material is available" );
00193 case GL_FRONT:
00194 switch (pname) {
00195 case GL_AMBIENT:
00196 material.SetAmbient( cpu_vec_xyzw(params[0], params[1], params[2], params[3]) );
00197 break;
00198 case GL_DIFFUSE:
00199 material.SetDiffuse( cpu_vec_xyzw(params[0], params[1], params[2], params[3]) );
00200 break;
00201 case GL_SPECULAR:
00202 material.SetSpecular( cpu_vec_xyzw(params[0], params[1], params[2], params[3]) );
00203 break;
00204 case GL_EMISSION:
00205 material.SetEmission( cpu_vec_xyzw(params[0], params[1], params[2], params[3]) );
00206 break;
00207 case GL_SHININESS:
00208 material.SetShininess( *params );
00209 break;
00210 case GL_AMBIENT_AND_DIFFUSE:
00211 material.SetAmbient( cpu_vec_xyzw(params[0], params[1], params[2], params[3]) );
00212 material.SetDiffuse( cpu_vec_xyzw(params[0], params[1], params[2], params[3]) );
00213 break;
00214 default:
00215 mError( "shouldn't get here" );
00216 }
00217 break;
00218 default:
00219 mError( "shouldn't get here" );
00220 }
00221 }
00222
00223 void glMaterialf( GLenum face, GLenum pname, GLfloat param )
00224 {
00225 CMaterial& material = pGLContext->GetMaterialManager().GetCurMaterial();
00226
00227 switch (face) {
00228 case GL_BACK:
00229 mNotImplemented( "GL_BACK - only front material is available" );
00230 break;
00231 case GL_FRONT_AND_BACK:
00232 mNotImplemented( "GL_FRONT_AND_BACK - only front material is available" );
00233 case GL_FRONT:
00234 if ( pname == GL_SHININESS )
00235 material.SetShininess( param );
00236 else { mError("shoudn't get here"); }
00237 break;
00238 default:
00239 mError( "shouldn't get here" );
00240 }
00241 }
00242
00243 void glColorMaterial( GLenum face, GLenum mode )
00244 {
00245 pGLContext->GetMaterialManager().SetColorMaterialMode( mode );
00246 }
00247