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; }
//************************************************************************************************************* 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(); }
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( ); }
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(); }
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; }
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; }
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; }
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(); }
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; }
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); } }
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; }
// 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; }
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); } }
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); }
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()); }
v3 v3::Unit(){ v3 uv (x, y, z); return uv.Scale(1.0 / Magnitude()); }
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); } } } } } } }
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); }
//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- 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; }
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); } } } }
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(); }
glm::vec2 SquarePlane::GetUVCoordinates(const glm::vec3 &point) { glm::vec2 uv(point.x + 0.5f, point.y + 0.5f); return uv; }
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); }
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); }
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); }
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(); } }