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