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 <stdio.h>
00008
00009 #include "ps2s/cpu_matrix.h"
00010 #include "ps2s/math.h"
00011
00012 #include "ps2gl/indexed_renderer.h"
00013 #include "ps2gl/glcontext.h"
00014 #include "ps2gl/material.h"
00015 #include "ps2gl/texture.h"
00016 #include "ps2gl/lighting.h"
00017
00018 #include "vu1_mem_indexed.h"
00019
00020 CIndexedRenderer::CIndexedRenderer( void *packet, CRendererProps caps, CRendererProps reqs,
00021 int inQuadsPerVert, int outQuadsPerVert,
00022 const char *name)
00023 : CBaseRenderer(packet, caps, reqs,
00024 inQuadsPerVert, outQuadsPerVert, kInputGeomStart, name)
00025 {
00026 printf("Max number of vertices in indexed array is %d\n", (kInputBufSize-4)/3 - 3 );
00027 printf("giftag = 0x%04x, context length = 0x%04x (%d)\n",
00028 kGifTag, kContextLength, kContextLength);
00029 }
00030
00031 void
00032 CIndexedRenderer::InitContext( GLenum primType, tU32 rcChanges, bool userRcChanged )
00033 {
00034 CGLContext &glContext = *pGLContext;
00035 CVifSCDmaPacket &packet = glContext.GetVif1Packet();
00036
00037 packet.Cnt();
00038 {
00039 AddVu1RendererContext( packet, primType, kContextStart );
00040
00041 packet.Mscal(0);
00042 packet.Flushe();
00043
00044 packet.Base( kDoubleBufBase );
00045 packet.Offset( kDoubleBufOffset );
00046 }
00047 packet.CloseTag();
00048
00049 CacheRendererState();
00050
00051
00052
00053 CImmLighting &lighting = glContext.GetImmLighting();
00054 bool doLighting = lighting.GetLightingEnabled();
00055
00056 float maxColorValue = GetMaxColorValue( XferTexCoords );
00057 cpu_vec_4 globalAmb;
00058 if (doLighting) globalAmb = lighting.GetGlobalAmbient() * maxColorValue;
00059 else globalAmb.set( 0, 0, 0, 0 );
00060
00061 CImmMaterial& material = glContext.GetMaterialManager().GetImmMaterial();
00062 cpu_vec_4 materialAmb = material.GetAmbient();
00063
00064 cpu_vec_4 materialEmm;
00065 if ( doLighting )
00066 materialEmm = material.GetEmission() * maxColorValue;
00067 else
00068 materialEmm = glContext.GetMaterialManager().GetCurColor() * maxColorValue;
00069
00070 ConstantVertColor = materialAmb * globalAmb + materialEmm;
00071 }
00072
00073 int
00074 CIndexedRenderer::GetPacketQwordSize( const CGeometryBlock &geometry )
00075 {
00076
00077 return Math::Max(geometry.GetTotalVertices() / 70, 1) * 1000;
00078 }
00079
00080 CRendererProps
00081 CIndexedRenderer::GetRenderContextDeps()
00082 {
00083 CRendererProps deps;
00084 deps = (tU64)0;
00085 deps.Lighting = 1;
00086 deps.Texture = 1;
00087 deps.PerVtxMaterial = 1;
00088
00089 return deps;
00090 }
00091
00092 bool
00093 CIndexedRenderer::GetCachePackets( const CGeometryBlock &geometry )
00094 {
00095 return !( pGLContext->GetImmLighting().GetLightingEnabled()
00096 && ! geometry.GetNormalsAreValid() );
00097 }
00098
00099 void
00100 CIndexedRenderer::DrawIndexedArrays( CGeometryBlock &block )
00101 {
00102
00103
00104
00105
00106
00107
00108 CVifSCDmaPacket &packet = pGLContext->GetVif1Packet();
00109
00110 int wordsPerVert = block.GetWordsPerVertex();
00111 int wordsPerNormal = (block.GetNormalsAreValid()) ? block.GetWordsPerNormal() : 0;
00112 int wordsPerTex = (block.GetTexCoordsAreValid()) ? block.GetWordsPerTexCoord() : 0;
00113 int wordsPerColor = (block.GetColorsAreValid()) ? block.GetWordsPerColor() : 0;
00114
00115 InitXferBlock( packet, wordsPerVert, wordsPerNormal, wordsPerTex, wordsPerColor );
00116
00117 for ( int curArray = 0; curArray < block.GetNumArrays(); curArray++ ) {
00118
00119 const void *normals, *vertices, *texCoords, *colors;
00120 vertices = block.GetVerticesAreValid() ? block.GetVertices(curArray) : NULL;
00121 normals = block.GetNormalsAreValid() ? block.GetNormals(curArray) : NULL;
00122 texCoords = block.GetTexCoordsAreValid() ? block.GetTexCoords(curArray) : NULL;
00123 colors = block.GetColorsAreValid() ? block.GetColors(curArray) : NULL;
00124
00125 packet.Cnt();
00126 packet.Stcycl(1,3).Nop();
00127 packet.CloseTag();
00128
00129 int numIndices = block.GetNumIndices(curArray);
00130 const void *indices = block.GetIndices(curArray);
00131 int numVertices = block.GetArrayLength(curArray);
00132
00133 XferBlock( packet,
00134 vertices, normals, texCoords, colors,
00135 kInputGeomStart,
00136 0, numVertices );
00137
00138
00139
00140 packet.Cnt();
00141 {
00142 packet.Stmod( Vifs::AddModes::kOffset );
00143
00144 Vifs::tMask mask = { 3, 3, 3, 0,
00145 3, 3, 3, 0,
00146 3, 3, 3, 0,
00147 3, 3, 3, 0 };
00148 packet.Stmask( mask );
00149 static const float row[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
00150 packet.Strow( row );
00151 packet.Pad128();
00152 }
00153 packet.CloseTag();
00154
00155 int numIndexQwords = numIndices/16 + (numIndices%16 > 0);
00156 packet.Ref( Core::MakePtrNormal((const unsigned int*)indices), numIndexQwords );
00157 {
00158 packet.Stcycl(1,1);
00159 packet.OpenUnpack( Vifs::UnpackModes::s_16, kInputGeomStart,
00160 Packet::kDoubleBuff, Packet::kMasked );
00161
00162 packet.CloseUnpack( numIndexQwords*8 );
00163 }
00164
00165
00166
00167 packet.Cnt();
00168 {
00169
00170
00171 packet.Stmod( Vifs::AddModes::kNone );
00172 packet.OpenUnpack( Vifs::UnpackModes::v4_32, 0, Packet::kDoubleBuff );
00173 {
00174 packet += numVertices;
00175 packet += numIndices/2 + (numIndices & 1);
00176 packet += numIndices;
00177 packet += 0;
00178 }
00179 packet.CloseUnpack();
00180
00181
00182
00183 packet.Strow( &ConstantVertColor );
00184 packet.Stcycl(numVertices,0);
00185 Vifs::tMask mask = { 1, 1, 1, 3,
00186 1, 1, 1, 3,
00187 1, 1, 1, 3,
00188 1, 1, 1, 3 };
00189 packet.Stmask( mask );
00190 packet.OpenUnpack( Vifs::UnpackModes::v4_32, kTempAreaStart,
00191 Packet::kDoubleBuff, Packet::kMasked );
00192 packet.CloseUnpack(numVertices);
00193
00194
00195
00196 packet.Mscnt();
00197 packet.Pad128();
00198 }
00199 packet.CloseTag();
00200 }
00201 }