void ClientGameObjectManagerAddon::createSoldierNPC(Event_CreateSoldierNPC *pTrueEvent)
{
	PEINFO("CharacterControl: GameObjectManagerAddon: Creating CreateSoldierNPC\n");

	PE::Handle hSoldierNPC("SoldierNPC", sizeof(SoldierNPC));
	SoldierNPC *pSoldierNPC = new(hSoldierNPC) SoldierNPC(*m_pContext, m_arena, hSoldierNPC, pTrueEvent);
	pSoldierNPC->addDefaultComponents();

	// add the soldier as component to the ObjecManagerComponentAddon
	// all objects of this demo live in the ObjecManagerComponentAddon
	addComponent(hSoldierNPC);
}
void ClientGameObjectManagerAddon::do_CREATE_WAYPOINT(PE::Events::Event *pEvt)
{
	PEINFO("GameObjectManagerAddon::do_CREATE_WAYPOINT()\n");

	assert(pEvt->isInstanceOf<Event_CREATE_WAYPOINT>());

	Event_CREATE_WAYPOINT *pTrueEvent = (Event_CREATE_WAYPOINT*)(pEvt);

	PE::Handle hWayPoint("WayPoint", sizeof(WayPoint));
	WayPoint *pWayPoint = new(hWayPoint) WayPoint(*m_pContext, m_arena, hWayPoint, pTrueEvent);
	pWayPoint->addDefaultComponents();

	addComponent(hWayPoint);
}
Пример #3
0
int Effect::l_SetSpeTechniqueReady(lua_State *luaVM)
{
#if APIABSTRACTION_D3D11
	const char *techName = lua_tostring(luaVM, -1);

	Handle h = EffectManager::Instance()->getEffectHandle(techName);
	if (h.isValid())
	{
		Effect *pEffect = h.getObject<Effect>();
		pEffect->setSpeShaderSatus(true);
	}
	else
	{
		PEINFO("PE: ERROR: l_setSpeTechniqueReady() : provided technique does not exist!");
	}

	lua_pop(luaVM, 1);
#else
	assert(!"Not Implemented");
#endif
	return 0;
}
Пример #4
0
static bool loadFragmentShader_PSVita(PE::GameContext &ctx, const char *filename, const char *name,
	PEAlphaBlendState *pBlendState,
	const SceGxmProgram *gxmProgram,
	const SceGxmProgram *gxmVertexProgram,
	SceGxmShaderPatcherId &out_programId,
	SceGxmFragmentProgram * &out_program
	)
{
	PEString::generatePathname(ctx, filename, "Default", "GPUPrograms", PEString::s_buf, PEString::BUF_SIZE);

	PEINFO("PE: PROGRESS: loading shader: %s from %s\n", name, PEString::s_buf);

	if (strcmp("main", name))
	{
		assert(!"Only shaders programs with name \"main()\" are supported");
	}

	PSVitaRenderer *pPSVitaRenderer = static_cast<PSVitaRenderer *>(ctx.getGPUScreen());

	SceGxmErrorCode err = sceGxmShaderPatcherRegisterProgram(pPSVitaRenderer->m_shaderPatcher, gxmProgram, &out_programId);
	PEASSERT(err == SCE_OK, "Error creating shader patcher id");
	SceGxmFragmentProgram *clearFragmentProgram = NULL;
	
	err = sceGxmShaderPatcherCreateFragmentProgram(
		pPSVitaRenderer->m_shaderPatcher,
		out_programId,
		SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
		MSAA_MODE,
		pBlendState->m_blendEnabled ? &pBlendState->m_blendInfo : NULL,
		gxmVertexProgram,
		&out_program);

	checkErrCode(err);

	PEASSERT(err == SCE_OK, "Error creating shader");

	return true;
}
void AnimSetBufferGPU::releaseGPUBuffer()
{
#if !PE_API_IS_D3D11
    PEINFO("Not implemented!");
#endif
}
Пример #6
0
// Reads the specified buffer from file
void IndexBufferCPU::ReadIndexBuffer(const char *filename, const char *package)
{
	m_minVertexIndex = 0x7FFFFFFF;
	m_maxVertexIndex = 0x80000000;
    strcpy(&m_dbgName[0], filename);

    PEString::generatePathname(*m_pContext, filename, package, "IndexBuffers", PEString::s_buf, PEString::BUF_SIZE);
	
	// Path is now a full path to the file with the filename itself
	FileReader f(PEString::s_buf);
	
	char line[256];
	f.nextNonEmptyLine(line, 255);
	// TODO : make sure it is "INDEX_BUFFER"

	f.nextInt32(m_verticesPerPolygon);

	PEASSERT(m_verticesPerPolygon == 3, "Non triangle index buffers not supported when reading from disk!");

	m_verticesPerPolygon = 3;
	m_primitiveTopology = PEPrimitveTopology_TRIANGLES;

	PrimitiveTypes::Int32 totalPolygonCount;
	f.nextInt32(totalPolygonCount);

	PrimitiveTypes::Int32 numberOfSets;
	f.nextInt32(numberOfSets);
	m_indexRanges.reset(numberOfSets);
	m_vertsPerFacePerRange.reset(numberOfSets); // stores number of vertices in face for every range

	m_values.reset(totalPolygonCount * m_verticesPerPolygon); // verticesPerPolygon UInt16 per vertex
	//dbg
    //PrimitiveTypes::Int32 memoryAddress = (PrimitiveTypes::Int32)m_values.m_dataHandle.getObject();

	PrimitiveTypes::Int32 curVertexIndexIndex = 0; // tracks number of vertices processed so far
	// Read all values
	for (int i = 0; i < numberOfSets; i++)// TODO : Right now, no distinction is really made once the different sets are loaded in
	{
		m_vertsPerFacePerRange.add(m_verticesPerPolygon);
		PrimitiveTypes::Int32 boneSegmentCount;
		f.nextInt32(boneSegmentCount);

		IndexRange range(*m_pContext, m_arena); // stores range of indices for material index range. it also stores separation bone segments
		range.m_start = curVertexIndexIndex;
		range.m_boneSegments.reset(boneSegmentCount);
		int minIndexInRange = 0x7FFFFFFF;
		int maxIndexInRange = 0x80000000;


		PrimitiveTypes::UInt32 rangePolygonCount = 0;
		for (int i = 0; i < boneSegmentCount; i++)
		{
			range.m_boneSegments.add(IndexRange::BoneSegment(*m_pContext, m_arena));
			IndexRange::BoneSegment &boneSegment = range.m_boneSegments[range.m_boneSegments.m_size-1];

			PrimitiveTypes::Int32 boneCountInSegment;
			f.nextInt32(boneCountInSegment); // number of bones used in the segment

			boneSegment.m_boneSegmentBones.reset(boneCountInSegment);
			boneSegment.m_start = curVertexIndexIndex;

			for (PrimitiveTypes::UInt32 ib = 0; ib < (PrimitiveTypes::UInt32)(boneCountInSegment); ib++)
			{
				PrimitiveTypes::Int32 boneId;
				f.nextInt32(boneId); // number of bones used in the segment
				boneSegment.m_boneSegmentBones.add(boneId);
			}

			PrimitiveTypes::Int32 boneSegmentPolygonCount;
			f.nextInt32(boneSegmentPolygonCount);

			if (boneSegmentPolygonCount > 0)
			{
				boneSegment.m_end = boneSegment.m_start + boneSegmentPolygonCount * m_verticesPerPolygon - 1;

				rangePolygonCount += boneSegmentPolygonCount;
				curVertexIndexIndex += boneSegmentPolygonCount * m_verticesPerPolygon;
				
				PrimitiveTypes::Int32 val;
				for (int j = 0; j < boneSegmentPolygonCount * m_verticesPerPolygon; j++)
				{
					f.nextInt32(val);
					m_values.add(val);
					if (val > maxIndexInRange)
						maxIndexInRange = val;
					if (val < minIndexInRange)
						minIndexInRange = val;
				}
			}
			else
			{
				// this bone segment has no polygons in it, so we need to skip it
				boneSegment.m_boneSegmentBones.reset(0); // make sure we release this memory, but there still is a spot in the array that will not be used
				i--;
				boneSegmentCount--;
				range.m_boneSegments.remove(range.m_boneSegments.m_size-1);
				PEINFO("PE: Warning: Empty bone segment was found in index buffer. This will lead to extra memory allocated for the segment that never is added");
			}
		}

		range.m_end = range.m_start + rangePolygonCount * m_verticesPerPolygon - 1;
		range.m_minVertIndex = minIndexInRange;
		range.m_maxVertIndex = maxIndexInRange;
		if (maxIndexInRange > m_maxVertexIndex)
			m_maxVertexIndex = maxIndexInRange;
		if (minIndexInRange < m_minVertexIndex)
			m_minVertexIndex = minIndexInRange;

		if (range.m_boneSegments.m_size == 1 && range.m_boneSegments[0].m_boneSegmentBones.m_size == 0)
		{
			// we have only one bone segment in range and the are 0 bones - this is a static mesh case
			// we dont need to store list of bone segments then. the range will be drawn

			range.m_boneSegments.reset(0);
		}

		#if APIABSTRACTION_D3D11
			// we are going to combine all bone segments into 1
			if (range.m_boneSegments.m_size > 1)
			{
				IndexRange::BoneSegment &boneSegment = range.m_boneSegments[0];

				boneSegment.m_start = range.m_start;
				boneSegment.m_end = range.m_end;	

				range.m_boneSegments.m_size = 1;

				//release other bone segments
				for (int is = 1; is < range.m_boneSegments.m_size; ++is)
				{
					IndexRange::BoneSegment &boneSegment = range.m_boneSegments[is];
					boneSegment.m_boneSegmentBones.reset(0);
				}
			}
		#endif
		

		if (range.m_end >= range.m_start)
		{
			m_indexRanges.add(range);
		}
		else
		{
			PEINFO("PE: Warning: Empty Index range (material) found. This will lead to extra memory allocated for the material taht is never used.\n");
			range.m_boneSegments.reset(0); // we release this memory but there is still one spot in the array for unused index range
		}
	}
}
Пример #7
0
	// Reads the animation from file
	void AnimationCPU::ReadAnimation(FileReader &f, SkeletonCPU &skel, float positionFactor, int version)
	{
		
		// Read animation
		f.nextNonEmptyLine(m_name, 128);

		// Partial body animation
		PrimitiveTypes::Int32 numJoints;
		
		f.nextInt32(numJoints);
		
		m_numJoints = numJoints;

		m_startJoint = 0; // todo: partial body animation shouldnt be controlled by range, but rather by retargetting array that we have below
		m_endJoint = m_numJoints-1;

		int targetSkelNumJoints = skel.m_numJoints;

		int animJointToSkelJoint[512];
		PEASSERT(m_endJoint < 512, "not enough buffer to retarget, increase 512");

		int jointUsage[512];
		memset(&jointUsage[0], 0, sizeof(jointUsage));
		PEASSERT(skel.m_numJoints < 512, "need to increase buffer");
		if (version < 3) 
		{
			// no retargetting
			for (int i = 0; i < 512; ++i)
				animJointToSkelJoint[i] = i;
		}
		else
		{
			for (int i = 0; i < 512; ++i)
				animJointToSkelJoint[i] = -1;
			// fill in based on names of joints
			for (int iSrcJoint = 0; iSrcJoint < m_numJoints; ++iSrcJoint)
			{
				char fullJointName[256];
				f.nextNonEmptyLine(fullJointName, 256);
				// need find same joint in skel
				// need to strip out maya napesapce in case the rig was referenced in, in which case joint name will be something like mixamorig:Spine
				int pos = StringOps::lfind(fullJointName, ':');
				const char *jointName = fullJointName;
				if (pos != -1)
				{
					jointName = &fullJointName[pos+1];
				}
				for (int iSkelJoint = 0; iSkelJoint < targetSkelNumJoints; ++iSkelJoint)
				{
					FastJoint &fj = skel.m_fastJoints[iSkelJoint];
					if (StringOps::strcmp(fj.m_pJointCPU->m_name, jointName) == 0 || StringOps::strcmp(fj.m_pJointCPU->m_name, fullJointName) == 0)
					{
						animJointToSkelJoint[iSrcJoint] = iSkelJoint;
						break;
					}
				}
			}
		}

		PrimitiveTypes::Int32 numFrames;
		f.nextInt32(numFrames);
		m_frames.reset(numFrames);

		for (PrimitiveTypes::UInt32 iFrame = 0; iFrame < (PrimitiveTypes::UInt32)(numFrames); iFrame++)
		{
			m_frames.add(Array<TSQ>(*m_pContext, m_arena));
			Array<TSQ> &curFrame = m_frames[iFrame];
			curFrame.reset(targetSkelNumJoints);

			// fill in with default values
			for (int iJoint = 0; iJoint < targetSkelNumJoints; ++iJoint)
			{
				FastJoint &fj = skel.m_fastJoints[iJoint];
				Matrix4x4 parentMatrix;
				parentMatrix.loadIdentity();
				
				if (fj.m_parent)
				{
					float *mf = fj.m_parent->m_pJointCPU->m_matrix;
					int iFloat = 0;

					for (PrimitiveTypes::UInt32 row = 0; row < 4; row++)
					{
						for (PrimitiveTypes::UInt32 col = 0; col < 4; col++)
						{
							parentMatrix.m[col][row] = mf[iFloat++];

							// i dont think we need to multiply since we already have a full matrix from bind pose
							//m.setPos(m.getPos() * positionFactor);
						}
					}
				}
				Matrix4x4 m;
				float *mf = fj.m_pJointCPU->m_matrix;
				int iFloat = 0;

				for (PrimitiveTypes::UInt32 row = 0; row < 4; row++)
				{
					for (PrimitiveTypes::UInt32 col = 0; col < 4; col++)
					{
						m.m[col][row] = mf[iFloat++];

						// i dont think we need to multiply since we already have a full matrix from bind pose
						//m.setPos(m.getPos() * positionFactor);
					}
				}
				
				m = parentMatrix.inverse() * m;
				TSQ tsq(m); // this is experimental, not 100 sure it works properly
				curFrame.add(tsq);
			}

			// read the data in
			for (PrimitiveTypes::UInt32 iJoint = 0; iJoint < m_numJoints; iJoint++)
			{
				// read each frame == numJoints matrices
				int targetJoint = animJointToSkelJoint[iJoint]; // might be retargetting or skipping completely

				Matrix4x4 m;
				Vector3 scale(1.0f, 1.0f, 1.0f);
				if (version == 0)
				{
					for (PrimitiveTypes::UInt32 row = 0; row < 4; row++)
					{
						for (PrimitiveTypes::UInt32 col = 0; col < 4; col++)
						{
							PrimitiveTypes::Float32 val;
							f.nextFloat32(val);
							m.m[col][row] = val;
						}
					}
					scale = Vector3(1.f, 1.f, 1.f);
				}
				else if (version == 1 || version == 2 || version == 3)
				{
					// read translation, rotation, scale
					Vector3 pos;
					f.nextFloat32(pos.m_x); f.nextFloat32(pos.m_y); f.nextFloat32(pos.m_z);
					Matrix4x4 tm(pos);


					Matrix3x3 rm;

					if (version == 1)
					{
						Vector3 rot;
						f.nextFloat32(rot.m_x); f.nextFloat32(rot.m_y); f.nextFloat32(rot.m_z);
						rot *= -1.0f;
						rot *= (PrimitiveTypes::Constants::c_Pi_F32 / 180.0f);

						rm = Matrix3x3(Rotate, rot, RotateOrder_ZYX);
					}
					else
					{
						Quaternion q;
						f.nextFloat32(q.m_w); f.nextFloat32(q.m_x); f.nextFloat32(q.m_y); f.nextFloat32(q.m_z);
						rm = Matrix3x3(q);
					}

					if (iJoint == 0)
					{
						f.nextFloat32(scale.m_x); f.nextFloat32(scale.m_y); f.nextFloat32(scale.m_z);
					}
					else
					{
						Vector3 temp;
						f.nextFloat32(temp.m_x); f.nextFloat32(temp.m_y); f.nextFloat32(temp.m_z);
					}
					Matrix3x3 res3x3 = rm;
					Matrix4x4 res(res3x3, pos);
					m = res;
				}

				m.setPos(m.getPos() * positionFactor);

				TSQ tsq(m, scale);
				if (targetJoint != -1)
				{
					curFrame[targetJoint] = tsq;
					jointUsage[targetJoint]++;
				}
				else
					PEINFO("Skipping joint %d\n", iJoint);
			}
		}
	}
Пример #8
0
int Effect::l_SetSpeShaderData(lua_State *luaVM)
{
	GameContext *pContext = (GameContext*)(lua_touserdata(luaVM, -1));
	lua_pop(luaVM, 1);

	PrimitiveTypes::UInt32 size;

	lua_pushstring(luaVM, "size"); // 
	lua_gettable(luaVM, -2);
	size = (PrimitiveTypes::UInt32)(lua_tonumber(luaVM, -1));
	lua_pop(luaVM, 1); // pop size


	Array<float> vals(*pContext, MemoryArena_Client);
	vals.reset(size * (3+2));
	float *pcur = vals.getFirstPtr();

	int ival = 1; // start indices from 1
	for (PrimitiveTypes::UInt32 i = 0; i < size; ++i)
	{
		for (PrimitiveTypes::UInt32 j = 0; j < 3; ++j)
		{
			lua_pushnumber(luaVM, ival++); 
			lua_gettable(luaVM, -2); // 

			PrimitiveTypes::Float32 val = (PrimitiveTypes::Float32)(lua_tonumber(luaVM, -1));
			*pcur = val;
			pcur++;
			lua_pop(luaVM, 1); // pop value
		}

		*pcur = 100.0f;
		pcur++;
		*pcur = 100.0f;
		pcur++;
	}


	lua_pushstring(luaVM, "techName"); // 
	lua_gettable(luaVM, -2);
	const char * techName = lua_tostring(luaVM, -1);
	lua_pop(luaVM, 1); // pop techName

	Handle h = EffectManager::Instance()->getEffectHandle(techName);

	if (h.isValid())
	{
		Effect *pEffect = h.getObject<Effect>();
		void * dest = pEffect->m_speData.getObject();
		memcpy(dest, vals.getFirstPtr(), size * (3+2) * sizeof(float));
	}
	else
	{
		PEINFO("PE: ERROR: l_setSpeTechniqueReady() : provided technique does not exist!");
	}

	lua_pop(luaVM, 1); // pop the input table

	vals.reset(0);

	return 0;
}
Пример #9
0
static bool loadVertexShader_PSVita(PE::GameContext &ctx, const char *filename, const char *name,
	EPEVertexFormat format,
	Effect *pEffect,
	const SceGxmProgram *gxmProgram,
	SceGxmShaderPatcherId &out_programId,
	SceGxmVertexProgram *out_programs[]
	)
{
	PEString::generatePathname(ctx, filename, "Default", "GPUPrograms", PEString::s_buf, PEString::BUF_SIZE);

	PEINFO("PE: PROGRESS: loading shader: %s from %s\n", name, PEString::s_buf);

	if (strcmp("main", name))
	{
		assert(!"Only shaders programs with name \"main()\" are supported");
	}

	PSVitaRenderer *pPSVitaRenderer = static_cast<PSVitaRenderer *>(ctx.getGPUScreen());

	SceGxmErrorCode err = sceGxmShaderPatcherRegisterProgram(pPSVitaRenderer->m_shaderPatcher, gxmProgram, &out_programId);
	PEASSERT(err == SCE_OK, "Error creating shader patcher id");
	
	pEffect->m_externalPerTechniqueData.initVertexAttributeBindings(pEffect); // need these to assign to vertex buffer infos

	for (int iBufferLayout = 0; iBufferLayout < PEVertexFormatLayout_Count; ++iBufferLayout)
	{
		PEVertexBufferInfo &bufferLayoutInfo = VertexBufferGPUManager::Instance()->m_vertexBufferInfos[iBufferLayout];
		EPEVertexFormat iFormat = VertexBufferGPUManager::Instance()->m_layoutToFormatMap[iBufferLayout];
		if (format == iFormat)
		{
			for (int iAttr = 0; iAttr < bufferLayoutInfo.m_apiVertexAttributes.m_size; ++iAttr)
			{
				bufferLayoutInfo.m_apiVertexAttributes[iAttr].regIndex = -1;
			}

			// set bindings in buffers infos, by going through raw api-abstract data of buffer infos
			// and figuring out which binding to use for destination api info
			int iApiAttrIndex = 0;
			for (int iBuf = 0; iBuf < bufferLayoutInfo.m_bufferInfos.m_size; ++iBuf)
			{
				PEVertexAttributeBufferInfo &bufInfo = bufferLayoutInfo.m_bufferInfos[iBuf];
				for (int iSem = 0; iSem < bufInfo.m_numAttributes; ++iSem)
				{
					PEVertexAttributeInfo &attrInfo = bufInfo.m_attributeInfos[iSem];
					// this does something like
					// for detailed_mesh's vertex attribute position, in this shader position is bound result of to sceGxmProgramParameterGetResourceIndex
					
					GLSLAttributeLocations::ApiBindingType resBinding = sceGxmProgramFindParameterBySemantic(gxmProgram, (SceGxmParameterSemantic)(attrInfo.m_apiSemantic), attrInfo.m_apiSemanticOrder);
					PEASSERT(resBinding && (sceGxmProgramParameterGetCategory(resBinding) == SCE_GXM_PARAMETER_CATEGORY_ATTRIBUTE), "Problem finding vertex attribute");

					uint32_t regIndex = sceGxmProgramParameterGetResourceIndex(resBinding);
					PEASSERT(regIndex != -1, "Invalid Index\n");

					bufferLayoutInfo.m_apiVertexAttributes[iApiAttrIndex].regIndex = regIndex;
					

					++iApiAttrIndex;
				}
			}
			
			SceGxmVertexAttribute *pVertexAttribute = bufferLayoutInfo.m_apiVertexAttributes.getFirstPtr();
			int numVertexAttrs = bufferLayoutInfo.m_apiVertexAttributes.m_size;
			SceGxmVertexStream *pVertexStream = bufferLayoutInfo.m_apiVertexStreams.getFirstPtr();
			int numStreams = bufferLayoutInfo.m_apiVertexStreams.m_size;

			err = sceGxmShaderPatcherCreateVertexProgram(
				pPSVitaRenderer->m_shaderPatcher,
				out_programId,
				pVertexAttribute,
				numVertexAttrs,
				pVertexStream,
				numStreams,
				&out_programs[iBufferLayout]);
			checkErrCode(err);
			PEASSERT(err == SCE_OK, "Error creating shader");
		}
	}

	return true;
}
Пример #10
0
void Effect::loadTechniqueSync_PSVita()
{
	lock();
    
    PSVitaRenderer *pPSVitaRenderer = static_cast<PSVitaRenderer *>(m_pContext->getGPUScreen());
    
	if (StringOps::length(m_spesFilename)){return;}
	if (StringOps::length(m_gsFilename)){return;}
	if (StringOps::length(m_csFilename)){return;}

	//D3DXMACRO Shader_Macros[3] = { {"HLSL_SEPARATE_LOAD", "1"} , {"APIABSTRACTION_D3D9", "1"} , {0, 0}};
	if (StringOps::length(m_vsFilename))
	{
		PEString::generatePathname(*m_pContext, m_vsFilename, "Default", "GPUPrograms", PEString::s_buf, PEString::BUF_SIZE);
		FileReader f(PEString::s_buf);
		char *data = NULL;
		PrimitiveTypes::UInt32 size;
		f.readIntoBuffer(data, size);
		m_pBasicVertexProgramGxp = (SceGxmProgram*)data;
	}

	if (StringOps::length(m_psFilename))
	{
		/* todo: don't compile pixel shaders
        int existingIndex = EffectManager::Instance()->m_pixelShaders.findIndex(m_psName);
         
        if (existingIndex != -1)
		{
			pPixelShader = EffectManager::Instance()->m_pixelShaders.m_pairs[existingIndex];
		}
		else
		*/
		{
			PEString::generatePathname(*m_pContext, m_psFilename, "Default", "GPUPrograms", PEString::s_buf, PEString::BUF_SIZE);
			FileReader f(PEString::s_buf);
			char *data = NULL;
			PrimitiveTypes::UInt32 size;
			f.readIntoBuffer(data, size);
			m_pBasicFragmentProgramGxp = (SceGxmProgram*)data;
			SceGxmErrorCode gxmErrorCode = sceGxmProgramCheck(m_pBasicFragmentProgramGxp);
			switch(gxmErrorCode)
			{
			case SCE_OK: PEINFO("sceGxmProgramCheck() : OK\n"); break;
			case SCE_GXM_ERROR_INVALID_POINTER: PEINFO("sceGxmProgramCheck() : SCE_GXM_ERROR_INVALID_POINTER\n"); break;
			case SCE_GXM_ERROR_INVALID_VALUE: PEINFO("sceGxmProgramCheck() : SCE_GXM_ERROR_INVALID_VALUE\n"); break;
			}
			PEASSERT(gxmErrorCode == SCE_OK, "check failed\n");

			gxmErrorCode = sceGxmProgramCheck(m_pBasicVertexProgramGxp);
			switch(gxmErrorCode)
			{
			case SCE_OK: PEINFO("sceGxmProgramCheck() : OK\n"); break;
			case SCE_GXM_ERROR_INVALID_POINTER: PEINFO("sceGxmProgramCheck() : SCE_GXM_ERROR_INVALID_POINTER\n");break;
			case SCE_GXM_ERROR_INVALID_VALUE: PEINFO("sceGxmProgramCheck() : SCE_GXM_ERROR_INVALID_VALUE\n");break;
			}
			PEASSERT(gxmErrorCode == SCE_OK, "check failed\n");

			if (!loadFragmentShader_PSVita(*m_pContext, m_psFilename, m_psName,
				m_pBlendState,
				m_pBasicFragmentProgramGxp,
				m_pBasicVertexProgramGxp,
				m_basicFragmentProgramId,
				m_basicFragmentProgram
				)) 
			{
				assert(!"Could not compile fragment program");
				unlock();
				return;
			}
		}
	}

	if (m_pBasicVertexProgramGxp)
	{
		if (!loadVertexShader_PSVita(*m_pContext, m_vsFilename, m_vsName,
			m_vsVertexFormat,
			this,
			m_pBasicVertexProgramGxp,
			m_basicVertexProgramId,
			m_basicVertexProgram
			))
		{
			assert(!"Could not compile vertex program");
			unlock();
			return;
		}
	}

	m_externalPerTechniqueData.init(this);

	m_isReady = true;
	unlock();
}