{"id":3248,"date":"2026-09-12T22:19:48","date_gmt":"2026-09-12T22:19:48","guid":{"rendered":"https:\/\/yazilimperver.net\/?p=3248"},"modified":"2026-09-12T22:19:48","modified_gmt":"2026-09-12T22:19:48","slug":"sdl-painter-resim-cizimi-faz-2","status":"publish","type":"post","link":"https:\/\/yazilimperver.net\/index.php\/2026\/09\/12\/sdl-painter-resim-cizimi-faz-2\/","title":{"rendered":"sdl-painter \u2013 Resim \u00c7izimi (faz-2)"},"content":{"rendered":"<div>Sevgili yaz\u0131l\u0131mperver dostlar\u0131m, tekrar merhaba.<\/div>\n<div>\u00d6nceki yaz\u0131lar\u0131mda, altyap\u0131ya g\u00f6z att\u0131k, temel \u015fekilleri \u00e7izdik ve d\u00f6n\u00fc\u015f\u00fcm y\u0131\u011f\u0131n\u0131yla bu \u015fekillere raks ettirdik.<\/div>\n<div><span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/yazilimperver.net\/index.php\/2026\/07\/03\/sdl-painter-proje-altyapisi-faz-0\/\">sdl-painter &#8211; Proje Altyap\u0131s\u0131 (faz-0)<\/a><\/strong><\/span><\/div>\n<div><span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/yazilimperver.net\/index.php\/2026\/08\/04\/sdl-painter-proje-altyapisi-devam-faz-0-ci-cd\/\">sdl-painter &#8211; Proje Altyap\u0131s\u0131(faz 0) &#8211; CI\/CD<\/a><\/strong><\/span><\/div>\n<div><span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/yazilimperver.net\/index.php\/2026\/08\/29\/sdl-painter-temel-sekiller-ve-kabiliyetler-faz-1\/\">sdl-painter \u2013 Temel \u015eekiller ve Kabiliyetler (faz-1)<\/a><\/strong><\/span><\/div>\n<div><span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/yazilimperver.net\/index.php\/2026\/09\/06\/sdl-painter-transformasyonlar-faz-2\/\">sdl-painter \u2013 Transformasyonlar (faz-2)<\/a><\/strong><\/span><\/div>\n<div><\/div>\n<div>Bu yaz\u0131da ise s\u0131ra resimlerde, bir dosyadan okudu\u011fumuz ya da kodla \u00fcretti\u011fimiz pikselleri ekrana nas\u0131l ta\u015f\u0131yoruz sorusunun cevab\u0131n\u0131 arayaca\u011f\u0131z. \u00d6zellikle oyun benzeri uygulamalarda en \u00e7ok ihtiya\u00e7 duyulan kabiliyetlerden birisi de resimlerin \u00e7izdirilmesidir. Burada temel kabiliyetlere de\u011finece\u011fim, muhtemelen sonraki yaz\u0131lar\u0131mda, \u00f6zellikle oyunlar\u0131n\u0131z i\u00e7in sizlere faydal\u0131 olaca\u011f\u0131n\u0131 d\u00fc\u015f\u00fcnd\u00fc\u011f\u00fcm bir tak\u0131m ek yetenekleri de sizlerle k\u0131sa k\u0131sa payla\u015faca\u011f\u0131m (merak edenler i\u00e7in repodaki \u00f6rneklerde bunlar var \ud83d\ude09 bu arada )<\/div>\n<div><\/div>\n<div>SDLPainter&#8217;da bu i\u015fin iki ciheti var ve bu yaz\u0131mda bunlar\u0131 belirli kavramlar ile ifade etmeye \u00e7al\u0131\u015faca\u011f\u0131m. `<strong>Image<\/strong>`, piksel verisini ana bellekte tutuyor; `<strong>Texture<\/strong>` ise \u00e7izim altyap\u0131m\u0131z\u0131n (backend) olu\u015fturdu\u011fu GPU&#8217;daki dokusunun sahipli\u011fini y\u00f6netiyor. `<strong>Painter::DrawImage<\/strong>` ise bu ikisini bir araya getiriyor.<\/div>\n<div><\/div>\n<div>Faz 3&#8217;\u00fcn temel tasar\u0131m\u0131n\u0131 anlat\u0131rken g\u00fcncel uygulamadaki filtreleme, renk tonlama, aynalama ve doku g\u00fcncelleme \u00f6zelliklerine de yeri geldik\u00e7e de\u011finece\u011fim.<\/div>\n<div><\/div>\n<h2><span style=\"color: #0000ff;\"><strong>Neden stb_image?<\/strong><\/span><\/h2>\n<div>\u0130lk konu resim dosyalar\u0131n\u0131 nas\u0131l y\u00fckleyece\u011fimiz. uEngine&#8217;de SDL_Image kullanm\u0131\u015ft\u0131m, onun \u00f6ncesinde de DevIL k\u00fct\u00fcphanesini kullanm\u0131\u015ft\u0131m.<\/div>\n<div>A\u00e7\u0131k\u00e7as\u0131 bu k\u00fct\u00fcphanede, h\u0131zl\u0131ca bu kabiliyeti kazand\u0131rmak ad\u0131na stb_image&#8217;i kullanmaya karar verdim (<span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/github.com\/yazilimperver\/sdl-painter\/blob\/main\/adr\/ADR-005-stb-image-vs-sdl-image.md\">ADR-005<\/a><\/strong><\/span>). Temel ihtiyac\u0131m\u0131z basit: PNG ve JPEG gibi dosyalar\u0131 okuyup piksel verisini `IRenderer` aray\u00fcz\u00fcne iletmek.<\/div>\n<div><\/div>\n<div>`stb_image` tek ba\u015fl\u0131k dosyas\u0131ndan olu\u015fuyor ve kullanmak i\u00e7in a\u015fa\u011f\u0131daki tan\u0131m yapmak yeterli. K\u00fct\u00fcphanemde bunu `src\/image.cpp` i\u00e7erisinde tan\u0131mlad\u0131m:<\/div>\n<div>\n<pre class=\"lang:c++ decode:true \">#define STB_IMAGE_IMPLEMENTATION\r\n#include &lt;stb_image.h&gt;<\/pre>\n<p>Bu kullan\u0131m, ayr\u0131ca libpng veya libjpeg ba\u011flamay\u0131 gerektirmiyor. Projede `stb` yi conan \u00fczerinden kullan\u0131yorum, bu sebeple de kurulum kolay. Entegrasyon detaylar\u0131 i\u00e7in <span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/raw.githubusercontent.com\/nothings\/stb\/master\/stb_image.h\">stb_image kaynak dosyas\u0131<\/a><\/strong><\/span> dok\u00fcman\u0131na ba\u015fvurulabilir.<\/p>\n<\/div>\n<div>`SDL_image` da elbette kullan\u0131labilirdi (ileride belki kullan\u0131r\u0131z, daha \u00f6nce kulland\u0131m),\u00a0 ancak onun `SDL_Surface` tabanl\u0131 \u00e7\u0131kt\u0131s\u0131, do\u011frudan ham piksellerle \u00e7al\u0131\u015fan bu g\u00f6r\u00fcnt\u00fc y\u00fckleme yolunda ek bir avantaj bize sa\u011flam\u0131yor gibiydi.<\/div>\n<h3><span style=\"color: #0000ff;\"><strong>Image: Pikseller Ana Bellekte<\/strong><\/span><\/h3>\n<div>Bir g\u00f6r\u00fcnt\u00fcy\u00fc dosyadan olu\u015fturmak i\u00e7in a\u015fa\u011f\u0131daki kod par\u00e7as\u0131n\u0131 kullan\u0131yoruz:<\/div>\n<pre class=\"lang:c++ decode:true \">sdl_painter::Image image(\"assets\/resim.png\");\r\nif (!image.IsValid()) {\r\n\u00a0 \/\/ Y\u00fckleme ba\u015far\u0131s\u0131z\r\n}<\/pre>\n<div>Bu a\u015famada dosya okunup \u00e7\u00f6z\u00fcl\u00fcyor, fakat GPU&#8217;ya doku\/texture&#8217;u hen\u00fcz aktarmad\u0131k. Resim okunmadan, `<strong>stbi_load<\/strong>` \u00e7a\u011fr\u0131s\u0131ndan \u00f6nce, `<strong>stbi_info<\/strong>` ile boyutlar\u0131 kontrol ediyoruz ve toplam piksel s\u0131n\u0131r\u0131n\u0131 burada kontrol ediyoruz. Okuma ya da \u00e7\u00f6zme ba\u015far\u0131s\u0131z oldu\u011funda da hata veriyoruz; bu durum da `<strong>IsValid()<\/strong>` ile sorgulanabilir. Bu tarz kontroller, sizleri erkenden haberdar etme a\u00e7\u0131s\u0131ndan \u00f6nemli.<\/div>\n<div><\/div>\n<div>Boyutlar\u0131 `<strong>Width()<\/strong>` ve `<strong>Height()<\/strong>`, kanal say\u0131s\u0131n\u0131 `<strong>Channels()<\/strong>`, piksel verisini ise `<strong>RawData()<\/strong>` ile sorgulayabiliyoruz. `<strong>Image<\/strong>` kopyalanam\u0131yor, ancak ta\u015f\u0131nabiliyor.<\/div>\n<div><\/div>\n<div>`<strong>CreateFromData<\/strong>`, kodla \u00fcretilen veya ba\u015fka bir kaynaktan gelen pikseller i\u00e7in kullan\u0131yoruz. Veriyi kopyalad\u0131\u011f\u0131 i\u00e7in, \u00e7a\u011f\u0131ran\u0131n tamponunu daha sonra serbest b\u0131rak\u0131labilirsiniz. Burada kanal kanal say\u0131lar\u0131 (1, 2, 3 ve 4); tamponun en az `width \u00d7 height \u00d7 channels` byte i\u00e7ermesi ve sat\u0131rlar\u0131n arada bo\u015fluk olmadan s\u0131\u011fmas\u0131 gerekiyor.<\/div>\n<div><\/div>\n<div>\u0130\u00e7eride piksel verisi, \u00f6zel destructor (<strong>StbDeleter<\/strong>)&#8217;a sahip bir `std::unique_ptr` ile tutuluyor. Destructor `stbi_image_free` \u00e7a\u011f\u0131r\u0131yor. Projenin mevcut ayarlar\u0131nda hem `stbi_load` hem de `CreateFromData` i\u00e7in kullan\u0131lan `malloc` bu serbest b\u0131rakma y\u00f6ntemiyle uyumlu.<\/div>\n<div><\/div>\n<div>`<strong>IsValid()<\/strong>` yaln\u0131zca ana bellekte piksel verisi bulundu\u011funu g\u00f6sterir. GPU&#8217;ya y\u00fcklemenin ba\u015far\u0131l\u0131 olup olmad\u0131\u011f\u0131 ayr\u0131 bir konu; `<strong>Upload<\/strong>` ba\u015far\u0131s\u0131z olursa `<strong>kInvalidTexture<\/strong>` d\u00f6nd\u00fcr\u00fcl\u00fcyor.<\/div>\n<div><\/div>\n<h3><span style=\"color: #0000ff;\"><strong>Texture: GPU Kayna\u011f\u0131n\u0131n Sahibi<\/strong><\/span><\/h3>\n<div>`<strong>TextureHandle<\/strong>`, k\u00fct\u00fcphane aray\u00fcz\u00fcnde `<strong>uint32_t<\/strong>` tabanl\u0131 bir tan\u0131mlay\u0131c\u0131s\u0131. Bu OpenGL taraf\u0131nda bir doku kimli\u011fine kar\u015f\u0131l\u0131k geliyor. `<strong>Texture<\/strong>`, bu tan\u0131mlay\u0131c\u0131y\u0131 onu olu\u015fturan `<strong>IRenderer<\/strong>` ile birlikte tutuyor. RAII tasar\u0131m\u0131n\u0131n ilgili k\u0131s\u0131mlar\u0131 \u015f\u00f6yle:<\/div>\n<div>\n<pre class=\"lang:c++ decode:true \">class Texture {\r\n public:\r\n  explicit Texture(IRenderer* renderer = nullptr) : mRenderer(renderer) {}\r\n  Texture(IRenderer* renderer, TextureHandle handle)\r\n      : mRenderer(renderer), mHandle(handle) {}\r\n\r\n  ~Texture() { Reset(); }\r\n\r\n  Texture(const Texture&amp;) = delete;\r\n  Texture&amp; operator=(const Texture&amp;) = delete;\r\n  Texture(Texture&amp;&amp; other) noexcept;\r\n  Texture&amp; operator=(Texture&amp;&amp; other) noexcept;\r\n\r\n  void Reset() {\r\n    if (mRenderer != nullptr &amp;&amp; mHandle != kInvalidTexture) {\r\n      mRenderer-&gt;DestroyTexture(mHandle);\r\n    }\r\n    mHandle = kInvalidTexture;\r\n    mRenderer = nullptr;\r\n  }\r\n\r\n  TextureHandle Handle() const noexcept { return mHandle; }\r\n  IRenderer* Owner() const noexcept { return mRenderer; }\r\n  bool IsValid() const noexcept { return mHandle != kInvalidTexture; }\r\n\r\n private:\r\n  IRenderer* mRenderer{nullptr};\r\n  TextureHandle mHandle{kInvalidTexture};\r\n};\r\n<\/pre>\n<p>Kopyalama yapm\u0131yoruz; ta\u015f\u0131ma (*move*) ile sahipli\u011fi devrediyoruz. B\u00f6ylece ayn\u0131 GPU kayna\u011f\u0131n\u0131 iki nesnenin ayr\u0131 ayr\u0131 silmesinin \u00f6n\u00fcne ge\u00e7meyi hedefledim.<\/p>\n<\/div>\n<div>`<strong>Texture<\/strong>`, ham bir `<strong>IRenderer<\/strong>*` tutuyor. GPU&#8217;ya y\u00fcklenmi\u015f bir `<strong>Image<\/strong>`, onu y\u00fckleyen renderer yok edilmeden \u00f6nce yok etmeli. \u00c7izimler de g\u00f6r\u00fcnt\u00fc yok edilmeden \u00f6nce `<strong>End()<\/strong>` ile tamamlanmal\u0131. Pratikte, ge\u00e7erli bir SDL penceresi i\u00e7in \u015fu bildirim s\u0131ras\u0131n\u0131 takip ediyoruz:<\/div>\n<div><\/div>\n<div>\n<pre class=\"lang:c++ decode:true \">{\r\n  sdl_painter::Painter painter(window, sdl_painter::RendererBackend::kOpenGL);\r\n  sdl_painter::Image image(\"assets\/resim.png\");\r\n\r\n  if (painter.IsValid() &amp;&amp; image.IsValid()) {\r\n    painter.Begin();\r\n    painter.DrawImage(image, 50.0f, 80.0f);\r\n    painter.End();\r\n  }\r\n}  \/\/ \u00d6nce image, ard\u0131ndan painter yok edilir.\r\n<\/pre>\n<p>Bu tarz kaynaklar\u0131n ya\u015fm d\u00f6ng\u00fclerini takip etme, \u00f6zellikle bu tarz grafik uygulamalar\u0131 i\u00e7in kritik. \u0130leride benzer kaynaklar i\u00e7in bu konulara yine de\u011finiyor olaca\u011f\u0131m.<\/p>\n<\/div>\n<h3><span style=\"color: #0000ff;\"><strong>GPU Y\u00fckleme ve Filtre Se\u00e7imi<\/strong><\/span><\/h3>\n<div>`<strong>DrawImage<\/strong>`, \u00e7izimden \u00f6nce `<strong>Image::Upload<\/strong>` \u00e7a\u011f\u0131r\u0131yor. Tabi daha \u00f6nce bu resmi GPU&#8217;ya aktarm\u0131\u015fsak, yeniden y\u00fcklemiyoruz:<\/div>\n<div>\n<pre class=\"lang:c++ decode:true \">TextureHandle Image::Upload(IRenderer&amp; renderer) const {\r\n  if (!IsValid()) {\r\n    return kInvalidTexture;\r\n  }\r\n\r\n  if (mHandle.IsValid() &amp;&amp; mHandle.Owner() != &amp;renderer) {\r\n    mHandle.Reset();\r\n  }\r\n\r\n  if (!mHandle.IsValid()) {\r\n    mHandle = Texture(\r\n        &amp;renderer,\r\n        renderer.CreateTexture(mRawData.get(), mWidth, mHeight,\r\n                               mChannels, mFilter));\r\n  }\r\n\r\n  return mHandle.Handle();\r\n}\r\n<\/pre>\n<\/div>\n<div>Bu bize neyi sa\u011fl\u0131yor, hi\u00e7 \u00e7izilmeyen bir g\u00f6r\u00fcnt\u00fc GPU dokusu\/kayna\u011f\u0131 t\u00fcketmiyor. Y\u00fcklemeden sonra ana bellekteki piksel kopyas\u0131 da korunuyor.<\/div>\n<div>A\u015fa\u011f\u0131da buraya kadar olan ak\u0131\u015f\u0131 YZ&#8217;nin de yard\u0131m\u0131 ile g\u00f6rselle\u015ftirilmi\u015f halini g\u00f6rebilirsiniz (\u00e7ok iyi de\u011fil mi \ud83d\ude42 )<\/div>\n<div><\/div>\n<div id=\"attachment_3250\" style=\"width: 854px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3250\" class=\" wp-image-3250\" src=\"https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bd46a80ff.png\" alt=\"\" width=\"844\" height=\"468\" srcset=\"https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bd46a80ff.png 1504w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bd46a80ff-300x166.png 300w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bd46a80ff-1024x568.png 1024w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bd46a80ff-768x426.png 768w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bd46a80ff-500x277.png 500w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bd46a80ff-150x83.png 150w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bd46a80ff-1200x665.png 1200w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bd46a80ff-400x222.png 400w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bd46a80ff-800x444.png 800w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bd46a80ff-200x111.png 200w\" sizes=\"auto, (max-width: 844px) 100vw, 844px\" \/><p id=\"caption-attachment-3250\" class=\"wp-caption-text\">Pikseller Image olu\u015fturulurken haz\u0131rlan\u0131r; GPU dokusu ilk y\u00fcklemede olu\u015fturulur ve sonraki \u00e7izimlerde yeniden kullan\u0131l\u0131r.<\/p><\/div>\n<div><\/div>\n<div>`<strong>Image<\/strong>` tek bir GPU dokusunu \u00f6nbelle\u011fe al\u0131yor. Farkl\u0131 bir renderer ile kullan\u0131l\u0131rsa eskisini b\u0131rak\u0131p ana bellekteki veriden yeni bir doku olu\u015fturuluyor. Bu ge\u00e7i\u015f s\u0131ras\u0131nda eski renderer da h\u00e2l\u00e2 ge\u00e7erli olmal\u0131 tabi. Bu durumun \u00e7ok olmayaca\u011f\u0131n\u0131 \u00f6n g\u00f6r\u00fcyorum.<\/div>\n<div><\/div>\n<div>Filtreyi ise yine ilk y\u00fcklemeden \u00f6nce se\u00e7iyoruz:<\/div>\n<pre class=\"lang:c++ decode:true \">sdl_painter::Image sprite(\"assets\/karakter.png\");\r\nsprite.SetFilter(sdl_painter::TextureFilter::kNearest);<\/pre>\n<div>Varsay\u0131lan `<strong>kLinear<\/strong>`, \u00f6rnekler aras\u0131nda yumu\u015fak ge\u00e7i\u015f sa\u011fl\u0131yor. `<strong>kNearest<\/strong>` ise doku b\u00fcy\u00fct\u00fcl\u00fcrken keskin kenarlar\u0131 korumak i\u00e7in kullan\u0131\u015fl\u0131. \u0130lk \u00e7izimden sonra `<strong>SetFilter<\/strong>` \u00e7a\u011f\u0131rmak, \u00f6nbellekteki GPU dokusunun filtresini de\u011fi\u015ftirmez. `<strong>UpdateImage<\/strong>` da ilk y\u00fcklemeyi tetikleyebildi\u011finden filtreyi ondan \u00f6nce ayarlamak \u00f6nemli.<\/div>\n<div id=\"attachment_3251\" style=\"width: 846px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3251\" class=\" wp-image-3251\" src=\"https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bdd28b59e.png\" alt=\"\" width=\"836\" height=\"445\" srcset=\"https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bdd28b59e.png 1542w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bdd28b59e-300x160.png 300w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bdd28b59e-1024x545.png 1024w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bdd28b59e-768x408.png 768w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bdd28b59e-1536x817.png 1536w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bdd28b59e-500x266.png 500w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bdd28b59e-150x80.png 150w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bdd28b59e-1200x638.png 1200w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bdd28b59e-400x213.png 400w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bdd28b59e-800x425.png 800w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bdd28b59e-200x106.png 200w\" sizes=\"auto, (max-width: 836px) 100vw, 836px\" \/><p id=\"caption-attachment-3251\" class=\"wp-caption-text\">Ayn\u0131 24 \u00d7 24 g\u00f6r\u00fcnt\u00fcn\u00fcn 16 kat b\u00fcy\u00fct\u00fclm\u00fc\u015f h\u00e2li: kNearest piksel kenarlar\u0131n\u0131 korurken kLinear kom\u015fu \u00f6rnekler aras\u0131nda ge\u00e7i\u015f olu\u015fturur.<\/p><\/div>\n<div><\/div>\n<div>Bu konuya y\u00f6nelik daha detayl\u0131 bilgiler i\u00e7in <span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/learnopengl.com\/Getting-started\/Textures\">https:\/\/learnopengl.com\/Getting-started\/Textures<\/a><\/strong><\/span> adresine de bir g\u00f6z atabilirsiniz.<\/div>\n<h2><span style=\"color: #0000ff;\"><strong>OpenGL&#8217;de Doku Olu\u015fturma<\/strong><\/span><\/h2>\n<div>`<strong>stbi_load<\/strong>` \u00e7a\u011fr\u0131s\u0131nda istenen kanal say\u0131s\u0131 `0` b\u0131rak\u0131ld\u0131\u011f\u0131 i\u00e7in \u00e7\u0131kt\u0131 zorla RGBA&#8217;ya d\u00f6n\u00fc\u015ft\u00fcr\u00fclm\u00fcyor. Dosya uzant\u0131s\u0131ndan kanal say\u0131s\u0131 \u00e7\u0131karmak yerine `<strong>Channels<\/strong>()` de\u011ferini kullan\u0131yoruz. G\u00fcncel OpenGL e\u015flemesi \u015f\u00f6yle:<\/div>\n<div><\/div>\n<div>\n<table class=\"code-line\" dir=\"auto\" data-line=\"165\">\n<thead class=\"code-line\" dir=\"auto\" data-line=\"165\">\n<tr class=\"code-line\" dir=\"auto\" data-line=\"165\">\n<th>Kanal say\u0131s\u0131<\/th>\n<th>Piksel i\u00e7eri\u011fi<\/th>\n<th>OpenGL format\u0131<\/th>\n<th>Shader&#8217;\u0131n g\u00f6rd\u00fc\u011f\u00fc RGBA<\/th>\n<\/tr>\n<\/thead>\n<tbody class=\"code-line\" dir=\"auto\" data-line=\"167\">\n<tr class=\"code-line\" dir=\"auto\" data-line=\"167\">\n<td>1<\/td>\n<td>Gri<\/td>\n<td><code>GL_RED<\/code><\/td>\n<td><code>(gri, gri, gri, 1)<\/code><\/td>\n<\/tr>\n<tr class=\"code-line\" dir=\"auto\" data-line=\"168\">\n<td>2<\/td>\n<td>Gri ve alfa<\/td>\n<td><code>GL_RG<\/code><\/td>\n<td><code>(gri, gri, gri, alfa)<\/code><\/td>\n<\/tr>\n<tr class=\"code-line\" dir=\"auto\" data-line=\"169\">\n<td>3<\/td>\n<td>RGB<\/td>\n<td><code>GL_RGB<\/code><\/td>\n<td><code>(r, g, b, 1)<\/code><\/td>\n<\/tr>\n<tr class=\"code-line\" dir=\"auto\" data-line=\"170\">\n<td>4<\/td>\n<td>RGBA<\/td>\n<td><code>GL_RGBA<\/code><\/td>\n<td><code>(r, g, b, a)<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div><\/div>\n<div>Bir ve iki kanall\u0131 dokularda bu sonu\u00e7, OpenGL&#8217;in kanal e\u015fleme ayar\u0131yla elde ediliyor. \u00d6rne\u011fin gri ve alfa i\u00e7eren dokuda:<\/div>\n<pre class=\"lang:c++ decode:true \">const std::array&lt;GLint, 4&gt; swizzle = {\r\n\u00a0 \u00a0 GL_RED, GL_RED, GL_RED, GL_GREEN};\r\nglTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle.data());<\/pre>\n<div><strong>Not:<\/strong> Vulkan taraf\u0131nda ayn\u0131 anlam\u0131 korumak i\u00e7in 1, 2 ve 3 kanall\u0131 veriyi y\u00fcklemeden \u00f6nce RGBA&#8217;ya geni\u015fletiliyor.<\/div>\n<div>`<strong>CreateTexture<\/strong>` i\u00e7inden, doku ba\u011fland\u0131ktan ve kanal format\u0131 se\u00e7ildikten sonra \u00e7al\u0131\u015fan ilgili b\u00f6l\u00fcm:<\/div>\n<div>\n<pre class=\"lang:c++ decode:true\">GLint prev_alignment = 4;\r\nglGetIntegerv(GL_UNPACK_ALIGNMENT, &amp;prev_alignment);\r\nglPixelStorei(GL_UNPACK_ALIGNMENT, 1);\r\n\r\nconst GLint gl_filter =\r\n    (filter == TextureFilter::kNearest) ? GL_NEAREST : GL_LINEAR;\r\nglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter);\r\nglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter);\r\nglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);\r\nglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);\r\n\r\n\/\/ 1 ve 2 kanall\u0131 dokular\u0131n swizzle ayar\u0131 da y\u00fcklemeden \u00f6nce yap\u0131l\u0131r.\r\nglTexImage2D(GL_TEXTURE_2D, 0, static_cast&lt;GLint&gt;(format), width, height, 0,\r\n             format, GL_UNSIGNED_BYTE, data);\r\n\r\nglPixelStorei(GL_UNPACK_ALIGNMENT, prev_alignment);\r\nglBindTexture(GL_TEXTURE_2D, 0);<\/pre>\n<\/div>\n<div>`<strong>GL_CLAMP_TO_EDGE<\/strong>`, dokunun d\u0131\u015f kenar\u0131ndaki \u00f6rneklemeyi kenar pikselleriyle s\u0131n\u0131rlar. Ancak bir atlas\u0131n i\u00e7indeki sprite s\u0131n\u0131rlar\u0131n\u0131 bilmez; do\u011frusal filtrelemede kom\u015fu dilimlerin renkleri birbirine kar\u0131\u015fabilir. Atlas haz\u0131rlarken dilimler aras\u0131nda pay b\u0131rakmak veya kullan\u0131ma g\u00f6re `<strong>kNearest<\/strong>` se\u00e7mek bu nedenle \u00f6nemlidir. Spritesheet&#8217;lere bakarken bu \u00f6nemli olacak ama bu yaz\u0131 i\u00e7in yeterli.<\/div>\n<div><\/div>\n<h2><span style=\"color: #0000ff;\"><strong>DrawImage ve UV Koordinatlar\u0131<\/strong><\/span><\/h2>\n<div>`<strong>DrawImage<\/strong>` \u00fc\u00e7 overloaded API sunuyor:<\/div>\n<div>\n<pre class=\"lang:c++ decode:true \">using namespace sdl_painter;\r\n\r\npainter.DrawImage(image, 50.0f, 80.0f);            \/\/ \u00d6zg\u00fcn boyutu ile verilen konuma (sol \u00fcst k\u00f6\u015fe) g\u00f6re \u00e7izer\r\npainter.DrawImage(image, Rect{210, 80, 180, 180}); \/\/ Hedefe verilen rect'e g\u00f6re \u00f6l\u00e7ekleyerek \u00e7izer\r\npainter.DrawImage(atlas, Rect{0, 0, 128, 128},     \/\/ Kaynak dilim\r\n                         Rect{420, 80, 100, 100}); \/\/ Hedef dikd\u00f6rtgen\r\n<\/pre>\n<p>Hedef dikd\u00f6rtgene \u00f6l\u00e7ekleme en-boy oran\u0131n\u0131 kendili\u011finden korumuyor. Kaynak dikd\u00f6rtgen ise piksel cinsinden veriliyor ve normalle\u015ftirilmi\u015f doku koordinatlar\u0131na, yani UV&#8217;lere d\u00f6n\u00fc\u015ft\u00fcr\u00fcl\u00fcyor:<\/p>\n<\/div>\n<div>\n<pre class=\"lang:c++ decode:true \">u0 = src.x \/ image.Width()\r\nv0 = src.y \/ image.Height()\r\nu1 = (src.x + src.w) \/ image.Width()\r\nv1 = (src.y + src.h) \/ image.Height()<\/pre>\n<p>\u00d6rne\u011fin 256 \u00d7 256 bir atlas\u0131n sol \u00fcst 128 \u00d7 128 b\u00f6lgesi, `(0, 0)` ile `(0.5, 0.5)` aras\u0131na kar\u015f\u0131l\u0131k geliyor. Hesaplama ger\u00e7ek kodda float tipi de\u011ferlere g\u00f6re yap\u0131l\u0131yor. B\u00f6ylece tek dokunun farkl\u0131 b\u00f6lgelerini ayr\u0131 g\u00f6r\u00fcnt\u00fcler gibi \u00e7izebiliyoruz.<\/p>\n<\/div>\n<div id=\"attachment_3253\" style=\"width: 945px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3253\" class=\" wp-image-3253\" src=\"https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c060777e2.png\" alt=\"\" width=\"935\" height=\"502\" srcset=\"https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c060777e2.png 1540w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c060777e2-300x161.png 300w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c060777e2-1024x550.png 1024w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c060777e2-768x412.png 768w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c060777e2-1536x825.png 1536w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c060777e2-500x269.png 500w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c060777e2-150x81.png 150w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c060777e2-1200x644.png 1200w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c060777e2-400x215.png 400w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c060777e2-800x430.png 800w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c060777e2-200x107.png 200w\" sizes=\"auto, (max-width: 935px) 100vw, 935px\" \/><p id=\"caption-attachment-3253\" class=\"wp-caption-text\">256 \u00d7 256 atlas\u0131n sol \u00fcst 128 \u00d7 128 b\u00f6lgesi, (0, 0)\u2013(0.5, 0.5) UV aral\u0131\u011f\u0131ndan 100 \u00d7 100 hedefe \u00e7iziliyor.<\/p><\/div>\n<div><\/div>\n<div>\u00dc\u00e7 \u00e7a\u011fr\u0131 da sonunda `<strong>PushTexturedQuad<\/strong>` yard\u0131mc\u0131 API&#8217;sini kullan\u0131yor. G\u00fcncel uygulamada bu yard\u0131mc\u0131 UV&#8217;leri aynalama se\u00e7imine g\u00f6re d\u00fczenliyor; iki \u00fc\u00e7genin k\u00f6\u015felerini ise `<strong>Tessellator::TessellateTexturedRect<\/strong>` \u00fcretiyor:<\/div>\n<div><\/div>\n<div>\n<pre class=\"lang:c++ decode:true \">void Painter::PushTexturedQuad(TextureHandle texture, float u0, float v0,\r\n                               float u1, float v1, const Rect&amp; dest_rect,\r\n                               const Color&amp; tint, ImageFlip flip) {\r\n  if (flip == ImageFlip::kHorizontal || flip == ImageFlip::kBoth) {\r\n    std::swap(u0, u1);\r\n  }\r\n  if (flip == ImageFlip::kVertical || flip == ImageFlip::kBoth) {\r\n    std::swap(v0, v1);\r\n  }\r\n\r\n  const auto vertices = Tessellator::TessellateTexturedRect(\r\n      dest_rect.x, dest_rect.y, dest_rect.w, dest_rect.h, u0, v0, u1, v1);\r\n\r\n  mBatcher-&gt;SetBlendMode(mCurrentState.blend_mode);\r\n  mBatcher-&gt;PushTexturedTriangles(vertices, mCurrentState.transform,\r\n                                  texture, tint, mCurrentState.opacity);\r\n}\r\n<\/pre>\n<\/div>\n<div>Bu k\u00f6\u015felere mevcut d\u00f6n\u00fc\u015f\u00fcm matrisi de uygulan\u0131yor. Dolay\u0131s\u0131yla g\u00f6r\u00fcnt\u00fcler `<strong>Translate<\/strong>`, `<strong>Rotate<\/strong>` ve `<strong>Scale<\/strong>` ile \u015fekiller gibi d\u00f6n\u00fc\u015ft\u00fcr\u00fclebilir; ekrandaki sonu\u00e7 eksen hizal\u0131 olmak zorunda de\u011fil.<\/div>\n<div><\/div>\n<h2><span style=\"color: #0000ff;\"><strong>Renk Tonlama, Aynalama ve Opakl\u0131k<\/strong><\/span><\/h2>\n<div>Her `DrawImage` \u00e7a\u011fr\u0131s\u0131nda iste\u011fe ba\u011fl\u0131 olarak bir renk tonu (*tint*) ve aynalama se\u00e7ene\u011fi de verilebiliyor:<\/div>\n<div>\n<pre class=\"lang:c++ decode:true \">painter.DrawImage(image, Rect{50, 250, 128, 128},\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 Color{255, 100, 100, 255}, ImageFlip::kHorizontal);<\/pre>\n<p>Tint, dokunun rengiyle bile\u015fen bile\u015fen \u00e7arp\u0131l\u0131yor. Beyaz tint g\u00f6r\u00fcnt\u00fcy\u00fc mevcut renkleri ile koruyor; yukar\u0131daki renk ise ye\u015fil ve mavi bile\u015fenleri azalt\u0131yor. Bu i\u015flem beyaz bir sprite&#8217;\u0131 renklendirmek i\u00e7in uygun, fakat keyf\u00ee bir g\u00f6r\u00fcnt\u00fcy\u00fc gri tonlamaya d\u00f6n\u00fc\u015ft\u00fcren bir i\u015flem de\u011fil. Bunun da uygulamalar\u0131na oyunlarda bak\u0131yor olabiliriz. Tek bir resimi farkl\u0131 renklerde render etmek i\u00e7in birebir.<\/p>\n<\/div>\n<div>Aynalama, hedef dikd\u00f6rtgeni yerinde tutup UV u\u00e7lar\u0131n\u0131 de\u011fi\u015ftirir, yatay, dikey veya iki eksende birden uygulanabiliyor ve tek ba\u015f\u0131na ek geometri ya da \u00e7izim \u00e7a\u011fr\u0131s\u0131 da gerektirmiyor. A\u015fa\u011f\u0131da bunlar\u0131n ve renklendirmenin mant\u0131\u011f\u0131na y\u00f6nelik g\u00f6rseli g\u00f6rebilirisniz:<\/div>\n<div><\/div>\n<div>\n<div id=\"attachment_3254\" style=\"width: 930px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3254\" class=\" wp-image-3254\" src=\"https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c1069360e.png\" alt=\"\" width=\"920\" height=\"499\" srcset=\"https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c1069360e.png 1530w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c1069360e-300x163.png 300w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c1069360e-1024x556.png 1024w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c1069360e-768x417.png 768w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c1069360e-500x271.png 500w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c1069360e-150x81.png 150w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c1069360e-1200x651.png 1200w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c1069360e-400x217.png 400w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c1069360e-800x434.png 800w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c1069360e-200x108.png 200w\" sizes=\"auto, (max-width: 920px) 100vw, 920px\" \/><p id=\"caption-attachment-3254\" class=\"wp-caption-text\">\u00dcstte beyaz sprite farkl\u0131 tint de\u011ferleriyle \u00e7iziliyor. Altta asimetrik g\u00f6r\u00fcnt\u00fc yatay, dikey ve iki eksende aynalan\u0131yor.<\/p><\/div>\n<\/div>\n<div><\/div>\n<div>OpenGL fragment shader&#8217;\u0131 bu verileri \u015f\u00f6yle kullan\u0131yor:<\/div>\n<pre class=\"lang:c++ decode:true\">#version 330 core\r\nin vec2 v_tex_coord;\r\nin vec4 v_color;\r\nout vec4 frag_color;\r\n\r\nuniform sampler2D u_texture;\r\nuniform float u_opacity;\r\n\r\nvoid main() {\r\n\u00a0 \u00a0 vec4 tex_color = texture(u_texture, v_tex_coord);\r\n\u00a0 \u00a0 frag_color = tex_color * v_color * vec4(1.0, 1.0, 1.0, u_opacity);\r\n}<\/pre>\n<div>Son alfa de\u011feri, dokunun alfas\u0131 \u00d7 tint alfas\u0131 \u00d7 `<strong>SetOpacity<\/strong>` de\u011feri. `<strong>SetOpacity<\/strong>`, Painter&#8217;\u0131n sonraki \u00e7izimleri i\u00e7in ge\u00e7erli durumun bir par\u00e7as\u0131; ayn\u0131 frame i\u00e7inde de\u011fi\u015ftirilebiliyor ve `<strong>Save<\/strong>`\/`<strong>Restore<\/strong>` ile saklan\u0131p geri al\u0131nabiliyor.<\/div>\n<div><\/div>\n<div>Burada toplu \u00e7izim (batching) a\u00e7\u0131s\u0131ndan \u00f6nemli bir konu var. Tint k\u00f6\u015fe verisinde ta\u015f\u0131n\u0131yor; OpenGL&#8217;deki genel opakl\u0131k ise `<strong>u_opacity<\/strong>` uniform&#8217;unda tutuluyor. Ayn\u0131 doku, kar\u0131\u015ft\u0131rma modu ve opakl\u0131kla arka arkaya yap\u0131lan \u00e7izimler, tampon kapasitesi elverdi\u011fi s\u00fcrece farkl\u0131 tint de\u011ferleriyle ayn\u0131 grupta kalabiliyor. Farkl\u0131 opakl\u0131kla gelen \u00e7izim ise \u00f6nceki grubun g\u00f6nderilmesini\/flushlanmas\u0131n\u0131 gerektiriyor. Yaln\u0131zca bir g\u00f6r\u00fcnt\u00fcn\u00fcn saydaml\u0131\u011f\u0131n\u0131 de\u011fi\u015ftirmek i\u00e7in tint&#8217;in alfa bile\u015feni de kullan\u0131labilir.<\/div>\n<div><\/div>\n<h2><span style=\"color: #0000ff;\"><strong>Izgara \u00dczerine \u00c7izim ve Doku G\u00fcncelleme<\/strong><\/span><\/h2>\n<div>\u0130ki ek \u00f6zellikten daha bahsetmek istiyorum.<\/div>\n<div><\/div>\n<div>`<strong>DrawImageMesh<\/strong>`, k\u00f6\u015feleri ba\u011f\u0131ms\u0131z hareket eden bir \u0131zgara \u00fczerine doku \u00e7izmek i\u00e7in kullan\u0131lmas\u0131na olanak sa\u011flayan bir API&#8217;dir. `<strong>cols<\/strong>` ve `<strong>rows<\/strong>` h\u00fccre say\u0131lar\u0131n\u0131; `<strong>points<\/strong>` ise sat\u0131r s\u0131ras\u0131yla `(cols + 1) \u00d7 (rows + 1)` k\u00f6\u015feyi veriyor. UV&#8217;ler `(c \/ cols, r \/ rows)` olarak t\u00fcretiliyor. Noktalar\u0131n konumlar\u0131n\u0131 de\u011fi\u015ftirerek dalgalanan bayrak gibi bir y\u00fczey gibi efektleri elde edebilirsiniz. Bir \u00f6rne\u011fini `<strong>examples\/graphics\/mesh_warp.cpp`<\/strong> dosyas\u0131 i\u00e7erisinde g\u00f6rebilirsiniz.<\/div>\n<div id=\"attachment_3255\" style=\"width: 940px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3255\" class=\" wp-image-3255\" src=\"https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c1b1c8ee3.png\" alt=\"\" width=\"930\" height=\"516\" srcset=\"https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c1b1c8ee3.png 1497w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c1b1c8ee3-300x167.png 300w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c1b1c8ee3-1024x568.png 1024w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c1b1c8ee3-768x426.png 768w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c1b1c8ee3-500x278.png 500w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c1b1c8ee3-150x83.png 150w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c1b1c8ee3-1200x666.png 1200w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c1b1c8ee3-400x222.png 400w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c1b1c8ee3-800x444.png 800w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c1b1c8ee3-200x111.png 200w\" sizes=\"auto, (max-width: 930px) 100vw, 930px\" \/><p id=\"caption-attachment-3255\" class=\"wp-caption-text\">Ayn\u0131 doku, d\u00fcz ve deforme edilmi\u015f 12 \u00d7 8 h\u00fccreli \u0131zgarada. K\u00f6\u015feler hareket ederken UV hesab\u0131 ayn\u0131 kal\u0131yor.<\/p><\/div>\n<div><\/div>\n<div>Bir di\u011fer \u00f6nemli API&#8217;de `UpdateImage`. Bu API de isminden anla\u015f\u0131labilece\u011fi gibi GPU dokusunu g\u00fcncellemek i\u00e7in kullanabilirsiniz. Plazma, \u0131s\u0131 haritas\u0131 veya piksel tuvali gibi i\u00e7eri\u011fi s\u0131k de\u011fi\u015fen g\u00f6r\u00fcnt\u00fcler i\u00e7in mevcut GPU dokusunu g\u00fcncelleyebiliyoruz:<\/div>\n<div>\n<pre class=\"lang:c++ decode:true \">\/\/ image 4 kanall\u0131 olmal\u0131; rgba tam g\u00f6r\u00fcnt\u00fc boyutunda veri i\u00e7ermeli.\r\npainter.UpdateImage(image, rgba.data());<\/pre>\n<p>\u00c7a\u011fr\u0131, `<strong>Width() \u00d7 Height() \u00d7 4<\/strong>` byte&#8217;l\u0131k RGBA8 verisi bekliyor. G\u00f6r\u00fcnt\u00fc hen\u00fcz y\u00fcklenmemi\u015fse \u00f6nce doku olu\u015fturuluyor; sonraki \u00e7a\u011fr\u0131lar ayn\u0131 dokunun i\u00e7eri\u011fini de\u011fi\u015ftiriyor. Burada, ana bellekteki `<strong>Image::RawData()<\/strong>` kopyas\u0131 g\u00fcncellenmiyor. Bu y\u00fczden ba\u015fka bir renderer&#8217;a yeniden y\u00fckleme, son GPU i\u00e7eri\u011fini de\u011fil ba\u015flang\u0131\u00e7taki piksel verisini kullan\u0131r.<\/p>\n<\/div>\n<div>G\u00fcncellemeden \u00f6nce biriken \u00e7izimler g\u00f6nderilir\/flushlan\u0131r. B\u00f6ylece g\u00fcncellemeden \u00f6nceki \u00e7izimler eski doku i\u00e7eri\u011fini kullanmaya devam eder (buan y\u00f6nelik de bir hata vard\u0131 \ud83d\ude00 ). Bekleyen geometri varsa mevcut grup sonland\u0131r\u0131l\u0131r. Elbette, piksel aktar\u0131m\u0131n\u0131n maliyeti de ayr\u0131ca var, buna y\u00f6nelik de g\u00fczel bir \u00f6rnek i\u00e7in `<strong>examples\/graphics\/plasma.cpp<\/strong>` dosyas\u0131na g\u00f6z atabilirsiniz.<\/div>\n<div><\/div>\n<h2><span style=\"color: #0000ff;\"><strong>Kar\u0131\u015ft\u0131rma Modlar\u0131<\/strong><\/span><\/h2>\n<div>`<strong>SetBlendMode<\/strong>` API&#8217;sini, \u00e7izilen rengin hedefteki renkle nas\u0131l birle\u015fece\u011fini belirlemek i\u00e7in kullanabilirsiniz ve yine `<strong>Save<\/strong>`\/`<strong>Restore<\/strong>` taraf\u0131ndan tutuluyor. Mevcut d\u00f6rt modun davran\u0131\u015f\u0131 \u015f\u00f6yle; `<strong>C<\/strong>` RGB bile\u015fenlerini, `<strong>a<\/strong>` alfay\u0131 g\u00f6steriyor:<\/div>\n<div><\/div>\n<div>\n<table class=\"code-line\" dir=\"auto\" data-line=\"323\">\n<thead class=\"code-line\" dir=\"auto\" data-line=\"323\">\n<tr class=\"code-line\" dir=\"auto\" data-line=\"323\">\n<th>Mod<\/th>\n<th>RGB sonucu<\/th>\n<th>Alfa sonucu<\/th>\n<\/tr>\n<\/thead>\n<tbody class=\"code-line\" dir=\"auto\" data-line=\"325\">\n<tr class=\"code-line\" dir=\"auto\" data-line=\"325\">\n<td><code>kAlpha<\/code><\/td>\n<td><code>Cs \u00d7 as + Cd \u00d7 (1 - as)<\/code><\/td>\n<td><code>as + ad \u00d7 (1 - as)<\/code><\/td>\n<\/tr>\n<tr class=\"code-line\" dir=\"auto\" data-line=\"326\">\n<td><code>kAdditive<\/code><\/td>\n<td><code>Cs \u00d7 as + Cd<\/code><\/td>\n<td><code>as + ad<\/code><\/td>\n<\/tr>\n<tr class=\"code-line\" dir=\"auto\" data-line=\"327\">\n<td><code>kMultiply<\/code><\/td>\n<td><code>Cs \u00d7 Cd<\/code><\/td>\n<td><code>as \u00d7 ad<\/code><\/td>\n<\/tr>\n<tr class=\"code-line\" dir=\"auto\" data-line=\"328\">\n<td><code>kNone<\/code><\/td>\n<td><code>Cs<\/code><\/td>\n<td><code>as<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div><\/div>\n<div>De\u011ferleri normalle\u015ftirilmi\u015f olarak d\u00fc\u015f\u00fcn\u00fcn; RGBA8 hedefe yaz\u0131l\u0131rken temsil edilebilir aral\u0131kla s\u0131n\u0131rlan\u0131yor. Varsay\u0131lan `<strong>kAlpha<\/strong>`, saydam g\u00f6r\u00fcnt\u00fcler i\u00e7in al\u0131\u015f\u0131ld\u0131k davran\u0131\u015f\u0131 veriyor. `<strong>kAdditive<\/strong>` parlama ve \u0131\u015f\u0131k efektlerinde; `<strong>kMultiply<\/strong>` ise renkleri \u00e7arparak koyula\u015ft\u0131rmada kullan\u0131labilir. Mevcut `<strong>kMultiply<\/strong>` form\u00fcl\u00fcnde kaynak alfa RGB sonucunu a\u011f\u0131rl\u0131kland\u0131rm\u0131yor. `<strong>kNone<\/strong>` ise kaynak RGBA de\u011ferini do\u011frudan yazar.<\/div>\n<div id=\"attachment_3256\" style=\"width: 935px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3256\" class=\" wp-image-3256\" src=\"https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c228b9cde.png\" alt=\"\" width=\"925\" height=\"497\" srcset=\"https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c228b9cde.png 1531w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c228b9cde-300x161.png 300w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c228b9cde-1024x550.png 1024w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c228b9cde-768x412.png 768w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c228b9cde-500x268.png 500w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c228b9cde-150x81.png 150w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c228b9cde-1200x644.png 1200w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c228b9cde-400x215.png 400w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c228b9cde-800x430.png 800w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c228b9cde-200x107.png 200w\" sizes=\"auto, (max-width: 925px) 100vw, 925px\" \/><p id=\"caption-attachment-3256\" class=\"wp-caption-text\">Ayn\u0131 kaynak ve hedefin d\u00f6rt kar\u0131\u015ft\u0131rma modundaki RGB sonucu. Web sayfas\u0131nda yeniden alfa kar\u0131\u015f\u0131m\u0131 olu\u015fmamas\u0131 i\u00e7in sunum PNG\u2019si opak kaydedildi.<\/p><\/div>\n<p>OpenGL&#8217;de varsay\u0131lan alfa modu i\u00e7in kullan\u0131lan \u00e7a\u011fr\u0131 \u015f\u00f6yledir:<\/p>\n<pre class=\"lang:c++ decode:true \">glEnable(GL_BLEND);\r\nglBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 GL_ONE, GL_ONE_MINUS_SRC_ALPHA);<\/pre>\n<div>\u0130lk iki parametre RGB, son ikisi alfa fakt\u00f6rlerini belirliyor. `<strong>glBlendFuncSeparate<\/strong>` ile bu iki hesab\u0131 ayr\u0131 kurabiliyoruz. Ayr\u0131nt\u0131lara <span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/raw.githubusercontent.com\/KhronosGroup\/OpenGL-Refpages\/main\/gl4\/glBlendFuncSeparate.xml\">https:\/\/raw.githubusercontent.com\/KhronosGroup\/OpenGL-Refpages\/main\/gl4\/glBlendFuncSeparate.xml<\/a> <\/strong><\/span>sayfas\u0131ndan ula\u015fabilirsiniz.<\/div>\n<div><\/div>\n<div>K\u00fct\u00fcphanenin Vulkan renderer kullan\u0131m\u0131nda ise, kar\u0131\u015ft\u0131rma ayarlar\u0131 grafik pipeline&#8217;\u0131n\u0131n sabit durumuna yaz\u0131l\u0131yor. Bu y\u00fczden ilgili pipeline olu\u015fturulurken d\u00f6rt modun varyantlar\u0131 birlikte haz\u0131rlan\u0131yor; \u00e7izim s\u0131ras\u0131nda uygun olan ba\u011flan\u0131yor.<\/div>\n<div><\/div>\n<h2><span style=\"color: #0000ff;\"><strong>Demo<\/strong><\/span><\/h2>\n<div>Gelelim bu kabiliyetin demosuna. Demo, `<strong>examples\/graphics\/images.cpp<\/strong>` i\u00e7inde yer al\u0131yor (eski ad\u0131 `<strong>phase3_demo<\/strong>` ydu). G\u00f6r\u00fcnt\u00fc dosyas\u0131 gerektirmemesi i\u00e7in damal\u0131 desen, renk ge\u00e7i\u015fi, kenara do\u011fru saydamla\u015fan daire ve d\u00f6rt renkli atlas, kod i\u00e7erisinde prosed\u00fcrel olarak \u00fcretiliyor. Demo; \u00f6l\u00e7ekleme, atlas dilimleme, tint, aynalama ve d\u00f6n\u00fc\u015f\u00fcmleri bir arada g\u00f6stermesi a\u00e7\u0131s\u0131ndan faydal\u0131 oldu\u011funa inan\u0131yorum.<\/div>\n<div id=\"attachment_3257\" style=\"width: 847px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-3257\" class=\" wp-image-3257\" src=\"https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c27966d78.png\" alt=\"\" width=\"837\" height=\"487\" srcset=\"https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c27966d78.png 1100w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c27966d78-300x175.png 300w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c27966d78-1024x596.png 1024w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c27966d78-768x447.png 768w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c27966d78-500x291.png 500w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c27966d78-150x87.png 150w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c27966d78-400x233.png 400w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c27966d78-800x465.png 800w, https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5c27966d78-200x116.png 200w\" sizes=\"auto, (max-width: 837px) 100vw, 837px\" \/><p id=\"caption-attachment-3257\" class=\"wp-caption-text\">images.cpp i\u00e7indeki \u00e7izim kodunun 1100 \u00d7 640 ekran d\u0131\u015f\u0131 hedefe al\u0131nm\u0131\u015f \u00e7\u0131kt\u0131s\u0131. D\u00f6n\u00fc\u015f a\u00e7\u0131s\u0131 25\u00b0 olarak sabitlendi; atlas dilimlerinin tamam\u0131 g\u00f6r\u00fcn\u00fcr.<\/p><\/div>\n<div>Damal\u0131 desen \u00fcreticisini yaz\u0131ya uyarlayal\u0131m:<\/div>\n<div>\n<pre class=\"lang:c++ decode:true \">#include &lt;sdl_painter\/image.h&gt;\r\n#include &lt;cstddef&gt;\r\n#include &lt;cstdint&gt;\r\n#include &lt;vector&gt;\r\n\r\nstatic sdl_painter::Image MakeCheckerboard(int32_t size, int32_t cell) {\r\n  if (size &lt;= 0 || size &gt; 32767 || cell &lt;= 0) {\r\n    return {};\r\n  }\r\n\r\n  const auto side = static_cast&lt;std::size_t&gt;(size);\r\n  std::vector&lt;uint8_t&gt; pixels(side * side * 4);\r\n\r\n  for (int32_t y = 0; y &lt; size; ++y) {\r\n    for (int32_t x = 0; x &lt; size; ++x) {\r\n      const bool light = ((x \/ cell) + (y \/ cell)) % 2 == 0;\r\n      const auto idx =\r\n          (static_cast&lt;std::size_t&gt;(y) * side + static_cast&lt;std::size_t&gt;(x)) * 4;\r\n      pixels[idx + 0] = light ? 220 : 40;\r\n      pixels[idx + 1] = light ? 220 : 60;\r\n      pixels[idx + 2] = light ? 220 : 180;\r\n      pixels[idx + 3] = 255;\r\n    }\r\n  }\r\n\r\n  return sdl_painter::Image::CreateFromData(pixels.data(), size, size, 4);\r\n}\r\n<\/pre>\n<\/div>\n<div>\u00d6rne\u011fin `<strong>MakeCheckerboard<\/strong>(128, 16)` ile 16 piksel geni\u015fli\u011finde h\u00fccrelerden olu\u015fan bir g\u00f6r\u00fcnt\u00fc elde ediliyor. `<strong>CreateFromData<\/strong>` veriyi kopyalad\u0131\u011f\u0131 i\u00e7in yerel `<strong>pixels<\/strong>` vekt\u00f6r\u00fcn\u00fcn fonksiyon sonunda u\u00e7urulmas\u0131\/silinmesi de sorun olu\u015fturmaz.<\/div>\n<div><\/div>\n<h2><span style=\"color: #0000ff;\"><strong>Sonu\u00e7<\/strong><\/span><\/h2>\n<div>Art\u0131k dosyadan veya bellekten gelen g\u00f6r\u00fcnt\u00fcleri \u00e7izip \u00f6l\u00e7ekleyebiliyor, bir resim atlas\u0131n\u0131n belirli b\u00f6lgesini se\u00e7ebiliyor, renk tonuyla, aynalama uygulayabiliyoruz. Yeni art\u0131k uygulamalar\u0131m\u0131zda, SDLPainter ile resimleri de g\u00f6sterebiliyoruz.<\/div>\n<div><\/div>\n<div>Bir sonraki yaz\u0131mda, `<strong>SDL_ttf<\/strong>` kullanarak metin \u00e7izmeye ge\u00e7ece\u011fiz. Buradaki atlas ve UV hesab\u0131, karakterlerin ayn\u0131 doku \u00fczerinden \u00e7izilmesini anlamak i\u00e7in de \u00f6nemli.<\/div>\n<div><\/div>\n<div>Elbette, bu kabiliyet \u015fu an var, hemen a\u015fa\u011f\u0131daki adresten bunu deneyimleyebilirsiniz.<\/div>\n<div><\/div>\n<div><span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/github.com\/yazilimperver\/sdl-painter\">https:\/\/github.com\/yazilimperver\/sdl-painter<\/a><\/strong><\/span><\/div>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Sevgili yaz\u0131l\u0131mperver dostlar\u0131m, tekrar merhaba. \u00d6nceki yaz\u0131lar\u0131mda, altyap\u0131ya g\u00f6z att\u0131k, temel \u015fekilleri \u00e7izdik ve d\u00f6n\u00fc\u015f\u00fcm y\u0131\u011f\u0131n\u0131yla bu \u015fekillere raks ettirdik. sdl-painter &#8211; Proje Altyap\u0131s\u0131 (faz-0) sdl-painter &#8211; Proje Altyap\u0131s\u0131(faz 0) &#8211; CI\/CD sdl-painter \u2013 Temel \u015eekiller ve Kabiliyetler (faz-1) sdl-painter \u2013 Transformasyonlar (faz-2) Bu yaz\u0131da ise s\u0131ra resimlerde, bir dosyadan okudu\u011fumuz ya da kodla \u00fcretti\u011fimiz&#8230; <a class=\"more-link\" href=\"https:\/\/yazilimperver.net\/index.php\/2026\/09\/12\/sdl-painter-resim-cizimi-faz-2\/\">Continue reading <span class=\"meta-nav\">&#8594;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"dsgo_overlay_header":false,"dsgo_overlay_header_text_color":"","dsgo_overlay_skip_top_bar":false,"_designsetgo_exclude_llms":false,"footnotes":""},"categories":[10,41,25,188],"tags":[1226,1241,1240,1242,13,1239,1234,1232,334,1173,1214,1155,483,1233,1100,1237,1235,1238,1236,1208],"class_list":["post-3248","post","type-post","status-publish","format-standard","hentry","category-c","category-modern-c","category-oyun-gelistirme","category-yazilim-muhendisligi","tag-2d-grafik","tag-alpha-blending","tag-batching","tag-blend-mode","tag-c","tag-glsl","tag-goruntu-yukleme","tag-grafik-programlama","tag-opengl","tag-raii","tag-sdl-painter","tag-sdl3","tag-sprite","tag-stb_image","tag-texture","tag-texture-atlas","tag-texture-filtering","tag-tint","tag-uv-koordinatlari","tag-vulkan"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>sdl-painter \u2013 Resim \u00c7izimi (faz-2) - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/yazilimperver.net\/index.php\/2026\/09\/12\/sdl-painter-resim-cizimi-faz-2\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"sdl-painter \u2013 Resim \u00c7izimi (faz-2) - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131\" \/>\n<meta property=\"og:description\" content=\"Sevgili yaz\u0131l\u0131mperver dostlar\u0131m, tekrar merhaba. \u00d6nceki yaz\u0131lar\u0131mda, altyap\u0131ya g\u00f6z att\u0131k, temel \u015fekilleri \u00e7izdik ve d\u00f6n\u00fc\u015f\u00fcm y\u0131\u011f\u0131n\u0131yla bu \u015fekillere raks ettirdik. sdl-painter &#8211; Proje Altyap\u0131s\u0131 (faz-0) sdl-painter &#8211; Proje Altyap\u0131s\u0131(faz 0) &#8211; CI\/CD sdl-painter \u2013 Temel \u015eekiller ve Kabiliyetler (faz-1) sdl-painter \u2013 Transformasyonlar (faz-2) Bu yaz\u0131da ise s\u0131ra resimlerde, bir dosyadan okudu\u011fumuz ya da kodla \u00fcretti\u011fimiz... Continue reading &#8594;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/yazilimperver.net\/index.php\/2026\/09\/12\/sdl-painter-resim-cizimi-faz-2\/\" \/>\n<meta property=\"og:site_name\" content=\"Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2026-09-12T22:19:48+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bd46a80ff.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1504\" \/>\n\t<meta property=\"og:image:height\" content=\"834\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"yaz\u0131l\u0131mperver\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"yaz\u0131l\u0131mperver\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/yazilimperver.net\\\/index.php\\\/2026\\\/09\\\/12\\\/sdl-painter-resim-cizimi-faz-2\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/yazilimperver.net\\\/index.php\\\/2026\\\/09\\\/12\\\/sdl-painter-resim-cizimi-faz-2\\\/\"},\"author\":{\"name\":\"yaz\u0131l\u0131mperver\",\"@id\":\"https:\\\/\\\/yazilimperver.net\\\/#\\\/schema\\\/person\\\/534a27860d56170658018ac4c6f1af16\"},\"headline\":\"sdl-painter \u2013 Resim \u00c7izimi (faz-2)\",\"datePublished\":\"2026-09-12T22:19:48+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/yazilimperver.net\\\/index.php\\\/2026\\\/09\\\/12\\\/sdl-painter-resim-cizimi-faz-2\\\/\"},\"wordCount\":2581,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/yazilimperver.net\\\/#\\\/schema\\\/person\\\/534a27860d56170658018ac4c6f1af16\"},\"image\":{\"@id\":\"https:\\\/\\\/yazilimperver.net\\\/index.php\\\/2026\\\/09\\\/12\\\/sdl-painter-resim-cizimi-faz-2\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/yazilimperver.net\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/img_6aa5bd46a80ff.png\",\"keywords\":[\"2D grafik\",\"alpha blending\",\"batching\",\"blend mode\",\"c++\",\"GLSL\",\"g\u00f6r\u00fcnt\u00fc y\u00fckleme\",\"grafik programlama\",\"OpenGL\",\"RAII\",\"sdl-painter\",\"SDL3\",\"sprite\",\"stb_image\",\"texture\",\"texture atlas\",\"texture filtering\",\"tint\",\"UV koordinatlar\u0131\",\"vulkan\"],\"articleSection\":[\"C++\",\"Modern C++\",\"Oyun Geli\u015ftirme\",\"Yaz\u0131l\u0131m M\u00fchendisli\u011fi\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/yazilimperver.net\\\/index.php\\\/2026\\\/09\\\/12\\\/sdl-painter-resim-cizimi-faz-2\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/yazilimperver.net\\\/index.php\\\/2026\\\/09\\\/12\\\/sdl-painter-resim-cizimi-faz-2\\\/\",\"url\":\"https:\\\/\\\/yazilimperver.net\\\/index.php\\\/2026\\\/09\\\/12\\\/sdl-painter-resim-cizimi-faz-2\\\/\",\"name\":\"sdl-painter \u2013 Resim \u00c7izimi (faz-2) - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/yazilimperver.net\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/yazilimperver.net\\\/index.php\\\/2026\\\/09\\\/12\\\/sdl-painter-resim-cizimi-faz-2\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/yazilimperver.net\\\/index.php\\\/2026\\\/09\\\/12\\\/sdl-painter-resim-cizimi-faz-2\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/yazilimperver.net\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/img_6aa5bd46a80ff.png\",\"datePublished\":\"2026-09-12T22:19:48+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/yazilimperver.net\\\/index.php\\\/2026\\\/09\\\/12\\\/sdl-painter-resim-cizimi-faz-2\\\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/yazilimperver.net\\\/index.php\\\/2026\\\/09\\\/12\\\/sdl-painter-resim-cizimi-faz-2\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\\\/\\\/yazilimperver.net\\\/index.php\\\/2026\\\/09\\\/12\\\/sdl-painter-resim-cizimi-faz-2\\\/#primaryimage\",\"url\":\"https:\\\/\\\/yazilimperver.net\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/img_6aa5bd46a80ff.png\",\"contentUrl\":\"https:\\\/\\\/yazilimperver.net\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/img_6aa5bd46a80ff.png\",\"width\":1504,\"height\":834},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/yazilimperver.net\\\/index.php\\\/2026\\\/09\\\/12\\\/sdl-painter-resim-cizimi-faz-2\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Ana sayfa\",\"item\":\"https:\\\/\\\/yazilimperver.net\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"sdl-painter \u2013 Resim \u00c7izimi (faz-2)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/yazilimperver.net\\\/#website\",\"url\":\"https:\\\/\\\/yazilimperver.net\\\/\",\"name\":\"Yaz\u0131l\u0131mperver'in D\u00fcnyas\u0131\",\"description\":\"Payla\u015fmak g\u00fczeldir.\",\"publisher\":{\"@id\":\"https:\\\/\\\/yazilimperver.net\\\/#\\\/schema\\\/person\\\/534a27860d56170658018ac4c6f1af16\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/yazilimperver.net\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/yazilimperver.net\\\/#\\\/schema\\\/person\\\/534a27860d56170658018ac4c6f1af16\",\"name\":\"yaz\u0131l\u0131mperver\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\\\/\\\/yazilimperver.net\\\/wp-content\\\/uploads\\\/2018\\\/04\\\/cropped-OnlyIcon-1.png\",\"url\":\"https:\\\/\\\/yazilimperver.net\\\/wp-content\\\/uploads\\\/2018\\\/04\\\/cropped-OnlyIcon-1.png\",\"contentUrl\":\"https:\\\/\\\/yazilimperver.net\\\/wp-content\\\/uploads\\\/2018\\\/04\\\/cropped-OnlyIcon-1.png\",\"width\":512,\"height\":512,\"caption\":\"yaz\u0131l\u0131mperver\"},\"logo\":{\"@id\":\"https:\\\/\\\/yazilimperver.net\\\/wp-content\\\/uploads\\\/2018\\\/04\\\/cropped-OnlyIcon-1.png\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"sdl-painter \u2013 Resim \u00c7izimi (faz-2) - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/yazilimperver.net\/index.php\/2026\/09\/12\/sdl-painter-resim-cizimi-faz-2\/","og_locale":"tr_TR","og_type":"article","og_title":"sdl-painter \u2013 Resim \u00c7izimi (faz-2) - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131","og_description":"Sevgili yaz\u0131l\u0131mperver dostlar\u0131m, tekrar merhaba. \u00d6nceki yaz\u0131lar\u0131mda, altyap\u0131ya g\u00f6z att\u0131k, temel \u015fekilleri \u00e7izdik ve d\u00f6n\u00fc\u015f\u00fcm y\u0131\u011f\u0131n\u0131yla bu \u015fekillere raks ettirdik. sdl-painter &#8211; Proje Altyap\u0131s\u0131 (faz-0) sdl-painter &#8211; Proje Altyap\u0131s\u0131(faz 0) &#8211; CI\/CD sdl-painter \u2013 Temel \u015eekiller ve Kabiliyetler (faz-1) sdl-painter \u2013 Transformasyonlar (faz-2) Bu yaz\u0131da ise s\u0131ra resimlerde, bir dosyadan okudu\u011fumuz ya da kodla \u00fcretti\u011fimiz... Continue reading &#8594;","og_url":"https:\/\/yazilimperver.net\/index.php\/2026\/09\/12\/sdl-painter-resim-cizimi-faz-2\/","og_site_name":"Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131","article_published_time":"2026-09-12T22:19:48+00:00","og_image":[{"width":1504,"height":834,"url":"https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bd46a80ff.png","type":"image\/png"}],"author":"yaz\u0131l\u0131mperver","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"yaz\u0131l\u0131mperver","Tahmini okuma s\u00fcresi":"13 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/yazilimperver.net\/index.php\/2026\/09\/12\/sdl-painter-resim-cizimi-faz-2\/#article","isPartOf":{"@id":"https:\/\/yazilimperver.net\/index.php\/2026\/09\/12\/sdl-painter-resim-cizimi-faz-2\/"},"author":{"name":"yaz\u0131l\u0131mperver","@id":"https:\/\/yazilimperver.net\/#\/schema\/person\/534a27860d56170658018ac4c6f1af16"},"headline":"sdl-painter \u2013 Resim \u00c7izimi (faz-2)","datePublished":"2026-09-12T22:19:48+00:00","mainEntityOfPage":{"@id":"https:\/\/yazilimperver.net\/index.php\/2026\/09\/12\/sdl-painter-resim-cizimi-faz-2\/"},"wordCount":2581,"commentCount":0,"publisher":{"@id":"https:\/\/yazilimperver.net\/#\/schema\/person\/534a27860d56170658018ac4c6f1af16"},"image":{"@id":"https:\/\/yazilimperver.net\/index.php\/2026\/09\/12\/sdl-painter-resim-cizimi-faz-2\/#primaryimage"},"thumbnailUrl":"https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bd46a80ff.png","keywords":["2D grafik","alpha blending","batching","blend mode","c++","GLSL","g\u00f6r\u00fcnt\u00fc y\u00fckleme","grafik programlama","OpenGL","RAII","sdl-painter","SDL3","sprite","stb_image","texture","texture atlas","texture filtering","tint","UV koordinatlar\u0131","vulkan"],"articleSection":["C++","Modern C++","Oyun Geli\u015ftirme","Yaz\u0131l\u0131m M\u00fchendisli\u011fi"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/yazilimperver.net\/index.php\/2026\/09\/12\/sdl-painter-resim-cizimi-faz-2\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/yazilimperver.net\/index.php\/2026\/09\/12\/sdl-painter-resim-cizimi-faz-2\/","url":"https:\/\/yazilimperver.net\/index.php\/2026\/09\/12\/sdl-painter-resim-cizimi-faz-2\/","name":"sdl-painter \u2013 Resim \u00c7izimi (faz-2) - Yaz\u0131l\u0131mperver&#039;in D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/yazilimperver.net\/#website"},"primaryImageOfPage":{"@id":"https:\/\/yazilimperver.net\/index.php\/2026\/09\/12\/sdl-painter-resim-cizimi-faz-2\/#primaryimage"},"image":{"@id":"https:\/\/yazilimperver.net\/index.php\/2026\/09\/12\/sdl-painter-resim-cizimi-faz-2\/#primaryimage"},"thumbnailUrl":"https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bd46a80ff.png","datePublished":"2026-09-12T22:19:48+00:00","breadcrumb":{"@id":"https:\/\/yazilimperver.net\/index.php\/2026\/09\/12\/sdl-painter-resim-cizimi-faz-2\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/yazilimperver.net\/index.php\/2026\/09\/12\/sdl-painter-resim-cizimi-faz-2\/"]}]},{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/yazilimperver.net\/index.php\/2026\/09\/12\/sdl-painter-resim-cizimi-faz-2\/#primaryimage","url":"https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bd46a80ff.png","contentUrl":"https:\/\/yazilimperver.net\/wp-content\/uploads\/2026\/09\/img_6aa5bd46a80ff.png","width":1504,"height":834},{"@type":"BreadcrumbList","@id":"https:\/\/yazilimperver.net\/index.php\/2026\/09\/12\/sdl-painter-resim-cizimi-faz-2\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Ana sayfa","item":"https:\/\/yazilimperver.net\/"},{"@type":"ListItem","position":2,"name":"sdl-painter \u2013 Resim \u00c7izimi (faz-2)"}]},{"@type":"WebSite","@id":"https:\/\/yazilimperver.net\/#website","url":"https:\/\/yazilimperver.net\/","name":"Yaz\u0131l\u0131mperver'in D\u00fcnyas\u0131","description":"Payla\u015fmak g\u00fczeldir.","publisher":{"@id":"https:\/\/yazilimperver.net\/#\/schema\/person\/534a27860d56170658018ac4c6f1af16"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/yazilimperver.net\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/yazilimperver.net\/#\/schema\/person\/534a27860d56170658018ac4c6f1af16","name":"yaz\u0131l\u0131mperver","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/yazilimperver.net\/wp-content\/uploads\/2018\/04\/cropped-OnlyIcon-1.png","url":"https:\/\/yazilimperver.net\/wp-content\/uploads\/2018\/04\/cropped-OnlyIcon-1.png","contentUrl":"https:\/\/yazilimperver.net\/wp-content\/uploads\/2018\/04\/cropped-OnlyIcon-1.png","width":512,"height":512,"caption":"yaz\u0131l\u0131mperver"},"logo":{"@id":"https:\/\/yazilimperver.net\/wp-content\/uploads\/2018\/04\/cropped-OnlyIcon-1.png"}}]}},"_links":{"self":[{"href":"https:\/\/yazilimperver.net\/index.php\/wp-json\/wp\/v2\/posts\/3248","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/yazilimperver.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/yazilimperver.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/yazilimperver.net\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/yazilimperver.net\/index.php\/wp-json\/wp\/v2\/comments?post=3248"}],"version-history":[{"count":2,"href":"https:\/\/yazilimperver.net\/index.php\/wp-json\/wp\/v2\/posts\/3248\/revisions"}],"predecessor-version":[{"id":3258,"href":"https:\/\/yazilimperver.net\/index.php\/wp-json\/wp\/v2\/posts\/3248\/revisions\/3258"}],"wp:attachment":[{"href":"https:\/\/yazilimperver.net\/index.php\/wp-json\/wp\/v2\/media?parent=3248"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/yazilimperver.net\/index.php\/wp-json\/wp\/v2\/categories?post=3248"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/yazilimperver.net\/index.php\/wp-json\/wp\/v2\/tags?post=3248"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}