Пример #1
0
std::vector<gmtl::Point2f> uvPoints(int nm, int np)
{
	GLfloat u, v;
	std::vector<gmtl::Point2f> _uvs;
	for (int i = 0; i <= nm; i++) //nm = 4
	{
		for (int j = 0; j < np;) //np = 4
		{

			u = (GLfloat)i / (GLfloat)nm;
			v = (GLfloat)j / (GLfloat)(np);
			//std::cout << "[" << i << "," << j << "]";
			//std::cout << "[u:" << u << "v:" << v << "]" << std::endl;
			gmtl::Point2f uv(u, v);
			_uvs.push_back(uv);
			j++;
		}
	}
	return _uvs;
}
Пример #2
0
//*************************************************************************************************************
void DrawScene(LPD3DXEFFECT effect)
{
	D3DXMATRIX	world;
	D3DXMATRIX	inv;
	D3DXVECTOR4	uv(3, 3, 0, 0);

	D3DXMatrixScaling(&world, 5, 0.1f, 5);
	D3DXMatrixInverse(&inv, NULL, &world);

	effect->SetMatrix("matWorld", &world);
	effect->SetMatrix("matWorldInv", &inv);
	effect->SetVector("uv", &uv);

	effect->Begin(0, 0);
	effect->BeginPass(0);
	{
		device->SetTexture(0, texture2);
		shadowreceiver->DrawSubset(0);

		if( !drawsilhouette )
		{
			device->SetTexture(0, texture1);

			uv.x = uv.y = 1;
			effect->SetVector("uv", &uv);

			for( int i = 0; i < NUM_OBJECTS; ++i )
			{
				D3DXMatrixInverse(&inv, NULL, &objects[i].world);

				effect->SetMatrix("matWorld", &objects[i].world);
				effect->SetMatrix("matWorldInv", &inv);
				effect->CommitChanges();

				objects[i].object->DrawSubset(0);
			}
		}
	}
	effect->EndPass();
	effect->End();
}
Пример #3
0
void MeshCube::init( uint flags )
{
	fl = flags;
	for ( int i = 0; i < 8*3; i++ )
	{
		uint si = i % 8;
		uint face = i / 8;
		uint normalface = i / 4;

		glm::vec3 pos(cubeVerts[si * 3 + 0],
			cubeVerts[si * 3 + 1],
			cubeVerts[si * 3 + 2]);
		glm::vec3 color(1, 0, 1);
		glm::vec3 normal(0, 0, 0);
		glm::vec2 uv(0,0);

		addVertex(flags, pos, color, normal, uv);
	}

	for ( int i = 0; i < 12; i++ )
	{
		uint face = i / 4;

		addIndex(cubeInds[i * 3 + 0] + face * 8,
			cubeInds[i * 3 + 1] + face * 8,
			cubeInds[i * 3 + 2] + face * 8);
	}

	stepSize = 0;
	if ( flags & BUF_POS )
		stepSize += 3;
	if ( flags & BUF_COLOR )
		stepSize += 3;
	if ( flags & BUF_NORMAL )
		stepSize += 3;
	if ( flags & BUF_UV )
		stepSize += 2;

	if ( flags & BUF_NORMAL )
		calcNormals( );
}
Пример #4
0
void Game::draw() {
	glClearDepth(1.0);
	//Clear the colour and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	_colourProgram.use();
	glActiveTexture(GL_TEXTURE0);
	GLint textureLocation = _colourProgram.getUniformLocation("mySampler");
	glUniform1i(textureLocation, 0);


	GLuint timeLocation = _colourProgram.getUniformLocation("time");
	glUniform1f(timeLocation, _time);

	//Set the camera matrix
	GLuint pLocation = _colourProgram.getUniformLocation("P");
	glm::mat4 camMatrix = _cam.getCamMatrix();
	glUniformMatrix4fv(pLocation, 1, GL_FALSE, &(camMatrix[0][0]));

	_spriteBatch.begin();

	glm::vec4 pos(0.0f, 0.0f, 50.0f, 50.0f);
	glm::vec4 uv(0.0f, 0.0f, 1.0f, 1.0f);
	static OGLEng::GLTexture texture = OGLEng::ResourceManager::getTexture("Textures/PNG/CharacterRight_Standing.png");
	OGLEng::Colour colour;
	colour.r = 255;
	colour.g = 255;
	colour.b = 255;
	colour.a = 255;
	_spriteBatch.draw(pos, uv, texture.id, 0.0f, colour);

	_spriteBatch.end();
	_spriteBatch.renderBatch();

	glBindTexture(GL_TEXTURE_2D, 0);

	/// Disable the shader
	_colourProgram.unuse();

	_window.swapBuffer();
}
Пример #5
0
void Doc_plugin_interface::addImage(int handle, QPointF *start, QPointF *uvr, QPointF *vvr,
                                    int w, int h, QString name, int br, int con, int fade){
    RS_Vector ip(start->x(), start->y());
    RS_Vector uv(uvr->x(), uvr->y());
    RS_Vector vv(vvr->x(), vvr->y());
    RS_Vector size(w, h);

    RS_Image* image =
        new RS_Image(
            doc,
            RS_ImageData(handle /*QString(data.ref.c_str()).toInt(NULL, 16)*/,
                         ip, uv, vv,
                         size,
                         name,
                         br,
                         con,
                         fade));

//    setEntityAttributes(image, attributes);
    doc->addEntity(image);
}
Moo::DynamicVertexBuffer< Moo::VertexTUV >& ShimmerMesh::create( const Vector2& tl, const Vector2& dim, const Vector2& uvDimensions )
{
	Moo::DynamicVertexBuffer< Moo::VertexTUV >& vb = Moo::DynamicVertexBuffer< Moo::VertexTUV >::instance();
	Moo::VertexTUV* pVerts = vb.lock( nVerts_ );

	float xPosStep = dim[0] / xDivisor_;
	float xUVStep = uvDimensions[0] / xDivisor_;

	float yPosStep = float( dim[1] ) / yDivisor_;
	float yUVStep = float ( uvDimensions[1] ) / yDivisor_;

	float slowFactor = powf( 2.f, s_shimmerPower );

	Vector2 pos( tl );
	Vector2 uv( 0.f, 0.f );
	for (int y = 0; y < nVertsY_; y++)
	{
		pos[0] = tl[0];
		uv[0] = 0.f;

		for (int x = 0; x < nVertsX_; x++)
		{
			pVerts->pos_.set( pos[0], pos[1], 0, 1 );
			float t = (float)::GetTickCount();
			t /= slowFactor;
			pVerts->uv_.set( uv[0], uv[1] + ( cosf(t+(float)y) * s_shimmerSpread ) );

			pos[0] += xPosStep;
			uv[0] += xUVStep;

			pVerts++;
		}

		pos[1] += yPosStep;
		uv[1] += yUVStep;
	}
	vb.unlock();

	return vb;
}
Пример #7
0
void getUVFromConnectedTexturePlacementNode(MObject fileTextureNode, float inU, float inV, float& outU, float& outV)
{
	MObject texPlaceObj = getConnectedInNode(fileTextureNode, "uvCoord");
	outU = inU;
	outV = outV;
	if( texPlaceObj == MObject::kNullObj )
		return;

	double offsetU = 0.0;
	double offsetV = 0.0;

	MFnDependencyNode texPlaceNode(texPlaceObj);
	getDouble(MString("offsetU"), texPlaceNode, offsetU);
	getDouble(MString("offsetV"), texPlaceNode, offsetV);
	float repeatU = 1.0f, repeatV = 1.0f, rotateUV = 0.0f;
	getFloat("repeatU",  texPlaceNode, repeatU);
	getFloat("repeatV",  texPlaceNode, repeatV);
	getFloat("rotateUV",  texPlaceNode, rotateUV);

	MMatrix rotationMatrix;
	rotationMatrix.setToIdentity();
	rotationMatrix[0][0] =  cos(rotateUV) * repeatU;
	rotationMatrix[1][0] = -sin(rotateUV) * repeatU;
	rotationMatrix[0][1] =  sin(rotateUV) * repeatV;
	rotationMatrix[1][1] =  cos(rotateUV) * repeatV;

	MVector uv(inU - 0.5, inV - 0.5, 0.0);
	uv = uv * rotationMatrix;
	uv.x += 0.5;
	uv.y += 0.5;

	uv.x *= repeatU;
	uv.y *= repeatV;

	uv.x += offsetU;
	uv.y += offsetV;

	outU = uv.x;
	outV = uv.y;
}
Пример #8
0
glm::vec2 Sphere::GetUVCoordinates(const glm::vec3 &point)
{
   glm::vec3 p = glm::normalize(point);

   bool is_top = fequal(p.x, 0.f) && fequal(p.z, 0.f);

   if (is_top)
   {
       if (p.y >= 0)
        return glm::vec2(.5f, 0.f);
       else return glm::vec2(.5f, 1.f);
   }


   float phi = std::atan2(p.z, p.x);
   if (phi < 0) phi += TWO_PI;
   float theta = glm::acos(p.y); //map y to (-1, 1)

   glm::vec2 uv( 1 - phi / TWO_PI, 1 - theta / PI);

   return uv;
}
Пример #9
0
void MainGame::drawGame(){
	
	glClearDepth(1.0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	_colorProgram.use();

	glActiveTexture(GL_TEXTURE0);
	GLint textureLocation = _colorProgram.getUniformLocation("mySampler");
	glUniform1i(textureLocation, 0);

	GLuint pLocation = _colorProgram.getUniformLocation("P");
	glm::mat4 cameraMatrix = _camera.getCameraMatrix();
	glUniformMatrix4fv(pLocation, 1, GL_FALSE, &(cameraMatrix[0][0]));

	_spriteBatch.begin();

	glm::vec4 pos(0.0f, 0.0f, 50.0f, 50.0f);
	glm::vec4 uv(0.0f, 0.0f, 1.0f, 1.0f);
	static Snap::GLTexture texture = Snap::ResourceManager::getTexture("textures/jimmyJump_pack/PNG/CharacterRight_Standing.png");
	Snap::ColorRGBA8 ColorRGBA8;
	ColorRGBA8.r = 255;
	ColorRGBA8.g = 255;
	ColorRGBA8.b = 255;
	ColorRGBA8.a = 255;

	_spriteBatch.draw(pos, uv, texture.id, 0.0f, ColorRGBA8);

	for (int i = 0; i < _bullets.size(); i++) {
		_bullets[i].draw(_spriteBatch);
	}
	_spriteBatch.end();
	_spriteBatch.renderBatch();

	glBindTexture(GL_TEXTURE_2D, 0);
	_colorProgram.unuse();

	_window.swapBuffer();
}
Пример #10
0
	bool DeinterleaveUvAutoTest(int width, int height, const Func & f1, const Func & f2)
	{
		bool result = true;

		TEST_LOG_SS(Info, "Test " << f1.description << " & " << f2.description << " [" << width << ", " << height << "].");

		View uv(width, height, View::Uv16, NULL, TEST_ALIGN(width));
		FillRandom(uv);

		View u1(width, height, View::Gray8, NULL, TEST_ALIGN(width));
		View v1(width, height, View::Gray8, NULL, TEST_ALIGN(width));
		View u2(width, height, View::Gray8, NULL, TEST_ALIGN(width));
		View v2(width, height, View::Gray8, NULL, TEST_ALIGN(width));

		TEST_EXECUTE_AT_LEAST_MIN_TIME(f1.Call(uv, u1, v1));

		TEST_EXECUTE_AT_LEAST_MIN_TIME(f2.Call(uv, u2, v2));

		result = result && Compare(u1, u2, 0, true, 32);
		result = result && Compare(v1, v2, 0, true, 32);

		return result;
	}
Пример #11
0
  void buildMesh(Vertex vertex, Index index, size_t firstIndex=0, int numVSegments=8) {
    if (controlPoints_.size() < 4) return;

    std::vector<glm::vec3> subdivPoints((controlPoints_.size()-2) * numYSegments + 1);
    int numSegs = int(controlPoints_.size());
    size_t numVertices = 0;
    glm::vec3 normal(0, 0, 1);
    for (int seg = 0; seg < numSegs-3; ++seg) {
      for (int vseg = 0; vseg != numVSegments; ++vseg) {
        float t = vseg * (1.0f/numVSegments);
        glm::vec2 uv(0, float(seg) + v);
        glm::vec3 pos = evaluate(seg, t);
        vertex(pos, uv, normal);
        numVertices++;
      }
    }
    vertex(controlPoints_[numSegs-1], glm::vec2(0, float(numSegs-3)), normal);
    numVertices++;

    for (size_t i = 0; i != numVertices; ++i) {
      index(firstIndex + i);
    }
  }
Пример #12
0
void Level::init(const std::string filePath, GamaGameEngine::PhysicsWorld* world) {
	glClearDepth(1.0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	m_startPlayerPos.x = -100;
	m_startPlayerPos.y = -100;

	m_spriteBatch.init();
	m_spriteBatch.begin();

	glm::vec4 posAndSize(-420.0f, -226.0f, 7688, 384);
	glm::vec4 uv(0.0f, 0.0f, 1.0f, 1.0f);
	static GamaGameEngine::GLTexture texture = GamaGameEngine::ResourceManager::getTexture(filePath);
	GamaGameEngine::Colour colour;
	colour.r = 255;
	colour.g = 255;
	colour.b = 255;
	colour.a = 255;
	m_border.init(world, glm::vec2(3700.0f, 30.0f),glm::vec2(7400.0f, 5.0f), 0.0f, false);
	m_border.m_body->setStatic();
	m_border.init(world, glm::vec2(3700.0f, -220.0f), glm::vec2(7400.0f, 5.0f), 0.0f, false);
	m_border.m_body->setStatic();
	m_border.init(world, glm::vec2(-400.0f, 0.0f), glm::vec2(5.0f, 500.0f), 0.0f, false);
	m_border.m_body->setStatic();
	m_border.init(world, glm::vec2(7265.0f, 0.0f), glm::vec2(5.0f, 500.0f), 0.0f, false);
	m_border.m_body->setStatic();

	m_spriteBatch.addSprite(posAndSize, uv, texture.id, 0.0f, colour);

	m_spriteBatch.end();

	draw();

	//glBindTexture(GL_TEXTURE_2D, 0);

	//m_window.swapBuffer();
}
///dim is the output dimensions
Moo::DynamicVertexBuffer< Moo::VertexTUV >&
DistortionMesh::create( const Vector2& tl, const Vector2& dim, const Vector2& uvDimensions )
{
	Moo::DynamicVertexBuffer< Moo::VertexTUV >& vb = Moo::DynamicVertexBuffer< Moo::VertexTUV >::instance();
	Moo::VertexTUV* pVerts = vb.lock( nVerts_ );

	float xPosStep = dim[0] / xDivisor_;
	float xUVStep = uvDimensions[0] / xDivisor_;

	float yPosStep = float( dim[1] ) / yDivisor_;
	float yUVStep = float ( uvDimensions[1] ) / yDivisor_;

	Vector2 pos( tl );
	Vector2 uv( 0.f, 0.f );
	for (int y = 0; y < nVertsY_; y++)
	{
		pos[0] = tl[0];
		uv[0] = 0.f;

		for (int x = 0; x < nVertsX_; x++)
		{
			pVerts->pos_.set( pos[0], pos[1], 0, 1 );
			pVerts->uv_.set( uv[0], uv[1] );

			pos[0] += xPosStep;
			uv[0] += xUVStep;

			pVerts++;
		}

		pos[1] += yPosStep;
		uv[1] += yUVStep;
	}
	vb.unlock();

	return vb;
}
Пример #14
0
// Vertex Mapping, We use it in association with VMADs, see WriteDiscVertexMapping below
bool CLwoWriter::WriteVertexMapping()
{
	CLwoFile::CLayer::TexCoordMap& texCoords = m_curLayer.GetTexCoordMap();
	if(texCoords.size() == 0)
		return true;

	MSG_DEBUG("VMAP | TXUV");

	// "VMAP" + size
	WriteChunk(CLwoFile::CHUNK_VMAP);

	// type : "TXUV"
	WriteTag(CLwoFile::CHUNK_TXUV);

	ushort dimension = 2; // UVs are 2D
	WriteShort(dimension);

	std::string name("txuv00");
	WriteString(name);

	CLwoFile::CLayer::TexCoordMap::iterator texCoordIt, texCoordEnd;
	texCoordEnd = texCoords.end();

	ushort pointIndex;
	Vector3D uv(3);

	for(texCoordIt = texCoords.begin(); texCoordIt != texCoordEnd; ++texCoordIt) // For each LWO texCoord
	{
		pointIndex = texCoordIt->first;
		WriteShort(pointIndex); // vertex position index

		uv = (texCoordIt->second)[0].m_texCoord; // Retreive the first UV coordinate for this control point (the one assigned to the first face)
		WriteVector2D(uv); // Write UV
	}

	return true;
}
Пример #15
0
void Homura::draw(Bengine::SpriteBatch& spriteBatch){

	//draw the mana bar -----------------------------------------------------------------------------------------------------------------
	static Bengine::GLTexture manaBarBG = Bengine::ResourceManager::getTexture("Textures/Character/manaBarBG.png");
	static Bengine::GLTexture manaBarTick = Bengine::ResourceManager::getTexture("Textures/Character/manaBarTick.png");
	static Bengine::GLTexture manaBarFrame = Bengine::ResourceManager::getTexture("Textures/Character/manaBarFrame.png");
	glm::vec4 uv(0.0f, 0.0f, 1.0f, 1.0f);

	if (_alive)
	{
		spriteBatch.draw(glm::vec4(_body->GetPosition().x * TheMainGame::Instance()->_camera.getScreenDimensions().x / 32,
			_body->GetPosition().y * TheMainGame::Instance()->_camera.getScreenDimensions().y / 18 + TheMainGame::Instance()->_camera.getScreenDimensions().y / 18,
			TheMainGame::Instance()->_camera.getScreenDimensions().x / 16.7320261438, TheMainGame::Instance()->_camera.getScreenDimensions().y / 36), 0.0f, uv, manaBarBG.id, 0.0f, color);

		for (int i = 0; i < _mana; i++)
		{
			spriteBatch.draw(glm::vec4(_body->GetPosition().x * TheMainGame::Instance()->_camera.getScreenDimensions().x / 32 - TheMainGame::Instance()->_camera.getScreenDimensions().x / 34.1333333333 + (TheMainGame::Instance()->_camera.getScreenDimensions().x / 1706.66666667 * i),
				_body->GetPosition().y * TheMainGame::Instance()->_camera.getScreenDimensions().y / 18 + TheMainGame::Instance()->_camera.getScreenDimensions().y / 18,
				TheMainGame::Instance()->_camera.getScreenDimensions().x / 1706.66666667, TheMainGame::Instance()->_camera.getScreenDimensions().y / 36), 0.0f, uv, manaBarTick.id, 0.0f, color);
		}

		spriteBatch.draw(glm::vec4(_body->GetPosition().x * TheMainGame::Instance()->_camera.getScreenDimensions().x / 32,
			_body->GetPosition().y * TheMainGame::Instance()->_camera.getScreenDimensions().y / 18 + TheMainGame::Instance()->_camera.getScreenDimensions().y / 18,
			TheMainGame::Instance()->_camera.getScreenDimensions().x / 16.7320261438, TheMainGame::Instance()->_camera.getScreenDimensions().y / 36), 0.0f, uv, manaBarFrame.id, 0.0f, color);

		//---------------------------------------------------------------------------------------------------------------------

		_manaShield->draw(spriteBatch, _body->GetPosition().x, _body->GetPosition().y);
		_currentState->draw(spriteBatch, _body);
		_mainWeaponState->draw(spriteBatch, _body->GetPosition().x, _body->GetPosition().y);
	}




}
Пример #16
0
    void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
        const GrDistanceFieldLCDTextGeoProc& dfTexEffect =
                args.fGP.cast<GrDistanceFieldLCDTextGeoProc>();

        GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
        GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
        GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;

        // emit attributes
        varyingHandler->emitAttributes(dfTexEffect);

        GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;

        // setup pass through color
        if (!dfTexEffect.colorIgnored()) {
            varyingHandler->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor);
        }

        // Setup position
        this->setupPosition(vertBuilder,
                            uniformHandler,
                            gpArgs,
                            dfTexEffect.inPosition()->fName,
                            dfTexEffect.viewMatrix(),
                            &fViewMatrixUniform);

        // emit transforms
        this->emitTransforms(vertBuilder,
                             varyingHandler,
                             uniformHandler,
                             gpArgs->fPositionVar,
                             dfTexEffect.inPosition()->fName,
                             args.fTransformsIn,
                             args.fTransformsOut);

        // set up varyings
        bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask) ==
                              kUniformScale_DistanceFieldEffectMask;
        bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag);
        GrGLSLVertToFrag recipScale(kFloat_GrSLType);
        GrGLSLVertToFrag uv(kVec2f_GrSLType);
        varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
        vertBuilder->codeAppendf("%s = %s;", uv.vsOut(), dfTexEffect.inTextureCoords()->fName);

        // compute numbers to be hardcoded to convert texture coordinates from float to int
        SkASSERT(dfTexEffect.numTextures() == 1);
        GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture();
        SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()));

        GrGLSLVertToFrag st(kVec2f_GrSLType);
        varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
        vertBuilder->codeAppendf("%s = vec2(%d, %d) * %s;", st.vsOut(),
                                 atlas->width(), atlas->height(),
                                 dfTexEffect.inTextureCoords()->fName);

        // add frag shader code

        SkAssertResult(fragBuilder->enableFeature(
                GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));

        // create LCD offset adjusted by inverse of transform
        // Use highp to work around aliasing issues
        fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(args.fGLSLCaps,
                                                                 kHigh_GrSLPrecision));
        fragBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());
        fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(args.fGLSLCaps,
                                                                 kHigh_GrSLPrecision));

        SkScalar lcdDelta = 1.0f / (3.0f * atlas->width());
        if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) {
            fragBuilder->codeAppendf("float delta = -%.*f;\n", SK_FLT_DECIMAL_DIG, lcdDelta);
        } else {
            fragBuilder->codeAppendf("float delta = %.*f;\n", SK_FLT_DECIMAL_DIG, lcdDelta);
        }
        if (isUniformScale) {
            fragBuilder->codeAppendf("float st_grad_len = abs(dFdy(%s.y));", st.fsIn());
            fragBuilder->codeAppend("vec2 offset = vec2(st_grad_len*delta, 0.0);");
        } else if (isSimilarity) {
            // For a similarity matrix with rotation, the gradient will not be aligned
            // with the texel coordinate axes, so we need to calculate it.
            // We use dFdy because of a Mali 400 bug, and rotate -90 degrees to
            // get the gradient in the x direction.
            fragBuilder->codeAppendf("vec2 st_grad = dFdy(%s);", st.fsIn());
            fragBuilder->codeAppend("float st_grad_len = length(st_grad);");
            fragBuilder->codeAppend("vec2 offset = delta*vec2(st_grad.y, -st_grad.x);");
        } else {
            fragBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn());

            fragBuilder->codeAppend("vec2 Jdx = dFdx(st);");
            fragBuilder->codeAppend("vec2 Jdy = dFdy(st);");
            fragBuilder->codeAppend("vec2 offset = delta*Jdx;");
        }

        // green is distance to uv center
        fragBuilder->codeAppend("\tvec4 texColor = ");
        fragBuilder->appendTextureLookup(args.fSamplers[0], "uv", kVec2f_GrSLType);
        fragBuilder->codeAppend(";\n");
        fragBuilder->codeAppend("\tvec3 distance;\n");
        fragBuilder->codeAppend("\tdistance.y = texColor.r;\n");
        // red is distance to left offset
        fragBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n");
        fragBuilder->codeAppend("\ttexColor = ");
        fragBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType);
        fragBuilder->codeAppend(";\n");
        fragBuilder->codeAppend("\tdistance.x = texColor.r;\n");
        // blue is distance to right offset
        fragBuilder->codeAppend("\tuv_adjusted = uv + offset;\n");
        fragBuilder->codeAppend("\ttexColor = ");
        fragBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType);
        fragBuilder->codeAppend(";\n");
        fragBuilder->codeAppend("\tdistance.z = texColor.r;\n");

        fragBuilder->codeAppend("\tdistance = "
           "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceFieldThreshold"));");

        // adjust width based on gamma
        const char* distanceAdjustUniName = nullptr;
        fDistanceAdjustUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
                                                        kVec3f_GrSLType, kDefault_GrSLPrecision,
                                                        "DistanceAdjust", &distanceAdjustUniName);
        fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName);

        // To be strictly correct, we should compute the anti-aliasing factor separately
        // for each color component. However, this is only important when using perspective
        // transformations, and even then using a single factor seems like a reasonable
        // trade-off between quality and speed.
        fragBuilder->codeAppend("float afwidth;");
        if (isSimilarity) {
            // For similarity transform (uniform scale-only is a subset of this), we adjust for the 
            // effect of the transformation on the distance by using the length of the gradient of 
            // the texture coordinates. We use st coordinates to ensure we're mapping 1:1 from texel
            // space to pixel space.

            // this gives us a smooth step across approximately one fragment
            fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*st_grad_len;");
        } else {
            // For general transforms, to determine the amount of correction we multiply a unit
            // vector pointing along the SDF gradient direction by the Jacobian of the st coords
            // (which is the inverse transform for this fragment) and take the length of the result.
            fragBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance.r), dFdy(distance.r));");
            // the length of the gradient may be 0, so we need to check for this
            // this also compensates for the Adreno, which likes to drop tiles on division by 0
            fragBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);");
            fragBuilder->codeAppend("if (dg_len2 < 0.0001) {");
            fragBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
            fragBuilder->codeAppend("} else {");
            fragBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
            fragBuilder->codeAppend("}");
            fragBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
            fragBuilder->codeAppend("                 dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");

            // this gives us a smooth step across approximately one fragment
            fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
        }

        fragBuilder->codeAppend(
                      "vec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), distance), 1.0);");
        // set alpha to be max of rgb coverage
        fragBuilder->codeAppend("val.a = max(max(val.r, val.g), val.b);");

        fragBuilder->codeAppendf("%s = val;", args.fOutputCoverage);
    }
Пример #17
0
        void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
            const PLSQuadEdgeEffect& qe = args.fGP.cast<PLSQuadEdgeEffect>();
            GrGLSLVertexBuilder* vsBuilder = args.fVertBuilder;
            GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
            GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;

            // emit attributes
            varyingHandler->emitAttributes(qe);

            GrGLSLVertToFrag uv(kVec2f_GrSLType);
            varyingHandler->addVarying("uv", &uv, kHigh_GrSLPrecision);
            vsBuilder->codeAppendf("%s = %s;", uv.vsOut(), qe.inUV()->fName);

            GrGLSLVertToFrag ep1(kVec2f_GrSLType);
            varyingHandler->addVarying("endpoint1", &ep1, kHigh_GrSLPrecision);
            vsBuilder->codeAppendf("%s = vec2(%s.x, %s.y);", ep1.vsOut(), 
                                  qe.inEndpoint1()->fName, qe.inEndpoint1()->fName);

            GrGLSLVertToFrag ep2(kVec2f_GrSLType);
            varyingHandler->addVarying("endpoint2", &ep2, kHigh_GrSLPrecision);
            vsBuilder->codeAppendf("%s = vec2(%s.x, %s.y);", ep2.vsOut(), 
                                  qe.inEndpoint2()->fName, qe.inEndpoint2()->fName);

            GrGLSLVertToFrag delta(kVec2f_GrSLType);
            varyingHandler->addVarying("delta", &delta, kHigh_GrSLPrecision);
            vsBuilder->codeAppendf("%s = vec2(%s.x - %s.x, %s.y - %s.y) * 0.5;", 
                                   delta.vsOut(), ep1.vsOut(), ep2.vsOut(), ep2.vsOut(), 
                                   ep1.vsOut());

            GrGLSLVertToFrag windings(kInt_GrSLType);
            varyingHandler->addFlatVarying("windings", &windings, kLow_GrSLPrecision);
            vsBuilder->codeAppendf("%s = %s;", 
                                   windings.vsOut(), qe.inWindings()->fName);

            // Setup position
            this->setupPosition(vsBuilder, gpArgs, qe.inPosition()->fName);

            // emit transforms
            this->emitTransforms(vsBuilder, varyingHandler, uniformHandler, gpArgs->fPositionVar, 
                                 qe.inPosition()->fName, qe.localMatrix(), args.fTransformsIn, 
                                 args.fTransformsOut);

            GrGLSLFragmentBuilder* fsBuilder = args.fFragBuilder;
            SkAssertResult(fsBuilder->enableFeature(
                           GrGLSLFragmentShaderBuilder::kPixelLocalStorage_GLSLFeature));
            SkAssertResult(fsBuilder->enableFeature(
                    GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
            static const int QUAD_ARGS = 2;
            GrGLSLShaderVar inQuadArgs[QUAD_ARGS] = {
                GrGLSLShaderVar("dot", kFloat_GrSLType, 0, kHigh_GrSLPrecision),
                GrGLSLShaderVar("uv", kVec2f_GrSLType, 0, kHigh_GrSLPrecision)
            };
            SkString inQuadName;

            const char* inQuadCode = "if (uv.x * uv.x <= uv.y) {"
                                     "return dot >= 0.0;"
                                     "} else {"
                                     "return false;"
                                     "}";
            fsBuilder->emitFunction(kBool_GrSLType, "in_quad", QUAD_ARGS, inQuadArgs, inQuadCode, 
                                    &inQuadName);
            fsBuilder->declAppendf(GR_GL_PLS_PATH_DATA_DECL);
            // keep the derivative instructions outside the conditional
            fsBuilder->codeAppendf("highp vec2 uvdX = dFdx(%s);", uv.fsIn());
            fsBuilder->codeAppendf("highp vec2 uvdY = dFdy(%s);", uv.fsIn());
            fsBuilder->codeAppend("highp vec2 uvIncX = uvdX * 0.45 + uvdY * -0.1;");
            fsBuilder->codeAppend("highp vec2 uvIncY = uvdX * 0.1 + uvdY * 0.55;");
            fsBuilder->codeAppendf("highp vec2 uv = %s.xy - uvdX * 0.35 - uvdY * 0.25;", 
                                   uv.fsIn());
            fsBuilder->codeAppendf("highp vec2 firstSample = %s.xy - vec2(0.25);",
                                   fsBuilder->fragmentPosition());
            fsBuilder->codeAppendf("highp float d = dot(%s, (firstSample - %s).yx) * 2.0;", 
                                   delta.fsIn(), ep1.fsIn());
            fsBuilder->codeAppendf("pls.windings[0] += %s(d, uv) ? %s : 0;", inQuadName.c_str(), 
                                   windings.fsIn());
            fsBuilder->codeAppend("uv += uvIncX;");
            fsBuilder->codeAppendf("d += %s.x;", delta.fsIn());
            fsBuilder->codeAppendf("pls.windings[1] += %s(d, uv) ? %s : 0;", inQuadName.c_str(), 
                                   windings.fsIn());
            fsBuilder->codeAppend("uv += uvIncY;");
            fsBuilder->codeAppendf("d += %s.y;", delta.fsIn());
            fsBuilder->codeAppendf("pls.windings[2] += %s(d, uv) ? %s : 0;", inQuadName.c_str(), 
                                   windings.fsIn());
            fsBuilder->codeAppend("uv -= uvIncX;");
            fsBuilder->codeAppendf("d -= %s.x;", delta.fsIn());
            fsBuilder->codeAppendf("pls.windings[3] += %s(d, uv) ? %s : 0;", inQuadName.c_str(), 
                                   windings.fsIn());
        }
Пример #18
0
v3 v3::Unit(){
    v3 uv (x, y, z);
    return uv.Scale(1.0 / Magnitude());
}
Пример #19
0
    void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
        const GrDistanceFieldA8TextGeoProc& dfTexEffect =
                args.fGP.cast<GrDistanceFieldA8TextGeoProc>();
        GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
        SkAssertResult(fragBuilder->enableFeature(
                GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));

        GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
        GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
        GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;

        // emit attributes
        varyingHandler->emitAttributes(dfTexEffect);

#ifdef SK_GAMMA_APPLY_TO_A8
        // adjust based on gamma
        const char* distanceAdjustUniName = nullptr;
        // width, height, 1/(3*width)
        fDistanceAdjustUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
                                                        kFloat_GrSLType, kDefault_GrSLPrecision,
                                                        "DistanceAdjust", &distanceAdjustUniName);
#endif

        // Setup pass through color
        if (!dfTexEffect.colorIgnored()) {
            varyingHandler->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor);
        }

        // Setup position
        this->setupPosition(vertBuilder,
                            uniformHandler,
                            gpArgs,
                            dfTexEffect.inPosition()->fName,
                            dfTexEffect.viewMatrix(),
                            &fViewMatrixUniform);

        // emit transforms
        this->emitTransforms(vertBuilder,
                             varyingHandler,
                             uniformHandler,
                             gpArgs->fPositionVar,
                             dfTexEffect.inPosition()->fName,
                             args.fTransformsIn,
                             args.fTransformsOut);

        // add varyings
        GrGLSLVertToFrag recipScale(kFloat_GrSLType);
        GrGLSLVertToFrag uv(kVec2f_GrSLType);
        bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask) ==
                              kUniformScale_DistanceFieldEffectMask;
        bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag);
        varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
        vertBuilder->codeAppendf("%s = %s;", uv.vsOut(), dfTexEffect.inTextureCoords()->fName);

        // compute numbers to be hardcoded to convert texture coordinates from float to int
        SkASSERT(dfTexEffect.numTextures() == 1);
        GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture();
        SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()));

        GrGLSLVertToFrag st(kVec2f_GrSLType);
        varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
        vertBuilder->codeAppendf("%s = vec2(%d, %d) * %s;", st.vsOut(),
                                 atlas->width(), atlas->height(),
                                 dfTexEffect.inTextureCoords()->fName);
        
        // Use highp to work around aliasing issues
        fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(args.fGLSLCaps,
                                                                 kHigh_GrSLPrecision));
        fragBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());

        fragBuilder->codeAppend("\tfloat texColor = ");
        fragBuilder->appendTextureLookup(args.fSamplers[0],
                                         "uv",
                                         kVec2f_GrSLType);
        fragBuilder->codeAppend(".r;\n");
        fragBuilder->codeAppend("\tfloat distance = "
                       SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");");
#ifdef SK_GAMMA_APPLY_TO_A8
        // adjust width based on gamma
        fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName);
#endif

        fragBuilder->codeAppend("float afwidth;");
        if (isUniformScale) {
            // For uniform scale, we adjust for the effect of the transformation on the distance
            // by using the length of the gradient of the t coordinate in the y direction. 
            // We use st coordinates to ensure we're mapping 1:1 from texel space to pixel space.
            // We use the y gradient because there is a bug in the Mali 400 in the x direction.

            // this gives us a smooth step across approximately one fragment
            fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(%s.y));",
                                     st.fsIn());
        } else if (isSimilarity) {
            // For similarity transform, we adjust the effect of the transformation on the distance
            // by using the length of the gradient of the texture coordinates. We use st coordinates
            // to ensure we're mapping 1:1 from texel space to pixel space.
            // We use the y gradient because there is a bug in the Mali 400 in the x direction.

            // this gives us a smooth step across approximately one fragment
            fragBuilder->codeAppendf("float st_grad_len = length(dFdy(%s));", st.fsIn());
            fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*st_grad_len);");
        } else {
            // For general transforms, to determine the amount of correction we multiply a unit
            // vector pointing along the SDF gradient direction by the Jacobian of the st coords
            // (which is the inverse transform for this fragment) and take the length of the result.
            fragBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(distance));");
            // the length of the gradient may be 0, so we need to check for this
            // this also compensates for the Adreno, which likes to drop tiles on division by 0
            fragBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);");
            fragBuilder->codeAppend("if (dg_len2 < 0.0001) {");
            fragBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
            fragBuilder->codeAppend("} else {");
            fragBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
            fragBuilder->codeAppend("}");

            fragBuilder->codeAppendf("vec2 Jdx = dFdx(%s);", st.fsIn());
            fragBuilder->codeAppendf("vec2 Jdy = dFdy(%s);", st.fsIn());
            fragBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
            fragBuilder->codeAppend("                 dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");

            // this gives us a smooth step across approximately one fragment
            fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
        }
        fragBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);");

        fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
    }
void MeshTopoData::BuildInitialMapping(PatchMesh *msh)
{
	//build bounding box
	Box3 bbox;
	bbox.Init();
	//normalize the length width height
	for (int i = 0; i < TVMaps.f.Count(); i++)
	{
		int pcount = 3;
		pcount = TVMaps.f[i]->count;
		for (int j = 0; j < pcount; j++)
		{
			bbox += TVMaps.geomPoints[TVMaps.f[i]->v[j]];
			if (TVMaps.f[i]->flags & FLAG_CURVEDMAPPING)
			{
				if (TVMaps.f[i]->vecs)
				{
					bbox += TVMaps.geomPoints[TVMaps.f[i]->vecs->vhandles[j*2]];
					bbox += TVMaps.geomPoints[TVMaps.f[i]->vecs->vhandles[j*2+1]];
					if (TVMaps.f[i]->flags & FLAG_INTERIOR)
					{
						bbox += TVMaps.geomPoints[TVMaps.f[i]->vecs->vinteriors[j]];
					}
				}
			}

		}

	}
	Tab<int> indexList;

	int vct = msh->numVecs+msh->numVerts;
	indexList.SetCount(vct);
	BitArray usedIndex;
	usedIndex.SetSize(vct);
	usedIndex.ClearAll();

	for (int i = 0; i < vct; i++)
		indexList[i] = -1;

	for (int i = 0; i < TVMaps.f.Count(); i++)
	{
		if (!(TVMaps.f[i]->flags & FLAG_DEAD))
		{
			int pcount = 3;
			pcount = TVMaps.f[i]->count;

			for (int j = 0; j < pcount; j++)
			{
				//		usedIndex.Set(TVMaps.f[i].t[j]);
				usedIndex.Set(msh->patches[i].v[j]);
				if (TVMaps.f[i]->flags & FLAG_CURVEDMAPPING)
				{
					if (TVMaps.f[i]->vecs)
					{
						usedIndex.Set(msh->patches[i].vec[j*2]+msh->numVerts);
						usedIndex.Set(msh->patches[i].vec[j*2+1]+msh->numVerts);
						if (TVMaps.f[i]->flags & FLAG_INTERIOR)
						{
							usedIndex.Set(msh->patches[i].interior[j]+msh->numVerts);

						}
					}	
				}

			}
		}

	}

	int ct = 0;
	for (int i = 0; i < usedIndex.GetSize(); i++)
	{
		if (usedIndex[i])
			indexList[i] = ct++;

	}

	TVMaps.v.SetCount(usedIndex.NumberSet());
	mVSel.SetSize(usedIndex.NumberSet());

	//watje 10-19-99 bug 213437  to prevent a divide by 0 which gives you a huge u,v, or w value
	if (bbox.Width().x == 0.0f) bbox += Point3(0.5f,0.0f,0.0f);
	if (bbox.Width().y == 0.0f) bbox += Point3(0.0f,0.5f,0.0f);
	if (bbox.Width().z == 0.0f) bbox += Point3(0.0f,0.0f,0.5f);

	for (int i = 0; i < TVMaps.f.Count(); i++)
	{
		if (!(TVMaps.f[i]->flags & FLAG_DEAD))
		{
			int pcount = 3;
			pcount = TVMaps.f[i]->count;

			TVMaps.f[i]->flags &= ~FLAG_DEAD;
			for (int j = 0; j < pcount; j++)
			{
				int index;
				int a = msh->patches[i].v[j];
				index = indexList[a];
				TVMaps.f[i]->t[j] = index;
				Point3 uv(	TVMaps.geomPoints[TVMaps.f[i]->v[j]].x/bbox.Width().x + 0.5f,
							TVMaps.geomPoints[TVMaps.f[i]->v[j]].y/bbox.Width().y + 0.5f,
							TVMaps.geomPoints[TVMaps.f[i]->v[j]].z/bbox.Width().z + 0.5f);

				TVMaps.v[index].SetP(uv);
				TVMaps.v[index].SetInfluence(0.f);
				TVMaps.v[index].SetFlag(0);
				TVMaps.v[index].SetControlID(-1);
				if (TVMaps.f[i]->flags & FLAG_CURVEDMAPPING)
				{
					if (TVMaps.f[i]->vecs)
					{
						//					usedIndex.Set(msh->patches[i].vec[j*2]+msh->numVerts);
						//					usedIndex.Set(msh->patches[i].vec[j*2+1]+msh->numVerts);
						int index;
						int a = msh->patches[i].vec[j*2]+msh->numVerts;
						index = indexList[a];
						TVMaps.f[i]->vecs->handles[j*2] = index;
						Point3 uv(	TVMaps.geomPoints[TVMaps.f[i]->vecs->vhandles[j*2]].x/bbox.Width().x + 0.5f,
									TVMaps.geomPoints[TVMaps.f[i]->vecs->vhandles[j*2]].y/bbox.Width().y + 0.5f,
									TVMaps.geomPoints[TVMaps.f[i]->vecs->vhandles[j*2]].z/bbox.Width().z + 0.5f);
									
						TVMaps.v[index].SetP(uv);  
						TVMaps.v[index].SetInfluence(0.f);
						TVMaps.v[index].SetFlag(0);
						TVMaps.v[index].SetControlID(-1);

						a = msh->patches[i].vec[j*2+1]+msh->numVerts;
						index = indexList[a];
						TVMaps.f[i]->vecs->handles[j*2+1] = index;
						uv.x = TVMaps.geomPoints[TVMaps.f[i]->vecs->vhandles[j*2+1]].x/bbox.Width().x + 0.5f;
						uv.y = TVMaps.geomPoints[TVMaps.f[i]->vecs->vhandles[j*2+1]].y/bbox.Width().y + 0.5f;
						uv.z = TVMaps.geomPoints[TVMaps.f[i]->vecs->vhandles[j*2+1]].z/bbox.Width().z + 0.5f;
						TVMaps.v[index].SetP(uv);  
						TVMaps.v[index].SetInfluence(0.f);
						TVMaps.v[index].SetFlag(0);
						TVMaps.v[index].SetControlID(-1);


						if (TVMaps.f[i]->flags & FLAG_INTERIOR)
						{
							int index;
							int a = msh->patches[i].interior[j]+msh->numVerts;
							index = indexList[a];
							TVMaps.f[i]->vecs->interiors[j] = index;
							uv.x = TVMaps.geomPoints[TVMaps.f[i]->vecs->vinteriors[j]].x/bbox.Width().x + 0.5f;
							uv.y = TVMaps.geomPoints[TVMaps.f[i]->vecs->vinteriors[j]].y/bbox.Width().y + 0.5f;
							uv.z = TVMaps.geomPoints[TVMaps.f[i]->vecs->vinteriors[j]].z/bbox.Width().z + 0.5f;
							TVMaps.v[index].SetP(uv);  									
							TVMaps.v[index].SetInfluence(0.f);
							TVMaps.v[index].SetFlag(0);
							TVMaps.v[index].SetControlID(-1);

						}
					}	
				}
			}
		}

	}


}
Пример #21
0
void UltraEyeRenderer::drawHenshinInstruction()
{
	XuSkeletonJointInfo jrh, jh, jre;
	m_henshinDetector->getUserDetector()->getSkeletonJointInfo(XU_SKEL_RIGHT_HAND, &jrh);
	m_henshinDetector->getUserDetector()->getSkeletonJointInfo(XU_SKEL_HEAD, &jh);
	m_henshinDetector->getUserDetector()->getSkeletonJointInfo(XU_SKEL_RIGHT_ELBOW, &jre);

	if (!isConfident(jrh) || !isConfident(jh) || !isConfident(jre)) return;

	const float CIRCLE_RADIUS = 100;

	XV3 fv(m_henshinDetector->getUserDetector()->getForwardVector());
	XV3 uv(m_henshinDetector->getUserDetector()->getUpVector());
	XV3 armDirection((jrh.position - jre.position).normalize());
	XV3 adjustedRightHand(jrh.position + armDirection * 30); // slightly move to the fingertip side
	XV3 adjustedHead(jh.position + fv * 100); // slightly move forward
	XV3 arrowTip(adjustedRightHand.interpolate(adjustedHead, 0.95f));
	XV3 arrowBottom(adjustedRightHand.interpolate(adjustedHead, 0.0f));
	float len = (arrowTip - arrowBottom).magnitude();
	XV3 triangleBottom(arrowBottom.interpolate(arrowTip, 0.8f));
	XV3 triangleOpening = (arrowTip - arrowBottom).cross(armDirection).normalize() * len * 0.1f;
	XV3 arrowPlaneNorm = (arrowTip - arrowBottom).cross(triangleOpening).normalize();
	XV3 triangleEnd1(triangleBottom + triangleOpening);
	XV3 triangleEnd2(triangleBottom - triangleOpening);

	float maxAlpha = cramp((len - 50.0f) / 150.0f, 0, 1);
	float blinkSpeed = 1000.0f / std::max(len - 100.0f, 100.f);
	m_phase += m_ticker.tick() * blinkSpeed;
	float alpha = square(std::sin(m_phase)) * maxAlpha;

	M3DVector4f arrowColor = { 0.7f, 0.0f, 0.0f, alpha };
	m_rctx->shaderMan->UseStockShader(GLT_SHADER_FLAT, m_rctx->transform.GetModelViewProjectionMatrix(), arrowColor);

	const float THICKNESS = 2;
	glDisable(GL_DEPTH_TEST);
	glLineWidth(getPointSize() * THICKNESS);
	glPointSize(getPointSize() * THICKNESS);

	glBegin(GL_LINES);
	if (len > CIRCLE_RADIUS) {
		glVertex3fv(XV3toM3D(arrowBottom + (arrowTip - arrowBottom).normalize() * CIRCLE_RADIUS));
		glVertex3fv(XV3toM3D(arrowTip));
	}
	glVertex3fv(XV3toM3D(arrowTip));
	glVertex3fv(XV3toM3D(triangleEnd1));
	glVertex3fv(XV3toM3D(arrowTip));
	glVertex3fv(XV3toM3D(triangleEnd2));
	glEnd();

	glBegin(GL_LINE_LOOP);
	XV3 r0((arrowTip - arrowBottom).normalize() * CIRCLE_RADIUS);
	GLFrame f;
	f.SetForwardVector(0, 0, 1); // invert Z
	const int SEGMENTS = 24;
	const float STEP_ANGLE = float(M_PI * 2 / SEGMENTS);
	for (int i = 0; i < SEGMENTS; i++) {
		f.RotateLocal(STEP_ANGLE, arrowPlaneNorm.X, arrowPlaneNorm.Y, arrowPlaneNorm.Z);
		M3DVector3f r;
		f.TransformPoint(XV3toM3D(r0), r);
		glVertex3fv(XV3toM3D(arrowBottom + r));
	}
	glEnd();

	if (m_isNewUser) {
		XV3 p(-0.95f, 0.80f, 0.0f), s(0.001f, 0.0015f, 1.0f);
		renderStrokeText(m_rctx, "Put your Ultra Eye On! Now!", p, s, 3.0f, arrowColor);
	}

	glEnable(GL_DEPTH_TEST);
}
Пример #22
0
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
bool CVRADDispColl::MakeChildPatch( int ndxPatch )
{
	int	vNodeCount = 0;
	int	ndxVNodes[256];

	// find all the nodes that reside behind all of the planes
	GetNodesInPatch( ndxPatch, ndxVNodes, vNodeCount );
	if( vNodeCount <= 0 )
		return false;

	// accumulate data into current patch
	Vector2D uv( 0.0f, 0.0f );
	Vector2D uvBounds[2];
	uvBounds[0].Init( 99999.0f, 99999.0f );
	uvBounds[1].Init( -99999.0f, -99999.0f );

	patch_t *pPatch = &patches.Element( ndxPatch );
	if( pPatch )
	{
		for( int ndxNode = 0; ndxNode < vNodeCount; ndxNode++ )
		{
			VNode_t *pVNode = &m_pVNodes[ndxVNodes[ndxNode]];
			if( pVNode )
			{
				VectorAdd( pPatch->normal, pVNode->patchNormal, pPatch->normal );
				pPatch->area += pVNode->patchArea;
				Vector2DAdd( uv, pVNode->patchOriginUV, uv );

				if( uvBounds[0].x > pVNode->patchOriginUV.x ) { uvBounds[0].x = pVNode->patchOriginUV.x; }
				if( uvBounds[0].y > pVNode->patchOriginUV.y ) { uvBounds[0].y = pVNode->patchOriginUV.y; }

				if( uvBounds[1].x < pVNode->patchOriginUV.x ) { uvBounds[1].x = pVNode->patchOriginUV.x; }
				if( uvBounds[1].y < pVNode->patchOriginUV.y ) { uvBounds[1].y = pVNode->patchOriginUV.y; }
			}
		}

		VectorNormalize( pPatch->normal );

		uv /= vNodeCount;
		DispUVToSurfPt( uv, pPatch->origin, 1.0f );		

		for( int i = 0; i < 2; i++ )
		{
			uvBounds[0][i] -= 0.05f;
			uvBounds[1][i] += 0.05f;
		}

		// approximate patch winding - used for debugging!
		pPatch->winding = AllocWinding( 4 );
		if( pPatch->winding )
		{
			pPatch->winding->numpoints = 4;
			DispUVToSurfPt( uvBounds[0], pPatch->winding->p[0], 0.0f );
			DispUVToSurfPt( Vector2D( uvBounds[0].x, uvBounds[1].y ), pPatch->winding->p[1], 0.0f );
			DispUVToSurfPt( uvBounds[1], pPatch->winding->p[2], 0.0f );
			DispUVToSurfPt( Vector2D( uvBounds[1].x, uvBounds[0].y ), pPatch->winding->p[3], 0.0f );
		}

		// get the parent patch
		patch_t *pParentPatch = &patches.Element( pPatch->parent );
		if( pParentPatch )
		{
			// make sure the area is down by at least a little above half the
			// parent's area we will test at 30% (so we don't spin forever on 
			// weird patch center sampling problems
			float deltaArea = pParentPatch->area - pPatch->area;
			if( deltaArea < ( pParentPatch->area * 0.3 ) )
				return false;
		}

#if 0
		// debugging!
		g_pFileSystem->FPrintf( pDispFile, "Child Patch %d\n", ndxPatch );
		g_pFileSystem->FPrintf( pDispFile, "	Parent %d\n", pPatch->parent );
		g_pFileSystem->FPrintf( pDispFile, "	Area: %lf\n", pPatch->area );
#endif

		return true;
	}

	return false;
}
Пример #23
0
void CTerrainMgr::RegiserVertexDecl()
{	
	CVertexDeclaration* pVD;
	//顶点的复合格式
	/*
	0 - 顶点 法线 Diffuse(顶点烘培色)
	1 - specular 
	2 - original   vertex color 
	3 - Level0UV   Level0UV 第一层取址纹理坐标
	4 - Level1UV   Level1UV 第二层取址纹理坐标
	5 - Shader0UV  第一层悬崖帖计算坐标
	6 - Level2UV   第三层取址纹理坐标;
	7 - lightmap
	*/
	//普通地表格式
	st_TerrainDecl.resize(VTX_DECL_NUM);
	if(!st_isEditor)
	{
		pVD = CDataSources::GetInst()->NewVertexDeclaration(vTerrain::NormalFormat);
		pVD->AddElement(0,0,					VET_FLOAT3,VES_POSITION);
		pVD->AddElement(0,sizeof(CVector3f),	VET_FLOAT3,VES_NORMAL);
		pVD->AddElement(0,pVD->GetVertexSize(0),VET_COLOUR,VES_DIFFUSE);

		pVD->AddElement(3,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,0);//第一层纹理坐标
		pVD->AddElement(4,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,1);//第二层纹理坐标
		st_TerrainDecl[TerrainFlag::Normal] = pVD;

		///add specular
		pVD = CDataSources::GetInst()->NewVertexDeclaration(vTerrain::NormalSpecularFormat);
		pVD->AddElement(0,0,					VET_FLOAT3,VES_POSITION);
		pVD->AddElement(0,sizeof(CVector3f),	VET_FLOAT3,VES_NORMAL);
		pVD->AddElement(0,pVD->GetVertexSize(0),VET_COLOUR,VES_DIFFUSE);

		pVD->AddElement(1,0,					VET_COLOUR,VES_SPECULAR);
		pVD->AddElement(2,0,					VET_COLOUR,VES_COLOR,2);

		pVD->AddElement(3,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,0);//第一层纹理坐标
		pVD->AddElement(4,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,1);//第二层纹理坐标
		st_TerrainDecl[TerrainFlag::NormalSpecular] = pVD;


		//普通地表格式- lightmap
		pVD = CDataSources::GetInst()->NewVertexDeclaration(vTerrain::NormalFormat|LIGHT_MAP);
		pVD->AddElement(0,0,					VET_FLOAT3,VES_POSITION);
		pVD->AddElement(0,sizeof(CVector3f),	VET_FLOAT3,VES_NORMAL);
		pVD->AddElement(0,pVD->GetVertexSize(0),VET_COLOUR,VES_DIFFUSE);

		pVD->AddElement(3,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,0);;//第一层纹理坐标
		pVD->AddElement(4,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,1);//第二层纹理坐标

		pVD->AddElement(MIN_SHARE_BUF,0,		VET_FLOAT2,VES_TEXTURE_COORDINATES,2);
		st_TerrainDecl[TerrainFlag::LightMap] = pVD;

		//普通地表格式- lightmap + sprcular
		pVD = CDataSources::GetInst()->NewVertexDeclaration(vTerrain::NormalFormat|LIGHT_MAP|SPECULAR);
		pVD->AddElement(0,0,					VET_FLOAT3,VES_POSITION);
		pVD->AddElement(0,sizeof(CVector3f),	VET_FLOAT3,VES_NORMAL);
		pVD->AddElement(0,pVD->GetVertexSize(0),VET_COLOUR,VES_DIFFUSE);

		pVD->AddElement(1,0,					VET_COLOUR,VES_SPECULAR);
		pVD->AddElement(2,0,					VET_COLOUR,VES_COLOR,2);

		pVD->AddElement(3,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,0);//第一层纹理坐标
		pVD->AddElement(4,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,1);//第二层纹理坐标

		pVD->AddElement(MIN_SHARE_BUF,0,		VET_FLOAT2,VES_TEXTURE_COORDINATES,2);
		st_TerrainDecl[TerrainFlag::NormalSpecular|TerrainFlag::LightMap] = pVD;

	}
	else
	{
		pVD = CDataSources::GetInst()->NewVertexDeclaration(vTerrain::NormalFormat);
		pVD->AddElement(0,0,					VET_FLOAT3,VES_POSITION);
		pVD->AddElement(0,sizeof(CVector3f),	VET_FLOAT3,VES_NORMAL);
		pVD->AddElement(0,pVD->GetVertexSize(0),VET_COLOUR,VES_DIFFUSE);

		pVD->AddElement(2,0,					VET_COLOUR,VES_SPECULAR);

		pVD->AddElement(3,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,0);//第一层纹理坐标
		pVD->AddElement(4,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,1);//第二层纹理坐标
		st_TerrainDecl[TerrainFlag::Normal] = pVD;

		//////////////////////////////////////////////////////////////////////////add specular
		pVD = CDataSources::GetInst()->NewVertexDeclaration(vTerrain::NormalSpecularFormat);
		pVD->AddElement(0,0,					VET_FLOAT3,VES_POSITION);
		pVD->AddElement(0,sizeof(CVector3f),	VET_FLOAT3,VES_NORMAL);
		pVD->AddElement(0,pVD->GetVertexSize(0),VET_COLOUR,VES_DIFFUSE);

		pVD->AddElement(1,0,					VET_COLOUR,VES_SPECULAR);
		pVD->AddElement(2,0,					VET_COLOUR,VES_COLOR,2);

		pVD->AddElement(3,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,0);//第一层纹理坐标
		pVD->AddElement(4,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,1);//第二层纹理坐标

		pVD->AddElement(5,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,2);
		st_TerrainDecl[TerrainFlag::NormalSpecular] = pVD;

		//普通地表格式- lightmap
		pVD = CDataSources::GetInst()->NewVertexDeclaration(vTerrain::NormalFormat|LIGHT_MAP);
		pVD->AddElement(0,0,					VET_FLOAT3,VES_POSITION);
		pVD->AddElement(0,sizeof(CVector3f),	VET_FLOAT3,VES_NORMAL);
		pVD->AddElement(0,pVD->GetVertexSize(0),VET_COLOUR,VES_DIFFUSE);

		pVD->AddElement(2,0,					VET_COLOUR,VES_SPECULAR);

		pVD->AddElement(3,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,0);//第一层纹理坐标
		pVD->AddElement(4,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,1);//第二层纹理坐标

		pVD->AddElement(MIN_SHARE_BUF,0,VET_FLOAT2,			VES_TEXTURE_COORDINATES,2);//lightmap
		st_TerrainDecl[TerrainFlag::LightMap] = pVD;

		//普通地表格式- lightmap + sprcular
		pVD = CDataSources::GetInst()->NewVertexDeclaration(vTerrain::NormalSpecularFormat|LIGHT_MAP);
		pVD->AddElement(0,0,					VET_FLOAT3,VES_POSITION);
		pVD->AddElement(0,sizeof(CVector3f),	VET_FLOAT3,VES_NORMAL);
		pVD->AddElement(0,pVD->GetVertexSize(0),VET_COLOUR,VES_DIFFUSE);

		pVD->AddElement(1,0,					VET_COLOUR,VES_SPECULAR);
		pVD->AddElement(2,0,					VET_COLOUR,VES_COLOR,2);

		pVD->AddElement(3,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,0);//第一层纹理坐标
		pVD->AddElement(4,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,1);//第二层纹理坐标

		pVD->AddElement(MIN_SHARE_BUF,0,		VET_FLOAT2,VES_TEXTURE_COORDINATES,2);
		st_TerrainDecl[TerrainFlag::NormalSpecular|TerrainFlag::LightMap] = pVD;
	}

	//Shader
	pVD = CDataSources::GetInst()->NewVertexDeclaration(vTerrain::ShaderFormat);
	pVD->AddElement(0,0,					VET_FLOAT3,VES_POSITION);
	pVD->AddElement(0,sizeof(CVector3f),	VET_FLOAT3,VES_NORMAL);
	pVD->AddElement(0,pVD->GetVertexSize(0),VET_COLOUR,VES_DIFFUSE);

	pVD->AddElement(2,0,					VET_COLOUR,VES_SPECULAR);

	pVD->AddElement(3,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,0);//第一层纹理坐标
	pVD->AddElement(4,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,1);//第二层纹理坐标

	pVD->AddElement(5,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,2);
	st_TerrainDecl[TerrainFlag::Cliff] = pVD;

	///cliff+specular
	pVD = CDataSources::GetInst()->NewVertexDeclaration(vTerrain::ShaderFormat|SPECULAR);
	pVD->AddElement(0,0,					VET_FLOAT3,VES_POSITION);
	pVD->AddElement(0,sizeof(CVector3f),	VET_FLOAT3,VES_NORMAL);
	pVD->AddElement(0,pVD->GetVertexSize(0),VET_COLOUR,VES_DIFFUSE);

	pVD->AddElement(1,0,					VET_COLOUR,VES_SPECULAR);
	pVD->AddElement(2,0,					VET_COLOUR,VES_COLOR,2);

	pVD->AddElement(3,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,0);//第一层纹理坐标
	pVD->AddElement(4,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,1);//第二层纹理坐标

	pVD->AddElement(5,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,2);
	st_TerrainDecl[TerrainFlag::Cliff|TerrainFlag::NormalSpecular] = pVD;


	//Shader - lightmap
	pVD = CDataSources::GetInst()->NewVertexDeclaration(vTerrain::ShaderFormat|LIGHT_MAP);
	pVD->AddElement(0,0,					VET_FLOAT3,VES_POSITION);
	pVD->AddElement(0,sizeof(CVector3f),	VET_FLOAT3,VES_NORMAL);
	pVD->AddElement(0,pVD->GetVertexSize(0),VET_COLOUR,VES_DIFFUSE);

	pVD->AddElement(2,0,					VET_COLOUR,VES_SPECULAR);

	pVD->AddElement(3,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,0);//第一层纹理坐标
	pVD->AddElement(4,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,1);//第二层纹理坐标

	pVD->AddElement(5,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,2);

	pVD->AddElement(MIN_SHARE_BUF,0,		VET_FLOAT2,VES_TEXTURE_COORDINATES,3);
	st_TerrainDecl[TerrainFlag::Cliff|TerrainFlag::LightMap] = pVD;

	///cliff+specular+lightmap
	pVD = CDataSources::GetInst()->NewVertexDeclaration(vTerrain::ShaderFormat|LIGHT_MAP|SPECULAR);
	pVD->AddElement(0,0,					VET_FLOAT3,VES_POSITION);
	pVD->AddElement(0,sizeof(CVector3f),	VET_FLOAT3,VES_NORMAL);
	pVD->AddElement(0,pVD->GetVertexSize(0),VET_COLOUR,VES_DIFFUSE);

	pVD->AddElement(1,0,					VET_COLOUR,VES_SPECULAR);
	pVD->AddElement(2,0,					VET_COLOUR,VES_COLOR,2);

	pVD->AddElement(3,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,0);//第一层纹理坐标
	pVD->AddElement(4,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,1);//第二层纹理坐标

	pVD->AddElement(5,0,					VET_FLOAT2,VES_TEXTURE_COORDINATES,2);

	pVD->AddElement(MIN_SHARE_BUF,0,		VET_FLOAT2,VES_TEXTURE_COORDINATES,3);
	st_TerrainDecl[TerrainFlag::Cliff|TerrainFlag::NormalSpecular|TerrainFlag::LightMap] = pVD;

	//---------借用一方宝地,初始化其他静态变量---------------------
	uint PerNum = eSRegionSpan / MAP_SIZE;
	uint SqrNum = PerNum * PerNum;


	vector<int16>		p(MAP_SIZE_SQR*6);
	vector<CVector2f>	uv(MAP_SIZE_SQR*4*SqrNum);
	float Magic = float(EXPAND_SIZE)/float(MAX_TEXTURE+EXPAND_SIZE*MAX_ROW_INDEX*2);
	float offset = 1.0f / MAX_ROW_INDEX;
	
	st_apTextUV.resize(256);
	for ( int i = 0;i<256;++i )
	{
		st_apTextUV[i].x = (i%MAX_ROW_INDEX)*offset + Magic;
		st_apTextUV[i].y = (i/MAX_ROW_INDEX)*offset + Magic;
	}

	Magic = 0.0009765625f;
	float uvStep = 1.0f / float(eSRegionSpan);//0.015625f;// 1/64.0f;
	
	for (uint i = 0,tempi = 0,ii = 0; i<MAP_SIZE; ++i,tempi+=MAP_SIZE*4,ii +=6*MAP_SIZE )
	{
		for (uint j = 0,tempj = 0,ij = 0; j<MAP_SIZE; ++j,tempj +=4,ij +=6 )
		{
			int	no = tempi + tempj;
			int ino = ii + ij;

			for(uint q = 0; q < SqrNum; ++q)
			{
				int delta = q * MAP_SIZE_SQR * 4;
				float dx = (q % PerNum) * uvStep * MAP_SIZE;
				float dy = (q / PerNum) * uvStep * MAP_SIZE;
				uv[no + 1 + delta].x = uv[no + 0 + delta].x = j*uvStep  + Magic + dx;///64.0f*/;
				uv[no + 2 + delta].y = uv[no + 0 + delta].y = 1-i*uvStep+ Magic - dy;///64.0f;
				uv[no + 3 + delta].x = uv[no + 2 + delta].x = uv[no + delta].x + uvStep;
				uv[no + 3 + delta].y = uv[no + 1 + delta].y = uv[no + delta].y - uvStep;
			}

			if (1 ==(i+j)%2)
			{
				p[ino] = p[ino+4] = no + 3;
				p[ino+1] = p[ino+3] = no;
				p[ino+2] = no + 1;
				p[ino+5] = no + 2;
			}
			else
			{
				p[ino] = no;
				p[ino+1] = p[ino+5] = no + 1;
				p[ino+2] = p[ino+4] = no + 2;
				p[ino+3] = no + 3;
			}
		}
	}

	Ast(NULL==st_pIndex);
	st_pIndex		= CHardwareBufferMgr::GetInst()->createIndexBuffer(
		MAP_SIZE_SQR*6,HBU_STATIC_WRITE_ONLY,&(p[0]));

	st_LightMapBuffer.resize(SqrNum);
	for(uint q = 0; q < SqrNum; ++q)
	{
		st_LightMapBuffer[q]	=	CHardwareBufferMgr::GetInst()->createVertexBuffer(
			sizeof(CVector2f),
			MAP_SIZE_SQR*4,
			HBU_STATIC_WRITE_ONLY,
			(&uv[q*MAP_SIZE_SQR * 4]));
	}

	g_TerrainTexHandler.CreateTerrainTex(CSceneConfig::GetInst()->GetTexQualityLevel());
	CTextureQualityMgr::GetInst()->_AddTexture(&g_TerrainTexHandler);
}
void MeshTopoData::BuildInitialMapping(MNMesh *msh)
{
	//build bounding box
	Box3 bbox;
	bbox.Init();

	int vertCount = 0;
	//normalize the length width height
	for (int i = 0; i < TVMaps.f.Count(); i++)
	{
		int pcount = 3;
		pcount = TVMaps.f[i]->count;
		vertCount += pcount;
		for (int j = 0; j < pcount; j++)
		{
			bbox += TVMaps.geomPoints[TVMaps.f[i]->v[j]];
		}

	}

	vertCount = msh->numv;
	Tab<int> indexList;

	indexList.SetCount(vertCount);
	BitArray usedIndex;
	usedIndex.SetSize(vertCount);
	usedIndex.ClearAll();

	for (int i = 0; i < vertCount; i++)
		indexList[i] = -1;

	for (int i = 0; i < TVMaps.f.Count(); i++)
	{
		if (!(TVMaps.f[i]->flags & FLAG_DEAD))
		{
			int pcount = 3;
			pcount = TVMaps.f[i]->count;
			for (int j = 0; j < pcount; j++)
			{
				usedIndex.Set(msh->f[i].vtx[j]);
			}
		}

	}

	int ct = 0;
	for (int i = 0; i < usedIndex.GetSize(); i++)
	{
		if (usedIndex[i])
			indexList[i] = ct++;

	}

	TVMaps.v.SetCount(usedIndex.NumberSet());
	mVSel.SetSize(usedIndex.NumberSet());

	//watje 10-19-99 bug 213437  to prevent a divide by 0 which gives you a huge u,v, or w value
	if (bbox.Width().x == 0.0f) bbox += Point3(0.5f,0.0f,0.0f);
	if (bbox.Width().y == 0.0f) bbox += Point3(0.0f,0.5f,0.0f);
	if (bbox.Width().z == 0.0f) bbox += Point3(0.0f,0.0f,0.5f);

	for (int i = 0; i < TVMaps.f.Count(); i++)
	{
		if (!(TVMaps.f[i]->flags & FLAG_DEAD))
		{
			int pcount = 3;
			pcount = TVMaps.f[i]->count;
			TVMaps.f[i]->flags &= ~FLAG_DEAD;
			for (int j = 0; j < pcount; j++)
			{
				int index;
				int a = msh->f[i].vtx[j];
				index = indexList[a];
				TVMaps.f[i]->t[j] = index;
				Point3 uv(	TVMaps.geomPoints[TVMaps.f[i]->v[j]].x/bbox.Width().x + 0.5f,
					TVMaps.geomPoints[TVMaps.f[i]->v[j]].y/bbox.Width().y + 0.5f,
					TVMaps.geomPoints[TVMaps.f[i]->v[j]].z/bbox.Width().z + 0.5f );
				TVMaps.v[index].SetP(uv);
				TVMaps.v[index].SetInfluence(0.f);
				TVMaps.v[index].SetFlag(0);
				TVMaps.v[index].SetControlID(-1);

			}

		}
	}

}
Пример #25
0
gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face&   F,
                                    const SMDS_MeshNode* n,
                                    const SMDS_MeshNode* n2) const
{
  gp_Pnt2d uv( 1e100, 1e100 );
  const SMDS_PositionPtr Pos = n->GetPosition();
  if(Pos->GetTypeOfPosition()==SMDS_TOP_FACE)
  {
    // node has position on face
    const SMDS_FacePosition* fpos =
      static_cast<const SMDS_FacePosition*>(n->GetPosition().get());
    uv = gp_Pnt2d(fpos->GetUParameter(),fpos->GetVParameter());
  }
  else if(Pos->GetTypeOfPosition()==SMDS_TOP_EDGE)
  {
    // node has position on edge => it is needed to find
    // corresponding edge from face, get pcurve for this
    // edge and recieve value from this pcurve
    const SMDS_EdgePosition* epos =
      static_cast<const SMDS_EdgePosition*>(n->GetPosition().get());
    SMESHDS_Mesh* meshDS = GetMeshDS();
    int edgeID = Pos->GetShapeId();
    TopoDS_Edge E = TopoDS::Edge(meshDS->IndexToShape(edgeID));
    double f, l;
    Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
    uv = C2d->Value( epos->GetUParameter() );
    // for a node on a seam edge select one of UVs on 2 pcurves
    if ( n2 && IsSeamShape( edgeID ) )
      uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0 ));
  }
  else if(Pos->GetTypeOfPosition()==SMDS_TOP_VERTEX)
  {
    if ( int vertexID = n->GetPosition()->GetShapeId() ) {
      bool ok = true;
      const TopoDS_Vertex& V = TopoDS::Vertex(GetMeshDS()->IndexToShape(vertexID));
      try {
        uv = BRep_Tool::Parameters( V, F );
      }
      catch (Standard_Failure& exc) {
        ok = false;
      }
      if ( !ok ) {
        for ( TopExp_Explorer vert(F,TopAbs_VERTEX); !ok && vert.More(); vert.Next() )
          ok = ( V == vert.Current() );
        if ( !ok ) {
#ifdef _DEBUG_
          MESSAGE ( "SMESH_MesherHelper::GetNodeUV(); Vertex " << vertexID
               << " not in face " << GetMeshDS()->ShapeToIndex( F ) );
#endif
          // get UV of a vertex closest to the node
          double dist = 1e100;
          gp_Pnt pn ( n->X(),n->Y(),n->Z() );
          for ( TopExp_Explorer vert(F,TopAbs_VERTEX); !ok && vert.More(); vert.Next() ) {
            TopoDS_Vertex curV = TopoDS::Vertex( vert.Current() );
            gp_Pnt p = BRep_Tool::Pnt( curV );
            double curDist = p.SquareDistance( pn );
            if ( curDist < dist ) {
              dist = curDist;
              uv = BRep_Tool::Parameters( curV, F );
              if ( dist < DBL_MIN ) break;
            }
          }
        }
        else {
          TopTools_ListIteratorOfListOfShape it( myMesh->GetAncestors( V ));
          for ( ; it.More(); it.Next() ) {
            if ( it.Value().ShapeType() == TopAbs_EDGE ) {
              const TopoDS_Edge & edge = TopoDS::Edge( it.Value() );
              double f,l;
              Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edge, F, f, l);
              if ( !C2d.IsNull() ) {
                double u = ( V == TopExp::FirstVertex( edge ) ) ?  f : l;
                uv = C2d->Value( u );
                break;
              }
            }
          }
        }
      }
      if ( n2 && IsSeamShape( vertexID ) )
        uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0 ));
    }
  }
  return uv.XY();
}
Пример #26
0
glm::vec2 SquarePlane::GetUVCoordinates(const glm::vec3 &point)
{
    glm::vec2 uv(point.x + 0.5f, point.y + 0.5f);

    return uv;
}
Пример #27
0
void cloth::render(Shader* shader)
{
	 glPolygonMode(GL_FRONT_AND_BACK, (draw_wire ? GL_LINE : GL_FILL));
	// reset normals (which where written to last frame)
	std::vector<Particle>::iterator particle;
	for(particle = particles.begin(); particle != particles.end(); particle++)
	{
		(*particle).resetNormal();
	}

	updateFaceNormal();

	static GLuint vertexArrayObject = 0;
	static GLuint vertexBuffer = 0;
	static GLuint texture;
	static int elementSize;
	if (vertexArrayObject == 0){
		glGenVertexArrays(1, &vertexArrayObject);
		glBindVertexArray(vertexArrayObject);

		glGenBuffers(1, &vertexBuffer);
		glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);

		GLuint positionAttributeLocation = glGetAttribLocation(shader->ProgramID, "position");
		GLuint uvAttributeLocation = glGetAttribLocation(shader->ProgramID, "uv");
		GLuint normalAttributeLocation = glGetAttribLocation(shader->ProgramID, "normal");
		glEnableVertexAttribArray(positionAttributeLocation);
		glEnableVertexAttribArray(uvAttributeLocation);
		glEnableVertexAttribArray(normalAttributeLocation);
		glVertexAttribPointer(positionAttributeLocation, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)0);
		glVertexAttribPointer(uvAttributeLocation, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)sizeof(vec3));
		glVertexAttribPointer(normalAttributeLocation, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)(sizeof(vec3)+sizeof(vec2)));

		std::vector<int> indices;


		for (int j = 0; j < num_particles_height-1; j++) {
			int index;
			if (j > 0) {
				indices.push_back(j * num_particles_width); // make degenerate
			}
			for (int i = 0; i <= num_particles_width-1; i++) {
				index = j * num_particles_width + i;
				indices.push_back(index);
				indices.push_back(index + num_particles_width);
			}
			if (j + 1 < num_particles_height-1) {
				indices.push_back(index + num_particles_width); // make degenerate
			}
		}
		elementSize = indices.size();

		GLuint elementArrayBuffer;
		glGenBuffers(1, &elementArrayBuffer);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBuffer);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementSize * sizeof(int), &(indices[0]), GL_STATIC_DRAW);
		texture = loadClothTexture("clothTexture.jpg");
	}
	std::vector<Vertex> vertexData;

	for(int y=0; y<num_particles_height; y++)
	{
		for(int x = 0; x<num_particles_width; x++)
		{
			vec2 uv(x/(num_particles_width - 1.0f),y/(num_particles_height-1.0f));

			SaveParticleVertexInfo(getParticle(x, y), uv, vertexData);
		}
	}
	glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
	glBufferData(GL_ARRAY_BUFFER, vertexData.size() * sizeof(Vertex), value_ptr(vertexData[0].position), GL_STREAM_DRAW);
	computeMatricesFromInputs();
	glm::mat4 ModelMatrix = glm::mat4(1.0f);
	glm::mat4 ProjectionMatrix = getProjectionMatrix();
	glm::mat4 ViewMatrix = getViewMatrix();
	mat4 mvp = ProjectionMatrix * ViewMatrix * ModelMatrix;
	mat4 modelView = ViewMatrix * ModelMatrix;
	glUniformMatrix4fv(glGetUniformLocation(shader->ProgramID, "mvp"),1,false, value_ptr(mvp));
	mat3 normalMatrix = inverse(transpose(mat3(modelView)));
	glUniformMatrix3fv(glGetUniformLocation(shader->ProgramID, "normalMatrix"),1,false, value_ptr(normalMatrix));

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, texture);
	glUniform1i(glGetUniformLocation(shader->ProgramID, "mainTexture"), 0);

	glBindVertexArray(vertexArrayObject);
	glDrawElements(GL_TRIANGLE_STRIP, elementSize, GL_UNSIGNED_INT, 0);
}
Пример #28
0
    void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
        const GrDistanceFieldA8TextGeoProc& dfTexEffect =
                args.fGP.cast<GrDistanceFieldA8TextGeoProc>();
        GrGLGPBuilder* pb = args.fPB;
        GrGLFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
        SkAssertResult(fsBuilder->enableFeature(
                GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));

        GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();

        // emit attributes
        vsBuilder->emitAttributes(dfTexEffect);

#ifdef SK_GAMMA_APPLY_TO_A8
        // adjust based on gamma
        const char* distanceAdjustUniName = NULL;
        // width, height, 1/(3*width)
        fDistanceAdjustUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
            kFloat_GrSLType, kDefault_GrSLPrecision,
            "DistanceAdjust", &distanceAdjustUniName);
#endif

        // Setup pass through color
        if (!dfTexEffect.colorIgnored()) {
            if (dfTexEffect.hasVertexColor()) {
                pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor);
            } else {
                this->setupUniformColor(pb, args.fOutputColor, &fColorUniform);
            }
        }

        // Setup position
        this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix(),
                            &fViewMatrixUniform);

        // emit transforms
        this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
                             args.fTransformsIn, args.fTransformsOut);

        // add varyings
        GrGLVertToFrag recipScale(kFloat_GrSLType);
        GrGLVertToFrag st(kVec2f_GrSLType);
        bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag);
        args.fPB->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
        vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName);

        GrGLVertToFrag uv(kVec2f_GrSLType);
        args.fPB->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
        // this is only used with text, so our texture bounds always match the glyph atlas
        vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", "
                               GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(),
                               dfTexEffect.inTextureCoords()->fName);
        
        // Use highp to work around aliasing issues
        fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
                                                             pb->ctxInfo().standard()));
        fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());

        fsBuilder->codeAppend("\tfloat texColor = ");
        fsBuilder->appendTextureLookup(args.fSamplers[0],
                                       "uv",
                                       kVec2f_GrSLType);
        fsBuilder->codeAppend(".r;\n");
        fsBuilder->codeAppend("\tfloat distance = "
                       SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold ");");
#ifdef SK_GAMMA_APPLY_TO_A8
        // adjust width based on gamma
        fsBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName);
#endif

        fsBuilder->codeAppend("float afwidth;");
        if (isSimilarity) {
            // For uniform scale, we adjust for the effect of the transformation on the distance
            // by using the length of the gradient of the texture coordinates. We use st coordinates
            // to ensure we're mapping 1:1 from texel space to pixel space.

            // this gives us a smooth step across approximately one fragment
            // we use y to work around a Mali400 bug in the x direction
            fsBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(%s.y));",
                                       st.fsIn());
        } else {
            // For general transforms, to determine the amount of correction we multiply a unit
            // vector pointing along the SDF gradient direction by the Jacobian of the st coords
            // (which is the inverse transform for this fragment) and take the length of the result.
            fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(distance));");
            // the length of the gradient may be 0, so we need to check for this
            // this also compensates for the Adreno, which likes to drop tiles on division by 0
            fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);");
            fsBuilder->codeAppend("if (dg_len2 < 0.0001) {");
            fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
            fsBuilder->codeAppend("} else {");
            fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
            fsBuilder->codeAppend("}");

            fsBuilder->codeAppendf("vec2 Jdx = dFdx(%s);", st.fsIn());
            fsBuilder->codeAppendf("vec2 Jdy = dFdy(%s);", st.fsIn());
            fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
            fsBuilder->codeAppend("                 dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");

            // this gives us a smooth step across approximately one fragment
            fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
        }
        fsBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);");

        fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
    }
Пример #29
0
    void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
        const GrDistanceFieldLCDTextGeoProc& dfTexEffect =
                args.fGP.cast<GrDistanceFieldLCDTextGeoProc>();
        GrGLGPBuilder* pb = args.fPB;

        GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();

        // emit attributes
        vsBuilder->emitAttributes(dfTexEffect);

        // setup pass through color
        if (!dfTexEffect.colorIgnored()) {
            this->setupUniformColor(pb, args.fOutputColor, &fColorUniform);
        }

        // Setup position
        this->setupPosition(pb, gpArgs, dfTexEffect.inPosition()->fName, dfTexEffect.viewMatrix(),
                            &fViewMatrixUniform);

        // emit transforms
        this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName,
                             args.fTransformsIn, args.fTransformsOut);

        // set up varyings
        bool isUniformScale = SkToBool(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask);
        GrGLVertToFrag recipScale(kFloat_GrSLType);
        GrGLVertToFrag st(kVec2f_GrSLType);
        args.fPB->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision);
        vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName);

        GrGLVertToFrag uv(kVec2f_GrSLType);
        args.fPB->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
        // this is only used with text, so our texture bounds always match the glyph atlas
        vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", "
                               GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(),
                               dfTexEffect.inTextureCoords()->fName);

        // add frag shader code
        GrGLFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();

        SkAssertResult(fsBuilder->enableFeature(
                GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));

        // create LCD offset adjusted by inverse of transform
        // Use highp to work around aliasing issues
        fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
                                                             pb->ctxInfo().standard()));
        fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn());
        fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision,
                                                             pb->ctxInfo().standard()));
        if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) {
            fsBuilder->codeAppend("float delta = -" GR_FONT_ATLAS_LCD_DELTA ";\n");
        } else {
            fsBuilder->codeAppend("float delta = " GR_FONT_ATLAS_LCD_DELTA ";\n");
        }
        if (isUniformScale) {
            fsBuilder->codeAppendf("float dy = abs(dFdy(%s.y));", st.fsIn());
            fsBuilder->codeAppend("vec2 offset = vec2(dy*delta, 0.0);");
        } else {
            fsBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn());

            fsBuilder->codeAppend("vec2 Jdx = dFdx(st);");
            fsBuilder->codeAppend("vec2 Jdy = dFdy(st);");
            fsBuilder->codeAppend("vec2 offset = delta*Jdx;");
        }

        // green is distance to uv center
        fsBuilder->codeAppend("\tvec4 texColor = ");
        fsBuilder->appendTextureLookup(args.fSamplers[0], "uv", kVec2f_GrSLType);
        fsBuilder->codeAppend(";\n");
        fsBuilder->codeAppend("\tvec3 distance;\n");
        fsBuilder->codeAppend("\tdistance.y = texColor.r;\n");
        // red is distance to left offset
        fsBuilder->codeAppend("\tvec2 uv_adjusted = uv - offset;\n");
        fsBuilder->codeAppend("\ttexColor = ");
        fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType);
        fsBuilder->codeAppend(";\n");
        fsBuilder->codeAppend("\tdistance.x = texColor.r;\n");
        // blue is distance to right offset
        fsBuilder->codeAppend("\tuv_adjusted = uv + offset;\n");
        fsBuilder->codeAppend("\ttexColor = ");
        fsBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2f_GrSLType);
        fsBuilder->codeAppend(";\n");
        fsBuilder->codeAppend("\tdistance.z = texColor.r;\n");

        fsBuilder->codeAppend("\tdistance = "
           "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceFieldThreshold"));");

        // adjust width based on gamma
        const char* distanceAdjustUniName = NULL;
        fDistanceAdjustUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
            kVec3f_GrSLType, kDefault_GrSLPrecision,
            "DistanceAdjust", &distanceAdjustUniName);
        fsBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName);

        // To be strictly correct, we should compute the anti-aliasing factor separately
        // for each color component. However, this is only important when using perspective
        // transformations, and even then using a single factor seems like a reasonable
        // trade-off between quality and speed.
        fsBuilder->codeAppend("float afwidth;");
        if (isUniformScale) {
            // For uniform scale, we adjust for the effect of the transformation on the distance
            // by using the length of the gradient of the texture coordinates. We use st coordinates
            // to ensure we're mapping 1:1 from texel space to pixel space.

            // this gives us a smooth step across approximately one fragment
            fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*dy;");
        } else {
            // For general transforms, to determine the amount of correction we multiply a unit
            // vector pointing along the SDF gradient direction by the Jacobian of the st coords
            // (which is the inverse transform for this fragment) and take the length of the result.
            fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance.r), dFdy(distance.r));");
            // the length of the gradient may be 0, so we need to check for this
            // this also compensates for the Adreno, which likes to drop tiles on division by 0
            fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);");
            fsBuilder->codeAppend("if (dg_len2 < 0.0001) {");
            fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);");
            fsBuilder->codeAppend("} else {");
            fsBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2);");
            fsBuilder->codeAppend("}");
            fsBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_grad.y*Jdy.x,");
            fsBuilder->codeAppend("                 dist_grad.x*Jdx.y + dist_grad.y*Jdy.y);");

            // this gives us a smooth step across approximately one fragment
            fsBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
        }

        fsBuilder->codeAppend(
                      "vec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), distance), 1.0);");

        fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
    }
Пример #30
0
void GSVertexTrace::FindMinMax(const void* vertex, const uint32* index, int count)
{
	const GSDrawingContext* context = m_state->m_context;

	int n = 1;

	switch(primclass)
	{
	case GS_POINT_CLASS:
		n = 1;
		break;
	case GS_LINE_CLASS:
	case GS_SPRITE_CLASS:
		n = 2;
		break;
	case GS_TRIANGLE_CLASS:
		n = 3;
		break;
	}

	GSVector4 tmin = s_minmax.xxxx();
	GSVector4 tmax = s_minmax.yyyy();
	GSVector4i cmin = GSVector4i::xffffffff();
	GSVector4i cmax = GSVector4i::zero();

	#if _M_SSE >= 0x401

	GSVector4i pmin = GSVector4i::xffffffff();
	GSVector4i pmax = GSVector4i::zero();

	#else

	GSVector4 pmin = s_minmax.xxxx();
	GSVector4 pmax = s_minmax.yyyy();
	
	#endif

	const GSVertex* RESTRICT v = (GSVertex*)vertex;

	for(int i = 0; i < count; i += n)
	{
		if(primclass == GS_POINT_CLASS)
		{
			GSVector4i c(v[index[i]].m[0]);

			if(color)
			{
				cmin = cmin.min_u8(c);
				cmax = cmax.max_u8(c);
			}

			if(tme)
			{
				if(!fst)
				{
					GSVector4 stq = GSVector4::cast(c);

					GSVector4 q = stq.wwww();

					stq = (stq.xyww() * q.rcpnr()).xyww(q);

					tmin = tmin.min(stq);
					tmax = tmax.max(stq);
				}
				else
				{
					GSVector4i uv(v[index[i]].m[1]);

					GSVector4 st = GSVector4(uv.uph16()).xyxy();

					tmin = tmin.min(st);
					tmax = tmax.max(st);
				}
			}

			GSVector4i xyzf(v[index[i]].m[1]);

			GSVector4i xy = xyzf.upl16();
			GSVector4i z = xyzf.yyyy();

			#if _M_SSE >= 0x401

			GSVector4i p = xy.blend16<0xf0>(z.uph32(xyzf));

			pmin = pmin.min_u32(p);
			pmax = pmax.max_u32(p);

			#else

			GSVector4 p = GSVector4(xy.upl64(z.srl32(1).upl32(xyzf.wwww())));

			pmin = pmin.min(p);
			pmax = pmax.max(p);

			#endif
		}
		else if(primclass == GS_LINE_CLASS)
		{
			GSVector4i c0(v[index[i + 0]].m[0]);
			GSVector4i c1(v[index[i + 1]].m[0]);

			if(color)
			{
				if(iip)
				{
					cmin = cmin.min_u8(c0.min_u8(c1));
					cmax = cmax.max_u8(c0.max_u8(c1));
				}
				else
				{
					cmin = cmin.min_u8(c1);
					cmax = cmax.max_u8(c1);
				}
			}

			if(tme)
			{
				if(!fst)
				{
					GSVector4 stq0 = GSVector4::cast(c0);
					GSVector4 stq1 = GSVector4::cast(c1);

					GSVector4 q = stq0.wwww(stq1).rcpnr();

					stq0 = (stq0.xyww() * q.xxxx()).xyww(stq0);
					stq1 = (stq1.xyww() * q.zzzz()).xyww(stq1);

					tmin = tmin.min(stq0.min(stq1));
					tmax = tmax.max(stq0.max(stq1));
				}
				else
				{
					GSVector4i uv0(v[index[i + 0]].m[1]);
					GSVector4i uv1(v[index[i + 1]].m[1]);

					GSVector4 st0 = GSVector4(uv0.uph16()).xyxy();
					GSVector4 st1 = GSVector4(uv1.uph16()).xyxy();

					tmin = tmin.min(st0.min(st1));
					tmax = tmax.max(st0.max(st1));
				}
			}

			GSVector4i xyzf0(v[index[i + 0]].m[1]);
			GSVector4i xyzf1(v[index[i + 1]].m[1]);

			GSVector4i xy0 = xyzf0.upl16();
			GSVector4i z0 = xyzf0.yyyy();
			GSVector4i xy1 = xyzf1.upl16();
			GSVector4i z1 = xyzf1.yyyy();

			#if _M_SSE >= 0x401

			GSVector4i p0 = xy0.blend16<0xf0>(z0.uph32(xyzf0));
			GSVector4i p1 = xy1.blend16<0xf0>(z1.uph32(xyzf1));

			pmin = pmin.min_u32(p0.min_u32(p1));
			pmax = pmax.max_u32(p0.max_u32(p1));

			#else

			GSVector4 p0 = GSVector4(xy0.upl64(z0.srl32(1).upl32(xyzf0.wwww())));
			GSVector4 p1 = GSVector4(xy1.upl64(z1.srl32(1).upl32(xyzf1.wwww())));

			pmin = pmin.min(p0.min(p1));
			pmax = pmax.max(p0.max(p1));

			#endif
		}
		else if(primclass == GS_TRIANGLE_CLASS)
		{
			GSVector4i c0(v[index[i + 0]].m[0]);
			GSVector4i c1(v[index[i + 1]].m[0]);
			GSVector4i c2(v[index[i + 2]].m[0]);

			if(color)
			{
				if(iip)
				{
					cmin = cmin.min_u8(c2).min_u8(c0.min_u8(c1));
					cmax = cmax.max_u8(c2).max_u8(c0.max_u8(c1));
				}
				else
				{
					cmin = cmin.min_u8(c2);
					cmax = cmax.max_u8(c2);
				}
			}

			if(tme)
			{
				if(!fst)
				{
					GSVector4 stq0 = GSVector4::cast(c0);
					GSVector4 stq1 = GSVector4::cast(c1);
					GSVector4 stq2 = GSVector4::cast(c2);

					GSVector4 q = stq0.wwww(stq1).xzww(stq2).rcpnr();

					stq0 = (stq0.xyww() * q.xxxx()).xyww(stq0);
					stq1 = (stq1.xyww() * q.yyyy()).xyww(stq1);
					stq2 = (stq2.xyww() * q.zzzz()).xyww(stq2);

					tmin = tmin.min(stq2).min(stq0.min(stq1));
					tmax = tmax.max(stq2).max(stq0.max(stq1));
				}
				else
				{
					GSVector4i uv0(v[index[i + 0]].m[1]);
					GSVector4i uv1(v[index[i + 1]].m[1]);
					GSVector4i uv2(v[index[i + 2]].m[1]);

					GSVector4 st0 = GSVector4(uv0.uph16()).xyxy();
					GSVector4 st1 = GSVector4(uv1.uph16()).xyxy();
					GSVector4 st2 = GSVector4(uv2.uph16()).xyxy();

					tmin = tmin.min(st2).min(st0.min(st1));
					tmax = tmax.max(st2).max(st0.max(st1));
				}
			}

			GSVector4i xyzf0(v[index[i + 0]].m[1]);
			GSVector4i xyzf1(v[index[i + 1]].m[1]);
			GSVector4i xyzf2(v[index[i + 2]].m[1]);

			GSVector4i xy0 = xyzf0.upl16();
			GSVector4i z0 = xyzf0.yyyy();
			GSVector4i xy1 = xyzf1.upl16();
			GSVector4i z1 = xyzf1.yyyy();
			GSVector4i xy2 = xyzf2.upl16();
			GSVector4i z2 = xyzf2.yyyy();

			#if _M_SSE >= 0x401

			GSVector4i p0 = xy0.blend16<0xf0>(z0.uph32(xyzf0));
			GSVector4i p1 = xy1.blend16<0xf0>(z1.uph32(xyzf1));
			GSVector4i p2 = xy2.blend16<0xf0>(z2.uph32(xyzf2));

			pmin = pmin.min_u32(p2).min_u32(p0.min_u32(p1));
			pmax = pmax.max_u32(p2).max_u32(p0.max_u32(p1));

			#else

			GSVector4 p0 = GSVector4(xy0.upl64(z0.srl32(1).upl32(xyzf0.wwww())));
			GSVector4 p1 = GSVector4(xy1.upl64(z1.srl32(1).upl32(xyzf1.wwww())));
			GSVector4 p2 = GSVector4(xy2.upl64(z2.srl32(1).upl32(xyzf2.wwww())));

			pmin = pmin.min(p2).min(p0.min(p1));
			pmax = pmax.max(p2).max(p0.max(p1));

			#endif
		}
		else if(primclass == GS_SPRITE_CLASS)
		{
			GSVector4i c0(v[index[i + 0]].m[0]);
			GSVector4i c1(v[index[i + 1]].m[0]);

			if(color)
			{
				if(iip)
				{
					cmin = cmin.min_u8(c0.min_u8(c1));
					cmax = cmax.max_u8(c0.max_u8(c1));
				}
				else
				{
					cmin = cmin.min_u8(c1);
					cmax = cmax.max_u8(c1);
				}
			}

			if(tme)
			{
				if(!fst)
				{
					GSVector4 stq0 = GSVector4::cast(c0);
					GSVector4 stq1 = GSVector4::cast(c1);

					GSVector4 q = stq1.wwww().rcpnr();

					stq0 = (stq0.xyww() * q).xyww(stq1);
					stq1 = (stq1.xyww() * q).xyww(stq1);

					tmin = tmin.min(stq0.min(stq1));
					tmax = tmax.max(stq0.max(stq1));
				}
				else
				{
					GSVector4i uv0(v[index[i + 0]].m[1]);
					GSVector4i uv1(v[index[i + 1]].m[1]);

					GSVector4 st0 = GSVector4(uv0.uph16()).xyxy();
					GSVector4 st1 = GSVector4(uv1.uph16()).xyxy();

					tmin = tmin.min(st0.min(st1));
					tmax = tmax.max(st0.max(st1));
				}
			}

			GSVector4i xyzf0(v[index[i + 0]].m[1]);
			GSVector4i xyzf1(v[index[i + 1]].m[1]);

			GSVector4i xy0 = xyzf0.upl16();
			GSVector4i z0 = xyzf0.yyyy();
			GSVector4i xy1 = xyzf1.upl16();
			GSVector4i z1 = xyzf1.yyyy();

			#if _M_SSE >= 0x401

			GSVector4i p0 = xy0.blend16<0xf0>(z0.uph32(xyzf1));
			GSVector4i p1 = xy1.blend16<0xf0>(z1.uph32(xyzf1));

			pmin = pmin.min_u32(p0.min_u32(p1));
			pmax = pmax.max_u32(p0.max_u32(p1));

			#else

			GSVector4 p0 = GSVector4(xy0.upl64(z0.srl32(1).upl32(xyzf1.wwww())));
			GSVector4 p1 = GSVector4(xy1.upl64(z1.srl32(1).upl32(xyzf1.wwww())));

			pmin = pmin.min(p0.min(p1));
			pmax = pmax.max(p0.max(p1));

			#endif
		}
	}

	#if _M_SSE >= 0x401

	pmin = pmin.blend16<0x30>(pmin.srl32(1));
	pmax = pmax.blend16<0x30>(pmax.srl32(1));

	#endif

	GSVector4 o(context->XYOFFSET);
	GSVector4 s(1.0f / 16, 1.0f / 16, 2.0f, 1.0f);

	m_min.p = (GSVector4(pmin) - o) * s;
	m_max.p = (GSVector4(pmax) - o) * s;

	if(tme)
	{
		if(fst)
		{
			s = GSVector4(1.0f / 16, 1.0f).xxyy();
		}
		else
		{
			s = GSVector4(1 << context->TEX0.TW, 1 << context->TEX0.TH, 1, 1);
		}

		m_min.t = tmin * s;
		m_max.t = tmax * s;
	}
	else
	{
		m_min.t = GSVector4::zero();
		m_max.t = GSVector4::zero();
	}

	if(color)
	{
		m_min.c = cmin.zzzz().u8to32();
		m_max.c = cmax.zzzz().u8to32();
	}
	else
	{
		m_min.c = GSVector4i::zero();
		m_max.c = GSVector4i::zero();
	}
}