float HandleDash( float offset )\n\ {\n\ float sum = 0.0; \n\ float dashMaxCount = float( textureSize( dashSampler, 0 ) ); \n\ int i; \n\ for(i=0; i<dashCount; ++i) sum += texture( dashSampler, i/dashMaxCount )[0]; \n\ offset -= sum * int(offset/sum); \n\ for(i=0; i<dashCount; ++i){ \n\ float dash = texture( dashSampler, i/dashMaxCount )[0]; \n\ if( offset < dash ) break; \n\ offset -= dash; \n\ } \n\ if( (i%2) > 0 ) discard; \n\ float dash = texture( dashSampler, i/dashMaxCount )[0]; \n\ float dx = dFdx( offset ); \n\ float dy = dFdy( offset ); \n\ // implicit lines: offset*(dash-offset) = 0 \n\ float fx = (dash - 2*offset) * dx; \n\ float fy = (dash - 2*offset) * dy; \n\ float sd = offset*(dash-offset) / sqrt( fx*fx + fy*fy ); \n\ \n\ float alpha = (sd - 0.5); \n\ if( alpha < 0.0 ) discard; \n\ if( alpha < 2.0 ) return 0.5*alpha; \n\ return 1.0; \n\ }\n\
Point TextTexture::load(const TextLabelInfo &ti) { m_ti = ti; TTF_Font *font = TTF_OpenFont(ti.fontName.c_str(), ti.fontSize); if(!font) { std::cerr << "Could not load font \"" << ti.fontName <<"\" : "<< TTF_GetError() <<std::endl; exit(-1); } SDL_Color c = {ti.color.r(), ti.color.g(), ti.color.b(), ti.color.a() }; SDL_Surface * pictureSurface = NULL; pictureSurface = TTF_RenderText_Blended(font, ti.text.c_str(), c); if(pictureSurface == NULL) { std::cerr<<"Could not render text : "<<TTF_GetError()<<std::endl; exit(-1); } dumpSurface(pictureSurface); TTF_CloseFont(font); SDL_Surface * convertedSurface = NULL; //First convert the texture to a format that is more suitable for openGL loading convertedSurface = Texture::convertSurface(pictureSurface); //this texture is not needed any more SDL_FreeSurface(pictureSurface); //then create a texture form the surface surfaceToTexture(convertedSurface); //get the size of the surface before deleting it Point textureSize(convertedSurface->w, convertedSurface->h); SDL_FreeSurface(convertedSurface); return textureSize; }
void RenderSystem::update(sf::RenderWindow *window, World &world) { for (unsigned int i = 0; i != world.entityCount; ++i) { RenderComponent *render = world.renderComponents[i]; TransformComponent *xform = world.transformComponents[i]; if (render && xform) { sf::Vector2f textureSize(render->texture->getSize()); render->vertices[0].texCoords = sf::Vector2f(0.0f, 0.0f); render->vertices[1].texCoords = sf::Vector2f(textureSize.x, 0.0f); render->vertices[2].texCoords = sf::Vector2f(textureSize.x, textureSize.y); render->vertices[3].texCoords = sf::Vector2f(0.0f, textureSize.y); render->vertices[0].position = render->vertices[0].texCoords; render->vertices[1].position = sf::Vector2f(xform->size.x, 0.0f); render->vertices[2].position = sf::Vector2f(xform->size.x, xform->size.y); render->vertices[3].position = sf::Vector2f(0.0f, xform->size.y); render->vertices[0].color = render->color; render->vertices[1].color = render->color; render->vertices[2].color = render->color; render->vertices[3].color = render->color; sf::RenderStates states; states.texture = render->texture; states.transform = xform->transform; window->draw(render->vertices, states); } } }
void GraphicsContext3DPrivate::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity) { m_context->markLayerComposited(); blitMultisampleFramebufferAndRestoreContext(); if (textureMapper->accelerationMode() == TextureMapper::OpenGLMode) { TextureMapperGL* texmapGL = static_cast<TextureMapperGL*>(textureMapper); TextureMapperGL::Flags flags = TextureMapperGL::ShouldFlipTexture | (m_context->m_attrs.alpha ? TextureMapperGL::ShouldBlend : 0); IntSize textureSize(m_context->m_currentWidth, m_context->m_currentHeight); texmapGL->drawTexture(m_context->m_texture, flags, textureSize, targetRect, matrix, opacity); return; } // Alternatively read pixels to a memory buffer. GraphicsContext* context = textureMapper->graphicsContext(); QPainter* painter = context->platformContext(); painter->save(); painter->setTransform(matrix); painter->setOpacity(opacity); const int height = m_context->m_currentHeight; const int width = m_context->m_currentWidth; painter->beginNativePainting(); makeCurrentIfNeeded(); glBindFramebuffer(GL_FRAMEBUFFER, m_context->m_fbo); QImage offscreenImage = qt_gl_read_framebuffer(QSize(width, height), true, true); glBindFramebuffer(GL_FRAMEBUFFER, m_context->m_state.boundFBO); painter->endNativePainting(); painter->drawImage(targetRect, offscreenImage); painter->restore(); }
vec4 BoxBlur(){ \ vec2 texel = 1.0f / textureSize(target, 0).xy; \ //9-tap box kernal\n \ vec4 color = texture(target, fTexCoord); \ color += texture(target, fTexCoord + vec2(-texel.x, texel.y)); \ return color / 2; \ }\
bool FontGlyphTextureCache::init(FontCore* font) { if (LN_REQUIRE(font)) return false; m_font = font; m_maxCacheGlyphs = 1024;// TODO 定数なのはなんとかしたい // TODO: 最大に達するとなんか落ちる // すべてのグリフが収まるビットマップサイズ FontGlobalMetrics metrix; m_font->getGlobalMetrics(&metrix); int mw = std::ceil(metrix.boundingMaxX - metrix.boundingMinX); int mh = std::ceil(metrix.boundingMaxY - metrix.boundingMinY); // 横方向に並べる数 // +1.0 は切り捨て対策。テクスチャサイズはmaxCharactersが収まる大きさであれば良い。(小さくなければOK) m_glyphWidthCount = (int)(sqrt((double)m_maxCacheGlyphs) + 1.0); // キャッシュ用テクスチャ作成 int w = std::max(mw, mh); m_glyphMaxBitmapSize = SizeI(w, w); SizeI textureSize(m_glyphWidthCount * w, m_glyphWidthCount * w); m_fillGlyphsTexture = newObject<Texture2D>(textureSize.width, textureSize.height, TextureFormat::RGBA8); m_fillGlyphsTexture->setResourceUsage(GraphicsResourceUsage::Dynamic); // TODO: 最大 DeviceSize チェック // 検索に使う情報をリセット m_curPrimUsedFlags.resize(m_maxCacheGlyphs); for (int i = 0; i < m_maxCacheGlyphs; i++) { m_indexStack.push(i); } resetUsedFlags(); return true; }
// Private Method(s) // Setup Tiles void Puzzle::setupTiles() { int tilesSquared = static_cast<int>(sqrt(mTiles.size())); int curCol = 0, curRow = 0; sf::FloatRect outlineRect = mGrid.getOutlineRect(); sf::Vector2f tileRect(outlineRect.width / tilesSquared, outlineRect.height / tilesSquared); sf::Vector2f textureSize(mTexture.getSize()); sf::Vector2f textureRect(textureSize.x / tilesSquared, textureSize.y / tilesSquared); sf::Vector2f scalingFactor(tileRect.x / textureRect.x, tileRect.y / textureRect.y); for (unsigned i = 0; i < mTiles.size(); i++) { mTiles[i].first->setTextureRect(static_cast<sf::IntRect> (sf::FloatRect(curCol * textureRect.x, curRow * textureRect.y, textureRect.x, textureRect.y))); mTiles[i].first->setTexture(mTexture); mTiles[i].first->scale(scalingFactor); mTiles[i].first->setPosition(mGrid.getTilePos(i)); curCol++; if (curCol % tilesSquared == 0) { curRow++; curCol = 0; } } }
void Tileset::computeGridSize() { unsigned long tileWidth = m_spacing.getLeft() + m_tileSize.getWidth() + m_spacing.getRight(); unsigned long tileHeight = m_spacing.getTop() + m_tileSize.getHeight() + m_spacing.getBottom(); Dimension textureSize(m_texture.getSize()); m_gridSize.setWidth((textureSize.getWidth() - m_margin.getLeft() - m_margin.getRight()) / tileWidth); m_gridSize.setHeight((textureSize.getHeight() - m_margin.getTop() - m_margin.getBottom()) / tileHeight); }
Void CText::Render(CRenderer& renderer) { Int32 length = m_TextLength - m_CtrlCharCount; Float32 x, y; CVector2f reso = renderer.GetCurrentViewport()->GetSize(); if( length <= 0 || m_Font == NULL ) return ; CShader& shader = m_Font->GetShader(); if(length <= m_Capacity) { UpdateBuffer( 0, length); renderer.Activate( m_VertexBuffer, 0 ); renderer.Activate( m_VertexLayout ); x = (Float32) ( GetPosition().GetX() ); y = (Float32) ( 1.0f - GetPosition().GetY() ); CVector3f snapedPos( (Float32)x, (Float32)y , 0.0f ); shader.GetParameter("Position")->SetValue( snapedPos ); shader.GetParameter("Resolution")->SetValue( reso ); shader.GetParameter("InputTexture")->SetValue( m_Font->GetTexture() ); CVector2f textureSize( (Float32)m_Font->GetTextureWidth(), (Float32)m_Font->GetTextureHeight() ); shader.GetParameter("Color")->SetValue( m_Color ); renderer.Activate( shader ); renderer.Draw( nPrimitiveType_TriangleList, length * 6, 0 ); } else { Int32 offset = 0; Int32 count = m_Capacity; while(offset < length) { UpdateBuffer( offset, count); offset += count; count = length - offset; if(count > m_Capacity) count = m_Capacity; } } }
void ImageOverlayRegionFinder::addRegion(QRect &newRegion, bool optimizeForPowersOf2) { const int SizeDivisor = 10; int size = qMax(m_overlay.getRows(), m_overlay.getColumns()); int joinThreshold = size / SizeDivisor; for (int i = 0; i < m_regions.size();) { QRect ®ion = m_regions[i]; QRect jointRegion = newRegion.united(region); int distance = distanceBetweenRegions(newRegion, region); bool join = distance <= joinThreshold; if (!join && optimizeForPowersOf2) { QSize newRegionTextureSize = textureSize(newRegion); QSize regionTextureSize = textureSize(region); QSize jointRegionTextureSize = textureSize(jointRegion); int newRegionTextureArea = area(newRegionTextureSize); int regionTextureArea = area(regionTextureSize); int jointRegionTextureArea = area(jointRegionTextureSize); join = jointRegionTextureArea <= newRegionTextureArea + regionTextureArea; } if (join) { newRegion = jointRegion; m_regions.removeAt(i); i = 0; } else { i++; } } m_regions << newRegion; }
QRectF SSGTexture::convertToNormalizedSourceRect(const QRectF &rect) const { QSize s = textureSize(); QRectF r = normalizedTextureSubRect(); qreal sx = r.width() / s.width(); qreal sy = r.height() / s.height(); return QRectF(r.x() + rect.x() * sx, r.y() + rect.y() * sy, rect.width() * sx, rect.height() * sy); }
void SpriteBatch::Impl::RenderBatch(std::shared_ptr<Texture> texture, SpriteInfo const* const* sprites, size_t count) { // Activate batch texture pixelShader->SetTexture(0, texture); while (count > 0) { size_t batchSize = count; size_t remainingSpace = MaxBatchSize - m_vertexBufferOffset; if (batchSize > remainingSpace) { if (remainingSpace < MinBatchSize) { m_vertexBufferOffset = 0; batchSize = std::min(count, MaxBatchSize); } else { batchSize = remainingSpace; } } VertexPositionColorTexture* vertices = nullptr; vertexBuffer->Map(m_vertexBufferOffset == 0 ? BufferMapType::Discard : BufferMapType::NoOverwrite, (void**) &vertices); vertices += m_vertexBufferOffset * VerticesPerSprite; for (size_t i = 0; i < batchSize; ++i) { float2 textureSize((float)texture->GetWidth(), (float)texture->GetHeight()); float2 inverseTextureSize(1.0f / textureSize.x, 1.0f / textureSize.y); RenderSprite(sprites[i], vertices, textureSize, inverseTextureSize); vertices += VerticesPerSprite; } vertexBuffer->Unmap(); // Draw indexed sprites! u32 startIndex = m_vertexBufferOffset * IndicesPerSprite; u32 indexCount = batchSize * IndicesPerSprite; device->DrawIndexed(indexCount, startIndex, 0); // Advance buffer position m_vertexBufferOffset += batchSize; sprites += batchSize; count -= batchSize; } }
TextCache::TextCache(std::string text, const TextParams ¶ms) : params(params) { // Render text SDL_Color white = {255,255,255,0}; SDL_Surface *renderedText = convertImage(TTF_RenderText_Blended(params.font, text.c_str(), white)); // Copy the text onto a new surface with a meaningful size int sizeX, sizeY; SDL_SetAlpha(renderedText, 0, 255); textureSize(renderedText->w, renderedText->h, sizeX, sizeY); SDL_Surface *image = SDL_CreateRGBSurface(SDL_SWSURFACE, sizeX, sizeY, 32, textureFormat.Rmask, textureFormat.Gmask, textureFormat.Bmask, textureFormat.Amask); SDL_FillRect(image, NULL, 0); SDL_BlitSurface(renderedText, NULL, image, NULL); GLuint textureID = 0; glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_2D, textureID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, //type of texture 0, //level of detail (mipmap) 4, //components per pixel image->w, image->h, //dimensions 0, //image border GL_RGBA, //colors order GL_UNSIGNED_BYTE, //components data type image->pixels); //pixel data /* gluBuild2DMipmaps(GL_TEXTURE_2D, //type of texture 4, // image->w, image->h, //dimensions GL_RGBA, //format GL_UNSIGNED_BYTE, //channel type image->pixels); //data */ this->text = text; this->w = image->w; this->h = image->h; this->texID = textureID; this->preserve = false; SDL_FreeSurface(renderedText); SDL_FreeSurface(image); }
void BulletEntity::spawn(const Vec2& position, const Vec2& velocity, shared_ptr<Entity> parent, sf::Texture* texture) { mPosition = position; mVelocity = velocity; mRotation = atan2(velocity.y, velocity.x) * RAD_TO_DEG + 90.0f; mParent = parent; Vec2 textureSize((float)texture->getSize().x, (float)texture->getSize().y); mTexture = texture; mSprite.setTexture(*mTexture); mSprite.setOrigin(textureSize * 0.5f); mSprite.setRotation(mRotation); mActive = true; }
//---------------------------------------------------------------- // ProgressBar: // Essentially a label that uses a spritesheet and manipulates // sprite's position. // parameter: row --> row on the spritesheet to show //---------------------------------------------------------------- void BaseHud::ProgressBar(int xOffset, int yOffset, int row, int alignment, float scaleX, float scaleY) { sf::Vector2u textureSize(progressBarTexture->getSize()); //get the image size int rowHeight = textureSize.y / 8; //calculate rowHeight // 8 = amount of rows sf::Vector2f alignedPos = fixAlignment(alignment, xOffset, yOffset, textureSize.x * scaleX, rowHeight * scaleY); //sprite progressBarTexture->setRepeated(false); progressBarSprite->setScale(scaleX, scaleY); progressBarSprite->setTexture(*progressBarTexture); progressBarSprite->setTextureRect(sf::IntRect(0, rowHeight * row, textureSize.x, rowHeight)); progressBarSprite->setPosition(alignedPos); _window->draw(*progressBarSprite); }
PIC_INLINE void FilterGLDeformGrid::initShaders() { fragment_source = GLSL_BICUBIC(); fragment_source += GLSL_TEXTURE_BICUBIC(); fragment_source += MAKE_STRING ( uniform sampler2D u_tex; \n uniform sampler2D u_grid; \n out vec4 f_color; \n \n void main(void) { vec2 tSize = vec2(textureSize(u_tex, 0)); vec2 coords = gl_FragCoord.xy / tSize.xy; \n vec2 shifts = textureBicubic(u_grid, coords.xy).xy; f_color = texture(u_tex, coords + shifts.xy); }
void SSGTexture::updateBindOptions(bool force) { QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); if (force || m_filteringChanged) { bool minLinear{m_minFilterMode == Linear}; bool magLinear{m_magFilterMode == Linear}; GLint minFilter = minLinear ? GL_LINEAR : GL_NEAREST; GLint magFilter = magLinear ? GL_LINEAR : GL_NEAREST; if (hasMipmaps()) { if (m_minMipmapMode == Nearest) minFilter = minLinear ? GL_LINEAR_MIPMAP_NEAREST : GL_NEAREST_MIPMAP_NEAREST; else if (m_minMipmapMode == Linear) minFilter = minLinear ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_LINEAR; if (m_magMipmapMode == Nearest) magFilter = magLinear ? GL_LINEAR_MIPMAP_NEAREST : GL_NEAREST_MIPMAP_NEAREST; else if (m_magMipmapMode == Linear) magFilter = magLinear ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_LINEAR; } funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter); funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter); m_filteringChanged = false; } if (force || m_wrapChanged) { #ifndef QT_NO_DEBUG if (m_horizontalWrap == Repeat || m_verticalWrap == Repeat) { bool npotSupported = QOpenGLFunctions(QOpenGLContext::currentContext()).hasOpenGLFeature(QOpenGLFunctions::NPOTTextures); QSize size = textureSize(); bool isNpot = !isPowerOfTwo(size.width()) || !isPowerOfTwo(size.height()); if (!npotSupported && isNpot) qWarning("Scene Graph: This system does not support the REPEAT wrap mode for non-power-of-two textures."); } #endif funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_horizontalWrap == Repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE); funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_verticalWrap == Repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE); m_wrapChanged = false; } }
void tst_QOpenGL::textureblitterPartOriginTopLeftSourceRectTransform() { TestVertex3D topLeft(uv_top_left); TestVertex3D bottomLeft(uv_bottom_left); TestVertex3D topRight(uv_top_right); TestVertex3D bottomRight(uv_bottom_right); QRectF sourceRect(50,190,170,170); QSize textureSize(400,400); QMatrix3x3 sourceMatrix = QOpenGLTextureBlitter::sourceTransform(sourceRect, textureSize, QOpenGLTextureBlitter::OriginTopLeft); const float x_point_ratio = sourceRect.topLeft().x() / textureSize.width(); const float y_point_ratio = sourceRect.topLeft().y() / textureSize.height(); const float width_ratio = sourceRect.width() / textureSize.width(); const float height_ratio = sourceRect.height() / textureSize.height(); TestVertex3D uvTopLeft = sourceMatrix * topLeft; const float expected_top_left[] = { x_point_ratio, 1 - y_point_ratio - height_ratio, 1 }; TestVertex3D expectedTopLeft(expected_top_left); QVERIFY(q_fuzzy_compare(uvTopLeft, expectedTopLeft)); TestVertex3D uvBottomLeft = sourceMatrix * bottomLeft; const float expected_bottom_left[] = { x_point_ratio, 1 - y_point_ratio, 1 }; TestVertex3D expectedBottomLeft(expected_bottom_left); QVERIFY(q_fuzzy_compare(uvBottomLeft, expectedBottomLeft)); TestVertex3D uvTopRight = sourceMatrix * topRight; const float expected_top_right[] = { x_point_ratio + width_ratio, 1 - y_point_ratio - height_ratio, 1 }; TestVertex3D expectedTopRight(expected_top_right); QVERIFY(q_fuzzy_compare(uvTopRight, expectedTopRight)); TestVertex3D uvBottomRight = sourceMatrix * bottomRight; const float expected_bottom_right[] = { x_point_ratio + width_ratio, 1 - y_point_ratio, 1 }; TestVertex3D expectedBottomRight(expected_bottom_right); QVERIFY(q_fuzzy_compare(uvBottomRight, expectedBottomRight)); }
void CCTiledLayerImpl::appendQuads(CCQuadSink& quadSink, CCAppendQuadsData& appendQuadsData) { const IntRect& contentRect = visibleContentRect(); if (!m_tiler || m_tiler->hasEmptyBounds() || contentRect.isEmpty()) return; CCSharedQuadState* sharedQuadState = quadSink.useSharedQuadState(createSharedQuadState()); appendDebugBorderQuad(quadSink, sharedQuadState, appendQuadsData); int left, top, right, bottom; m_tiler->contentRectToTileIndices(contentRect, left, top, right, bottom); if (hasDebugBorders()) { for (int j = top; j <= bottom; ++j) { for (int i = left; i <= right; ++i) { DrawableTile* tile = tileAt(i, j); IntRect tileRect = m_tiler->tileBounds(i, j); SkColor borderColor; if (m_skipsDraw || !tile || !tile->resourceId()) borderColor = SkColorSetARGB(debugTileBorderAlpha, debugTileBorderMissingTileColorRed, debugTileBorderMissingTileColorGreen, debugTileBorderMissingTileColorBlue); else borderColor = SkColorSetARGB(debugTileBorderAlpha, debugTileBorderColorRed, debugTileBorderColorGreen, debugTileBorderColorBlue); quadSink.append(CCDebugBorderDrawQuad::create(sharedQuadState, tileRect, borderColor, debugTileBorderWidth).PassAs<CCDrawQuad>(), appendQuadsData); } } } if (m_skipsDraw) return; for (int j = top; j <= bottom; ++j) { for (int i = left; i <= right; ++i) { DrawableTile* tile = tileAt(i, j); IntRect tileRect = m_tiler->tileBounds(i, j); IntRect displayRect = tileRect; tileRect.intersect(contentRect); // Skip empty tiles. if (tileRect.isEmpty()) continue; if (!tile || !tile->resourceId()) { if (drawCheckerboardForMissingTiles()) { SkColor defaultColor = SkColorSetRGB(defaultCheckerboardColorRed, defaultCheckerboardColorGreen, defaultCheckerboardColorBlue); SkColor evictedColor = SkColorSetRGB(debugTileEvictedCheckerboardColorRed, debugTileEvictedCheckerboardColorGreen, debugTileEvictedCheckerboardColorBlue); SkColor invalidatedColor = SkColorSetRGB(debugTileInvalidatedCheckerboardColorRed, debugTileEvictedCheckerboardColorGreen, debugTileEvictedCheckerboardColorBlue); SkColor checkerColor; if (hasDebugBorders()) checkerColor = tile ? invalidatedColor : evictedColor; else checkerColor = defaultColor; appendQuadsData.hadMissingTiles |= quadSink.append(CCCheckerboardDrawQuad::create(sharedQuadState, tileRect, checkerColor).PassAs<CCDrawQuad>(), appendQuadsData); } else appendQuadsData.hadMissingTiles |= quadSink.append(CCSolidColorDrawQuad::create(sharedQuadState, tileRect, backgroundColor()).PassAs<CCDrawQuad>(), appendQuadsData); continue; } IntRect tileOpaqueRect = tile->opaqueRect(); tileOpaqueRect.intersect(contentRect); // Keep track of how the top left has moved, so the texture can be // offset the same amount. IntSize displayOffset = tileRect.minXMinYCorner() - displayRect.minXMinYCorner(); IntPoint textureOffset = m_tiler->textureOffset(i, j) + displayOffset; float tileWidth = static_cast<float>(m_tiler->tileSize().width()); float tileHeight = static_cast<float>(m_tiler->tileSize().height()); IntSize textureSize(tileWidth, tileHeight); bool clipped = false; FloatQuad visibleContentInTargetQuad = CCMathUtil::mapQuad(drawTransform(), FloatQuad(visibleContentRect()), clipped); bool isAxisAlignedInTarget = !clipped && visibleContentInTargetQuad.isRectilinear(); bool useAA = m_tiler->hasBorderTexels() && !isAxisAlignedInTarget; bool leftEdgeAA = !i && useAA; bool topEdgeAA = !j && useAA; bool rightEdgeAA = i == m_tiler->numTilesX() - 1 && useAA; bool bottomEdgeAA = j == m_tiler->numTilesY() - 1 && useAA; const GC3Dint textureFilter = m_tiler->hasBorderTexels() ? GraphicsContext3D::LINEAR : GraphicsContext3D::NEAREST; quadSink.append(CCTileDrawQuad::create(sharedQuadState, tileRect, tileOpaqueRect, tile->resourceId(), textureOffset, textureSize, textureFilter, contentsSwizzled(), leftEdgeAA, topEdgeAA, rightEdgeAA, bottomEdgeAA).PassAs<CCDrawQuad>(), appendQuadsData); } } }
void main() { #ifdef MULTISAMPLE ivec2 screensize =textureSize( g_depth /*,0*/ ); #else ivec2 screensize =textureSize( g_depth, 0 ); #endif ndc_position = ( gl_FragCoord.xy / screensize ) * vec2(1) - vec2(1); // Retrieve data from gbuffer #ifndef MULTISAMPLE //vec3 f_position = vec3(vec4(positionFromDepth( 0 ),1)); vec4 fragCoord =texture( g_position, ndc_position).rgba; vec3 f_normal = mat3(mat_view)*texture(g_normal, ndc_position).rgb; vec3 f_diffuse = texture(g_diffusespec, ndc_position).rgb; float f_specular = texture(g_diffusespec, ndc_position).a; #endif vec3 color =vec3(0); #ifdef MULTISAMPLE /* For MS, we average over all the samples */ for( int i=0; i < NUM_SAMPLES; i++ ) { vec4 fragCoord =texelFetch( g_position, ivec2(gl_FragCoord.xy), i).rgba; vec3 f_normal = mat3(mat_view) * texelFetch( g_normal, ivec2(gl_FragCoord.xy), i).rgb; vec3 f_diffuse = texelFetch( g_diffusespec, ivec2(gl_FragCoord.xy), i).rgb; float f_specular = texelFetch( g_diffusespec, ivec2(gl_FragCoord.xy), i).a; #endif /* Calculate the NDC from the stored fragCoord, then reconstruct the view-space position using the inverse projection matrix */ vec4 ndcPos; ndcPos.xy = ((2.0 * fragCoord.xy) - (2.0 * vec2(0))) / (screensize) - 1; ndcPos.z = (2.0 * fragCoord.z - gl_DepthRange.near - gl_DepthRange.far) / (gl_DepthRange.far - gl_DepthRange.near); ndcPos.w = 1.0; vec4 clipPos = ndcPos / fragCoord.w; vec3 f_position = vec3(mat_windowtoview * clipPos); float attenuation = 1.0; vec3 diffuse; vec3 specular; vec3 lighting = f_diffuse * 0.001; // hard-coded ambient component vec3 viewDir = normalize( - f_position); if( light_direction.xyz == vec3(0) ) { // assumes point-light // Diffuse vec3 lightDir = normalize(light_position - f_position); diffuse = max(dot(f_normal, lightDir), 0.0) * f_diffuse * light_intensity; // Specular vec3 halfwayDir = normalize(lightDir + viewDir); float spec = pow(max(dot(f_normal, halfwayDir), 0.0), 16.0); specular = light_intensity * spec * f_specular; // Attenuation float distance = length(light_position - f_position); attenuation = 1.0 / ( light_attenuation.x + // constant light_attenuation.y * distance + // linear light_attenuation.z * distance * distance); // quadratic } else { // directional light lighting = f_diffuse * 0.1; // DELETE ME vec3 lightDir = normalize(-light_direction); float diff = max(dot(f_normal, lightDir), 0.0); diffuse = light_intensity * diff * f_diffuse; // Specular vec3 reflectDir = reflect(-lightDir, f_normal); float spec = pow(max(dot(viewDir, reflectDir), 0.0), 16.0 ); specular = light_intensity * spec * f_specular; } diffuse *= attenuation; specular *= attenuation; lighting += diffuse + specular; #ifdef MULTISAMPLE color += (1.0 / NUM_SAMPLES) * lighting; } #else color =lighting; #endif fragColor = vec4(color, 1.0); }
float GradientSampler_GetStop( int i ) \n\ { \n\ float gradientMaxStops = float( textureSize( gradientSampler, 0 ) ); \n\ return texture( gradientSampler, i/gradientMaxStops )[0]; \n\ } \n\
void GraphicsContext3DPrivate::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity) { if (!m_glContext) return; ASSERT(m_renderStyle == GraphicsContext3D::RenderOffscreen); m_context->markLayerComposited(); // FIXME: We do not support mask for the moment with TextureMapperImageBuffer. if (textureMapper->accelerationMode() != TextureMapper::OpenGLMode) { GraphicsContext* context = textureMapper->graphicsContext(); context->save(); context->platformContext()->setGlobalAlpha(opacity); const int height = m_context->m_currentHeight; const int width = m_context->m_currentWidth; int totalBytes = width * height * 4; auto pixels = std::make_unique<unsigned char[]>(totalBytes); if (!pixels) return; // OpenGL keeps the pixels stored bottom up, so we need to flip the image here. context->translate(0, height); context->scale(FloatSize(1, -1)); context->concatCTM(matrix.toAffineTransform()); m_context->readRenderingResults(pixels.get(), totalBytes); // Premultiply alpha. for (int i = 0; i < totalBytes; i += 4) if (pixels[i + 3] != 255) { pixels[i + 0] = min(255, pixels[i + 0] * pixels[i + 3] / 255); pixels[i + 1] = min(255, pixels[i + 1] * pixels[i + 3] / 255); pixels[i + 2] = min(255, pixels[i + 2] * pixels[i + 3] / 255); } RefPtr<cairo_surface_t> imageSurface = adoptRef(cairo_image_surface_create_for_data( const_cast<unsigned char*>(pixels.get()), CAIRO_FORMAT_ARGB32, width, height, width * 4)); context->platformContext()->drawSurfaceToContext(imageSurface.get(), targetRect, IntRect(0, 0, width, height), context); context->restore(); return; } #if USE(TEXTURE_MAPPER_GL) if (m_context->m_attrs.antialias && m_context->m_state.boundFBO == m_context->m_multisampleFBO) { GLContext* previousActiveContext = GLContext::getCurrent(); if (previousActiveContext != m_glContext) m_context->makeContextCurrent(); m_context->resolveMultisamplingIfNecessary(); ::glBindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_context->m_state.boundFBO); if (previousActiveContext && previousActiveContext != m_glContext) previousActiveContext->makeContextCurrent(); } TextureMapperGL* texmapGL = static_cast<TextureMapperGL*>(textureMapper); TextureMapperGL::Flags flags = TextureMapperGL::ShouldFlipTexture | (m_context->m_attrs.alpha ? TextureMapperGL::ShouldBlend : 0); IntSize textureSize(m_context->m_currentWidth, m_context->m_currentHeight); texmapGL->drawTexture(m_context->m_texture, flags, textureSize, targetRect, matrix, opacity); #endif // USE(ACCELERATED_COMPOSITING_GL) }
std::vector<SpriteFramePtr> SpriteFrame::loadSpriteFrames(const std::string& filename, bool mipmaps) { std::vector<SpriteFramePtr> frames; std::vector<uint8_t> data; if (!sharedEngine->getFileSystem()->loadFile(filename, data)) { return frames; } rapidjson::MemoryStream is(reinterpret_cast<char*>(data.data()), data.size()); rapidjson::Document document; document.ParseStream<0>(is); if (document.HasParseError()) { log("Failed to parse %s", filename.c_str()); return frames; } const rapidjson::Value& metaObject = document["meta"]; const rapidjson::Value& sizeObject = metaObject["size"]; Size2 textureSize(static_cast<float>(sizeObject["w"].GetInt()), static_cast<float>(sizeObject["h"].GetInt())); graphics::TexturePtr texture = sharedEngine->getCache()->getTexture(metaObject["image"].GetString(), false, mipmaps); const rapidjson::Value& framesArray = document["frames"]; frames.reserve(framesArray.Size()); for (rapidjson::SizeType index = 0; index < framesArray.Size(); ++index) { const rapidjson::Value& frameObject = framesArray[index]; const rapidjson::Value& rectangleObject = frameObject["frame"]; Rectangle rectangle(static_cast<float>(rectangleObject["x"].GetInt()), static_cast<float>(rectangleObject["y"].GetInt()), static_cast<float>(rectangleObject["w"].GetInt()), static_cast<float>(rectangleObject["h"].GetInt())); bool rotated = frameObject["rotated"].GetBool(); const rapidjson::Value& sourceSizeObject = frameObject["sourceSize"]; Size2 sourceSize(static_cast<float>(sourceSizeObject["w"].GetInt()), static_cast<float>(sourceSizeObject["h"].GetInt())); const rapidjson::Value& spriteSourceSizeObject = frameObject["spriteSourceSize"]; Vector2 sourceOffset(static_cast<float>(spriteSourceSizeObject["x"].GetInt()), static_cast<float>(spriteSourceSizeObject["y"].GetInt())); const rapidjson::Value& pivotObject = frameObject["pivot"]; Vector2 pivot(pivotObject["x"].GetFloat(), pivotObject["y"].GetFloat()); frames.push_back(std::make_shared<SpriteFrame>(rectangle, texture, rotated, sourceSize, sourceOffset, pivot)); } return frames; }
vec4 GradientSampler_GetColor( int i ) \n\ { \n\ float gradientMaxStops = float( textureSize( gradientSampler, 0 ) ); \n\ return texture( gradientSampler, (i + gradientStops)/gradientMaxStops ); \n\ return texture( gradientSampler, 0.5 + i/gradientMaxStops ); \n\ } \n\
void Light::SetupShadowViews(Camera* mainCamera, Vector<AutoPtr<ShadowView> >& shadowViews, size_t& useIndex) { size_t numViews = NumShadowViews(); if (!numViews) return; if (shadowViews.Size() < useIndex + numViews) shadowViews.Resize(useIndex + numViews); int numVerticalSplits = (lightType == LIGHT_POINT || (lightType == LIGHT_DIRECTIONAL && NumShadowSplits() > 2)) ? 2 : 1; int actualShadowMapSize = shadowRect.Height() / numVerticalSplits; for (size_t i = 0; i < numViews; ++i) { if (!shadowViews[useIndex + i]) shadowViews[useIndex + i] = new ShadowView(); ShadowView* view = shadowViews[useIndex + i].Get(); view->Clear(); view->light = this; Camera& shadowCamera = view->shadowCamera; switch (lightType) { case LIGHT_DIRECTIONAL: { IntVector2 topLeft(shadowRect.left, shadowRect.top); if (i & 1) topLeft.x += actualShadowMapSize; if (i & 2) topLeft.y += actualShadowMapSize; view->viewport = IntRect(topLeft.x, topLeft.y, topLeft.x + actualShadowMapSize, topLeft.y + actualShadowMapSize); float splitStart = Max(mainCamera->NearClip(), (i == 0) ? 0.0f : ShadowSplit(i - 1)); float splitEnd = Min(mainCamera->FarClip(), ShadowSplit(i)); float extrusionDistance = mainCamera->FarClip(); // Calculate initial position & rotation shadowCamera.SetTransform(mainCamera->WorldPosition() - extrusionDistance * WorldDirection(), WorldRotation()); // Calculate main camera shadowed frustum in light's view space Frustum splitFrustum = mainCamera->WorldSplitFrustum(splitStart, splitEnd); const Matrix3x4& lightView = shadowCamera.ViewMatrix(); Frustum lightViewFrustum = splitFrustum.Transformed(lightView); // Fit the frustum inside a bounding box BoundingBox shadowBox; shadowBox.Define(lightViewFrustum); // If shadow camera is far away from the frustum, can bring it closer for better depth precision /// \todo The minimum distance is somewhat arbitrary float minDistance = mainCamera->FarClip() * 0.25f; if (shadowBox.min.z > minDistance) { float move = shadowBox.min.z - minDistance; shadowCamera.Translate(Vector3(0.0f, 0.f, move)); shadowBox.min.z -= move, shadowBox.max.z -= move; } shadowCamera.SetOrthographic(true); shadowCamera.SetFarClip(shadowBox.max.z); Vector3 center = shadowBox.Center(); Vector3 size = shadowBox.Size(); shadowCamera.SetOrthoSize(Vector2(size.x, size.y)); shadowCamera.SetZoom(1.0f); // Center shadow camera to the view space bounding box Vector3 pos(shadowCamera.WorldPosition()); Quaternion rot(shadowCamera.WorldRotation()); Vector3 adjust(center.x, center.y, 0.0f); shadowCamera.Translate(rot * adjust, TS_WORLD); // Snap to whole texels { Vector3 viewPos(rot.Inverse() * shadowCamera.WorldPosition()); float invSize = 1.0f / actualShadowMapSize; Vector2 texelSize(size.x * invSize, size.y * invSize); Vector3 snap(-fmodf(viewPos.x, texelSize.x), -fmodf(viewPos.y, texelSize.y), 0.0f); shadowCamera.Translate(rot * snap, TS_WORLD); } } break; case LIGHT_POINT: { static const Quaternion pointLightFaceRotations[] = { Quaternion(0.0f, 90.0f, 0.0f), Quaternion(0.0f, -90.0f, 0.0f), Quaternion(-90.0f, 0.0f, 0.0f), Quaternion(90.0f, 0.0f, 0.0f), Quaternion(0.0f, 0.0f, 0.0f), Quaternion(0.0f, 180.0f, 0.0f) }; IntVector2 topLeft(shadowRect.left, shadowRect.top); if (i & 1) topLeft.y += actualShadowMapSize; topLeft.x += ((unsigned)i >> 1) * actualShadowMapSize; view->viewport = IntRect(topLeft.x, topLeft.y, topLeft.x + actualShadowMapSize, topLeft.y + actualShadowMapSize); shadowCamera.SetTransform(WorldPosition(), pointLightFaceRotations[i]); shadowCamera.SetFov(90.0f); // Adjust zoom to avoid edge sampling artifacts (there is a matching adjustment in the shadow sampling) shadowCamera.SetZoom(0.99f); shadowCamera.SetFarClip(Range()); shadowCamera.SetNearClip(Range() * 0.01f); shadowCamera.SetOrthographic(false); shadowCamera.SetAspectRatio(1.0f); } break; case LIGHT_SPOT: view->viewport = shadowRect; shadowCamera.SetTransform(WorldPosition(), WorldRotation()); shadowCamera.SetFov(fov); shadowCamera.SetZoom(1.0f); shadowCamera.SetFarClip(Range()); shadowCamera.SetNearClip(Range() * 0.01f); shadowCamera.SetOrthographic(false); shadowCamera.SetAspectRatio(1.0f); break; } } // Setup shadow matrices now as camera positions have been finalized if (lightType != LIGHT_POINT) { shadowMatrices.Resize(numViews); for (size_t i = 0; i < numViews; ++i) { ShadowView* view = shadowViews[useIndex + i].Get(); Camera& shadowCamera = view->shadowCamera; float width = (float)shadowMap->Width(); float height = (float)shadowMap->Height(); Vector3 offset((float)view->viewport.left / width, (float)view->viewport.top / height, 0.0f); Vector3 scale(0.5f * (float)view->viewport.Width() / width, 0.5f * (float)view->viewport.Height() / height, 1.0f); offset.x += scale.x; offset.y += scale.y; scale.y = -scale.y; // OpenGL has different depth range #ifdef TURSO3D_OPENGL offset.z = 0.5f; scale.z = 0.5f; #endif Matrix4 texAdjust(Matrix4::IDENTITY); texAdjust.SetTranslation(offset); texAdjust.SetScale(scale); shadowMatrices[i] = texAdjust * shadowCamera.ProjectionMatrix() * shadowCamera.ViewMatrix(); } } else { // Point lights use an extra constant instead shadowMatrices.Clear(); Vector2 textureSize((float)shadowMap->Width(), (float)shadowMap->Height()); pointShadowParameters = Vector4(actualShadowMapSize / textureSize.x, actualShadowMapSize / textureSize.y, (float)shadowRect.left / textureSize.x, (float)shadowRect.top / textureSize.y); } // Calculate shadow mapping constants Camera& shadowCamera = shadowViews[useIndex]->shadowCamera; float nearClip = shadowCamera.NearClip(); float farClip = shadowCamera.FarClip(); float q = farClip / (farClip - nearClip); float r = -q * nearClip; shadowParameters = Vector4(0.5f / (float)shadowMap->Width(), 0.5f / (float)shadowMap->Height(), q, r); useIndex += numViews; }