{"id":3237,"date":"2026-09-06T20:37:16","date_gmt":"2026-09-06T20:37:16","guid":{"rendered":"https:\/\/yazilimperver.com\/?p=3237"},"modified":"2026-09-06T20:37:16","modified_gmt":"2026-09-06T20:37:16","slug":"sdl-painter-transformasyonlar-faz-2","status":"publish","type":"post","link":"https:\/\/yazilimperver.com\/index.php\/2026\/09\/06\/sdl-painter-transformasyonlar-faz-2\/","title":{"rendered":"sdl-painter \u2013 Transformasyonlar (faz-2)"},"content":{"rendered":"<p id=\"PofTQeP\"><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-3239 aligncenter\" src=\"https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc6afec032.png\" alt=\"\" width=\"518\" height=\"272\" srcset=\"https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc6afec032.png 1200w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc6afec032-300x158.png 300w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc6afec032-1024x538.png 1024w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc6afec032-768x403.png 768w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc6afec032-500x263.png 500w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc6afec032-150x79.png 150w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc6afec032-400x210.png 400w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc6afec032-800x420.png 800w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc6afec032-200x105.png 200w\" sizes=\"auto, (max-width: 518px) 100vw, 518px\" \/><\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"17\">Tekrar merhaba dostlar. sdl-painter&#8217;\u0131 tan\u0131mak i\u00e7in fazlara b\u00f6lerek kabiliyetleri anlatnaya devam ediyorum.\u00a0<span style=\"color: #008000;\"><strong><a style=\"color: #008000;\" href=\"https:\/\/yazilimperver.com\/index.php\/2026\/08\/29\/sdl-painter-temel-sekiller-ve-kabiliyetler-faz-1\/\" data-href=\"https:\/\/yazilimperver.com\/index.php\/2026\/08\/29\/sdl-painter-temel-sekiller-ve-kabiliyetler-faz-1\/\">Bir \u00f6nceki yaz\u0131da<\/a><\/strong><\/span>\u00a0OpenGL \u00fczerinde temel \u015fekilleri nas\u0131l \u00e7izebilece\u011fimize bakm\u0131\u015ft\u0131k: \u00e7izgi, dikd\u00f6rtgen, daire, elips ve konkav poligon. \u015eimdi de, \u015fekillerimizi nas\u0131l hareket ettirece\u011fimize ili\u015fkin transformasyon hususlar\u0131na bak\u0131yor olaca\u011f\u0131z.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"19\">Bir \u00f6nceki yaz\u0131mda, t\u00fcm \u015fekiller sabit koordinatlarda g\u00f6rselle\u015ftiriliyordu. Bu yaz\u0131mda, bunlar\u0131 nas\u0131l hareket ettirip\/\u00f6teleyip, d\u00f6nd\u00fcr\u00fcp ya da boyutland\u0131rabilece\u011fimize, bir di\u011fer ifade ile transformasyon kabiliyetlerine bakaca\u011f\u0131z:\u00a0<code>Save()<\/code>\u00a0\/\u00a0<code>Restore()<\/code>,\u00a0<code>Translate<\/code>\u00a0\/\u00a0<code>Rotate<\/code>\u00a0\/\u00a0<code>Scale<\/code>\u00a0ve scissor tabanl\u0131 k\u0131rpma. Matris olarak\u00a0<code>glm::mat3<\/code>\u00a0kullan\u0131yoruz ama affine matrisleri elle kuruyoruz.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"21\">Bu konulara asl\u0131nda y\u0131llar \u00f6nce\u00a0<strong><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"https:\/\/yazilimperver.com\/index.php\/2023\/10\/15\/uengine4-seruveni-basicglpainter-ii\/\" data-href=\"https:\/\/yazilimperver.com\/index.php\/2023\/10\/15\/uengine4-seruveni-basicglpainter-ii\/\">uEngine4 Ser\u00fcveni \u2013 BasicGLPainter \u2013 II<\/a>\u00a0<\/span><\/strong>yaz\u0131mda da de\u011finmi\u015ftim. D\u00f6n\u00fc\u015f\u00fcmlerin matemati\u011fini ve k\u0131rpma alanlar\u0131n\u0131 orada anlatm\u0131\u015ft\u0131m; burada ayn\u0131 \u015feyleri tekrar etmek yerine, sdl-painter&#8217;da i\u015flerin nerede farkl\u0131la\u015ft\u0131\u011f\u0131na odaklanaca\u011f\u0131m.<\/p>\n<h2 id=\"d\u00f6n\u00fc\u015f\u00fcm-matrisleri-ve-\u00e7arp\u0131m-s\u0131ras\u0131\" class=\"code-line\" dir=\"auto\" data-line=\"27\"><strong><span style=\"color: #0000ff;\">D\u00f6n\u00fc\u015f\u00fcm Matrisleri ve \u00c7arp\u0131m S\u0131ras\u0131<\/span><\/strong><\/h2>\n<p class=\"code-line\" dir=\"auto\" data-line=\"29\">2B \u00e7izim i\u00e7in 3&#215;3 affine matrisler bize yetiyor; \u00f6teleme, d\u00f6nd\u00fcrme ve \u00f6l\u00e7eklemenin hepsini z bile\u015fenini\u00a0<code>1.0<\/code>\u00a0ile sabitleyerek ifade edebiliyoruz. Bu matrislerin nas\u0131l kuruldu\u011funu ve neden 3&#215;3 olduklar\u0131n\u0131\u00a0<strong><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"https:\/\/yazilimperver.com\/index.php\/2023\/10\/15\/uengine4-seruveni-basicglpainter-ii\/\" data-href=\"https:\/\/yazilimperver.com\/index.php\/2023\/10\/15\/uengine4-seruveni-basicglpainter-ii\/\">BasicGLPainter yaz\u0131s\u0131nda<\/a><\/span><\/strong>\u00a0anlatm\u0131\u015ft\u0131m, oraya bakman\u0131z\u0131 tavsiye ediyorum. sdl-painter taraf\u0131nda ise iki ayr\u0131nt\u0131 \u00f6ne \u00e7\u0131k\u0131yor.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"32\"><strong>Birincisi,\u00a0<code>glm::mat3<\/code>\u00a0s\u00fctun-major saklan\u0131yor<\/strong> (glm tercihi ADR-007; header-only ve OpenGL ile uyumlu). Yani indeksleme m[col]<\/p>\n<div class=\"row-fluid\"><\/div>\n<p>\u00a0\u015feklinde ve \u00f6teleme\u00a0<strong>s\u00fctun 2<\/strong>&#8216;de duruyor:<\/p>\n<pre class=\"lang:c++ decode:true \">\/\/ glm::mat3, column-major: m[col]<div class=\"row-fluid\"><\/div>\r\n| sx*cos  -sy*sin   tx |\r\n| sx*sin   sy*cos   ty |\r\n|   0        0       1 |<\/pre>\n<p class=\"code-line\" dir=\"auto\" data-line=\"41\">GLM kullanmam\u0131za ra\u011fmen matrisleri\u00a0<code>glm::rotate<\/code>\u00a0gibi\u00a0<code>gtx\/experimental<\/code>\u00a0yard\u0131mc\u0131lar\u0131yla de\u011fil elle kuruyoruz:<\/p>\n<pre class=\"lang:c++ decode:true \">void Painter::Rotate(float angle_degrees) {\r\n  const float r = glm::radians(angle_degrees);\r\n  const float c = std::cos(r);\r\n  const float s = std::sin(r);\r\n  \/\/ column-major: rot[col]<div class=\"row-fluid\"><\/div>. Row-major {c,-s; s,c} karsiligi.\r\n  glm::mat3 rot(1.0F);\r\n  rot[0][0] =  c;  rot[0][1] = s;\r\n  rot[1][0] = -s;  rot[1][1] = c;\r\n  \/\/ Sagdan carp (post-multiply): QPainter \/ HTML Canvas semantigi.\r\n  mCurrentState.transform = mCurrentState.transform * rot;\r\n}\r\n<\/pre>\n<p class=\"code-line\" dir=\"auto\" data-line=\"57\"><code>Translate<\/code>\u00a0ve\u00a0<code>Scale<\/code>\u00a0de ayn\u0131 kal\u0131pta: birim matris, ilgili h\u00fccreler (<code>t[2][0]=dx<\/code>,\u00a0<code>t[2][1]=dy<\/code>\u00a0\/\u00a0<code>sc[0][0]=sx<\/code>,\u00a0<code>sc[1][1]=sy<\/code>) ve yine sa\u011fdan \u00e7arp\u0131m.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"59\"><strong>\u0130kincisi, \u00e7arp\u0131m s\u0131ras\u0131.<\/strong>\u00a0Post-multiply (<code>M = M * op<\/code>) ile QPainter ve benzeri k\u00fct\u00fcphanelerin kural\u0131n\u0131 izliyoruz:\u00a0<strong>ilk \u00e7a\u011fr\u0131lan d\u00f6n\u00fc\u015f\u00fcm en d\u0131\u015fta, son \u00e7a\u011fr\u0131lan en i\u00e7te<\/strong>\u00a0uygulan\u0131r.\u00a0<code>Translate(dx, dy)<\/code>\u00a0sonra\u00a0<code>Rotate(a)<\/code>\u00a0\u00e7a\u011f\u0131r\u0131rsak \u015fekil \u00f6nce kendi merkezinde d\u00f6ner, sonra\u00a0<code>(dx, dy)<\/code>&#8216;ye ta\u015f\u0131n\u0131r \u2014 \u00e7arp\u0131m\u00a0<code>M\u00b7v = T\u00b7R\u00b7v<\/code>\u00a0oldu\u011fu i\u00e7in\u00a0<code>R<\/code>\u00a0\u00f6nce etki eder.<\/p>\n<p dir=\"auto\" data-line=\"59\">\u015eimdi bu durumu ifade eden bir resim ile bu ba\u015fl\u0131\u011f\u0131 da kapatal\u0131m (daha \u00f6nce bu tarz resimleri bulmak biraz oluyordu art\u0131k kolayca olu\u015fturabiliyoruz \ud83d\ude42 ).<\/p>\n<p id=\"XELdIeT\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-3241 aligncenter\" src=\"https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc9176b83a.png\" alt=\"\" width=\"1148\" height=\"881\" srcset=\"https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc9176b83a.png 2240w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc9176b83a-300x230.png 300w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc9176b83a-1024x786.png 1024w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc9176b83a-768x590.png 768w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc9176b83a-1536x1179.png 1536w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc9176b83a-2048x1573.png 2048w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc9176b83a-500x384.png 500w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc9176b83a-150x115.png 150w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc9176b83a-1200x921.png 1200w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc9176b83a-400x307.png 400w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc9176b83a-800x614.png 800w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc9176b83a-200x154.png 200w\" sizes=\"auto, (max-width: 1148px) 100vw, 1148px\" \/><\/p>\n<div class=\"code-line\" dir=\"auto\" data-line=\"61\"><\/div>\n<h2 id=\"save--restore-ve-renderstate\" class=\"code-line\" dir=\"auto\" data-line=\"65\"><strong><span style=\"color: #0000ff;\">Save() \/ Restore() ve RenderState<\/span><\/strong><\/h2>\n<p class=\"code-line\" dir=\"auto\" data-line=\"67\">Transform&#8217;u tek ba\u015f\u0131na tutmak yetmiyor elbette,\u00a0<code>Painter<\/code>&#8216;\u0131n ta\u015f\u0131d\u0131\u011f\u0131 ba\u015fka durum bilgileri de var:<\/p>\n<pre class=\"lang:c++ decode:true\">struct RenderState {\r\n  glm::mat3 transform{1.0F};  \/\/\/&lt; 3x3 affine d\u00f6n\u00fc\u015f\u00fcm (column-major, birim)\r\n  Pen pen; \/\/\/ \u00c7izgisel \u015fekiller i\u00e7in\r\n  Brush brush;  \/\/\/ Dolgu durumu\r\n  float opacity{1.0F};   \/\/\/ Opakl\u0131k\r\n  BlendMode blend_mode{BlendMode::kAlpha}; \/\/\/ Blend modla\u0131r\r\n  Rect clip_rect;\r\n  bool has_clip{false};\r\n};\r\n<\/pre>\n<p class=\"code-line\" dir=\"auto\" data-line=\"81\"><code>Save()<\/code>\u00a0temelde, bu yap\u0131n\u0131n tamam\u0131n\u0131 kopyal\u0131yor,\u00a0<code>Restore()<\/code>\u00a0y\u0131\u011f\u0131ndan \u00e7\u0131kar\u0131p yerine koyuyor. Yani\u00a0<code>SetBrush<\/code>,\u00a0<code>SetOpacity<\/code>\u00a0ya da\u00a0<code>SetBlendMode<\/code>\u00a0de\u00a0<code>Save<\/code>\/<code>Restore<\/code>\u00a0kapsam\u0131nda eski haline d\u00f6n\u00fcyor.\u00a0<code>Pen<\/code>&#8216;in kesik deseninin\u00a0<code>std::vector<\/code>\u00a0de\u011fil sabit boyutlu bir dizi olmas\u0131n\u0131n sebebi de tam olarak buras\u0131: her\u00a0<code>Save<\/code>\/<code>Restore<\/code>\u00a0ile kopyalan\u0131yor. OpenGL ve benzeri grafik API&#8217;lerinde bu y\u0131\u011f\u0131n mant\u0131\u011f\u0131na rastlayabilirsiniz.<\/p>\n<pre class=\"lang:c++ decode:true \">void Painter::Save() {\r\n  mStateStack.push_back(mCurrentState);  \/\/ Flush yok: kaydedilenler GPU durumu degil.\r\n}\r\n\r\nvoid Painter::Restore() {\r\n  if (mStateStack.empty()) {\r\n    spdlog::warn(\"Painter::Restore() \u00e7a\u011fr\u0131ld\u0131 ancak state stack bo\u015f \"\r\n                 \"(unbalanced Save\/Restore).\");\r\n    return;\r\n  }\r\n  const RenderState previous = mCurrentState;\r\n  mCurrentState = mStateStack.back();\r\n  mStateStack.pop_back();\r\n\r\n  \/\/ Yalnizca clip bir GPU durumu: degistiyse flush + yeniden uygula.\r\n  if (!ClipEquals(previous, mCurrentState)) {\r\n    if (mBatcher != nullptr) mBatcher-&gt;Flush();\r\n    if (mCurrentState.has_clip) ApplyScissor(mCurrentState.clip_rect);\r\n    else ClearScissorCounted();\r\n  }\r\n}\r\n<\/pre>\n<p class=\"code-line\" dir=\"auto\" data-line=\"107\">Beklenmedik\u00a0<code>Restore()<\/code>\u00a0\u00e7a\u011fr\u0131s\u0131nda uyar\u0131 bas\u0131yoruz; b\u00f6yle bir uyar\u0131 g\u00f6r\u00fcrseniz genellikle erken bir\u00a0<code>return<\/code>\u00a0vard\u0131r ya da bir\u00a0<code>Restore<\/code>\u00a0atlanm\u0131\u015ft\u0131r.<\/p>\n<h3 id=\"i\u0307\u00e7-i\u00e7e-transform\" class=\"code-line\" dir=\"auto\" data-line=\"109\"><span style=\"color: #0000ff;\"><strong>\u0130\u00e7 i\u00e7e transform<\/strong><\/span><\/h3>\n<p class=\"code-line\" dir=\"auto\" data-line=\"111\">Transformasyonlar\u0131n as\u0131l mahareti, silsile halinde uyguland\u0131\u011f\u0131nda ortaya \u00e7\u0131k\u0131yor:<\/p>\n<pre class=\"lang:c++ decode:true \">painter.Save();\r\n  painter.Translate(730.0f, 190.0f);\r\n  painter.Rotate(angle * 0.7f);              \/\/ dis katman doner\r\n  painter.SetBrush(Brush(Color{60, 180, 200, 200}));\r\n  painter.FillRect(-50.0f, -50.0f, 100.0f, 100.0f);\r\n\r\n  painter.Save();\r\n    painter.Rotate(angle * 1.5f);            \/\/ orta katman daha hizli\r\n    painter.Scale(0.5f, 0.5f);\r\n    painter.SetBrush(Brush(Color{255, 120, 60, 220}));\r\n    painter.FillRect(-50.0f, -50.0f, 100.0f, 100.0f);\r\n\r\n    painter.Save();\r\n      painter.Rotate(-angle * 2.0f);         \/\/ ic katman ters doner\r\n      painter.Scale(0.5f, 0.5f);\r\n      painter.SetBrush(Brush(Color{50, 220, 120, 220}));\r\n      painter.FillRect(-50.0f, -50.0f, 100.0f, 100.0f);\r\n    painter.Restore();\r\n  painter.Restore();\r\npainter.Restore();\r\n<\/pre>\n<p class=\"code-line\" dir=\"auto\" data-line=\"136\">Her\u00a0<code>Save<\/code>\/<code>Restore<\/code>\u00a0\u00e7ifti ba\u011f\u0131ms\u0131z bir koordinat uzay\u0131 a\u00e7\u0131yor; i\u00e7 katman\u0131n\u00a0<code>Rotate(-angle * 2.0f)<\/code>\u00a0\u00e7a\u011fr\u0131s\u0131 d\u0131\u015f katman\u0131n d\u00f6n\u00fc\u015f\u00fcn\u00fc iptal etmiyor, \u00fczerine ters y\u00f6nde bir d\u00f6n\u00fc\u015f ekliyor.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"138\">Bir \u015feyi kendi merkezi etraf\u0131nda d\u00f6nd\u00fcrmenin genel kal\u0131b\u0131 da bu:\u00a0<code>Translate(merkez)<\/code>,\u00a0<code>Rotate(a\u00e7\u0131)<\/code>, sonra \u015fekli\u00a0<strong>merkezi orijinde olacak \u015fekilde<\/strong>\u00a0\u00e7iz (<code>FillRect(-w\/2, -h\/2, w, h)<\/code>).<\/p>\n<p dir=\"auto\" data-line=\"138\">\u015eimdi bu durumu g\u00f6sterecek bir resim olu\u015fturtup, bakal\u0131m:<\/p>\n<p id=\"YdABtTS\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-3240 aligncenter\" src=\"https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc7325ebe7.png\" alt=\"\" width=\"966\" height=\"604\" srcset=\"https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc7325ebe7.png 2240w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc7325ebe7-300x188.png 300w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc7325ebe7-1024x640.png 1024w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc7325ebe7-768x480.png 768w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc7325ebe7-1536x960.png 1536w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc7325ebe7-2048x1280.png 2048w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc7325ebe7-500x313.png 500w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc7325ebe7-150x94.png 150w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc7325ebe7-1200x750.png 1200w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc7325ebe7-400x250.png 400w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc7325ebe7-800x500.png 800w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dc7325ebe7-200x125.png 200w\" sizes=\"auto, (max-width: 966px) 100vw, 966px\" \/><\/p>\n<div class=\"code-line\" dir=\"auto\" data-line=\"140\"><\/div>\n<h2 id=\"peki-d\u00f6n\u00fc\u015f\u00fcm-nereye-uygulan\u0131yor\" class=\"code-line\" dir=\"auto\" data-line=\"144\"><span style=\"color: #0000ff;\"><strong>Peki D\u00f6n\u00fc\u015f\u00fcm Nereye Uygulan\u0131yor?<\/strong><\/span><\/h2>\n<p class=\"code-line\" dir=\"auto\" data-line=\"146\">\u0130lk ba\u015fta,\u00a0<code>Painter<\/code>\u00a0her \u00e7izimden \u00f6nce\u00a0<code>mCurrentState.transform<\/code>&#8216;u renderer&#8217;a yaz\u0131yor, vertex shader da\u00a0<code>u_model<\/code>\u00a0uniform&#8217;uyla \u00e7arp\u0131yordu. Model matrisi bir uniform oldu\u011fu i\u00e7in de de\u011fi\u015fti\u011fi anda biriken \u00e7izimlerin flushlanmas\u0131 gerekiyordu; yani\u00a0<code>Translate<\/code>,\u00a0<code>Rotate<\/code>,\u00a0<code>Scale<\/code>,\u00a0<code>Save<\/code>\u00a0ve\u00a0<code>Restore<\/code>, hepsi i\u00e7in\u00a0<code>Flush()<\/code>\u00a0ile ba\u015fl\u0131yordu.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"148\"><strong><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"https:\/\/yazilimperver.com\/index.php\/2026\/08\/29\/sdl-painter-temel-sekiller-ve-kabiliyetler-faz-1\/\" data-href=\"https:\/\/yazilimperver.com\/index.php\/2026\/08\/29\/sdl-painter-temel-sekiller-ve-kabiliyetler-faz-1\/\">Faz 1 yaz\u0131s\u0131nda<\/a>\u00a0<\/span><\/strong><code>RenderBatcher<\/code>&#8216;\u0131 anlat\u0131rken bu duruma de\u011finmi\u015ftim: \u015fekil ba\u015f\u0131na transform kullanan kod \u2014 ki 2B&#8217;de en yayg\u0131n kal\u0131p budur \u2014 batch&#8217;lemeden hi\u00e7 fayda g\u00f6rm\u00fcyordu:<\/p>\n<table class=\"code-line\" dir=\"auto\" data-line=\"150\">\n<thead class=\"code-line\" dir=\"auto\" data-line=\"150\">\n<tr class=\"code-line\" dir=\"auto\" data-line=\"150\">\n<th>Sahne (2000 \u015fekil)<\/th>\n<th>Draw call<\/th>\n<th>S\u00fcre<\/th>\n<\/tr>\n<\/thead>\n<tbody class=\"code-line\" dir=\"auto\" data-line=\"152\">\n<tr class=\"code-line\" dir=\"auto\" data-line=\"152\">\n<td>Transform yok<\/td>\n<td>2<\/td>\n<td>\u2014<\/td>\n<\/tr>\n<tr class=\"code-line\" dir=\"auto\" data-line=\"153\">\n<td>\u015eekil ba\u015f\u0131na\u00a0<code>Save<\/code>+<code>Translate<\/code>+<code>Restore<\/code><\/td>\n<td>2000<\/td>\n<td>9.44 ms<\/td>\n<\/tr>\n<tr class=\"code-line code-active-line\" dir=\"auto\" data-line=\"154\">\n<td>Ayn\u0131s\u0131, d\u00f6n\u00fc\u015f\u00fcm CPU&#8217;da<\/td>\n<td>2<\/td>\n<td><strong>0.30 ms<\/strong><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"code-line\" dir=\"auto\" data-line=\"156\">A\u00e7\u0131k\u00e7as\u0131, \u00e7\u00f6z\u00fcm d\u00f6n\u00fc\u015f\u00fcm\u00fc CPU&#8217;ya almak oldu:\u00a0<code>RenderBatcher<\/code>\u00a0matrisi vertex&#8217;lere, rengin yaz\u0131ld\u0131\u011f\u0131 ayn\u0131 kopyalama d\u00f6ng\u00fcs\u00fcnde uyguluyor. Ek ge\u00e7i\u015f yok, ek tahsis yok;\u00a0<code>u_model<\/code>\u00a0art\u0131k frame ba\u015f\u0131na bir kez, daima birim matris olarak yaz\u0131l\u0131yor. Bu elbette tek do\u011frudur diyemiyorum, bunula birlikte bunu uzun s\u00fcredir yapmak istiyordum ve bu vesile ile bunu deneyece\u011fim. \u00c7oklu ve hareketli 2B \u015fekiller i\u00e7in \u015fu an ba\u015far\u0131l\u0131 bir i\u015f ortaya koyuyor.<\/p>\n<pre class=\"lang:c++ decode:true \">\/\/ RenderBatcher icinde: donusum ve renk tek geci\u015fte\r\nconst Affine2D t(transform);\r\nfor (auto v : vertices) {\r\n  const float x = v.x;\r\n  const float y = v.y;\r\n  v.x = t.X(x, y);\r\n  v.y = t.Y(x, y);\r\n  v.r = color.r; v.g = color.g; v.b = color.b; v.a = color.a;\r\n  mVertexBuffer.push_back(v);\r\n}\r\n<\/pre>\n<p class=\"code-line\" dir=\"auto\" data-line=\"171\"><code>Affine2D<\/code>, bu bile\u015fenleri elle \u00e7arp\u0131yor; affine bir matriste alt sat\u0131r daima\u00a0<code>[0 0 1]<\/code>\u00a0oldu\u011fu i\u00e7in\u00a0<code>glm::vec3<\/code>\u00a0\u00fczerinden gidip \u00fc\u00e7\u00fcnc\u00fc bile\u015feni hesaplaman\u0131n anlam\u0131 yok.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"173\">Sonu\u00e7:\u00a0<code>Translate<\/code>\/<code>Rotate<\/code>\/<code>Scale<\/code>\u00a0art\u0131k hi\u00e7bir \u015fey flushlam\u0131yor,\u00a0<code>Save()<\/code>\u00a0de flushlam\u0131yor,\u00a0<code>Restore()<\/code>\u00a0yaln\u0131zca k\u0131rpma ger\u00e7ekten de\u011fi\u015ftiyse flushl\u0131yor (eskiden her\u00a0<code>Restore<\/code>\u00a0ko\u015fulsuz bir\u00a0<code>ClearScissor<\/code> \u00fcretiyordu ve 2000 \u015fekilde frame ba\u015f\u0131na 2000 gereksiz durum de\u011fi\u015fimine sebebiyet veriyordu).<\/p>\n<h2 id=\"scissor-k\u0131rpma\" class=\"code-line\" dir=\"auto\" data-line=\"177\"><span style=\"color: #0000ff;\"><strong>Scissor K\u0131rpma<\/strong><\/span><\/h2>\n<p class=\"code-line\" dir=\"auto\" data-line=\"179\">K\u0131rpma, \u00e7izimi ekran\u0131n belirli bir dikd\u00f6rtgeniyle s\u0131n\u0131rlamak demek: o dikd\u00f6rtgenin d\u0131\u015f\u0131na ta\u015fan her \u015feyi k\u0131rpar. uEngine4&#8217;te bunu stencil testiyle yap\u0131yordum \u2014 \u00f6nce maske \u015feklini stencil tamponuna \u00e7iz, sonra yaln\u0131zca maskeye denk gelen pikselleri ge\u00e7ir. Esnek bir y\u00f6ntem, \u00e7\u00fcnk\u00fc maskenin dikd\u00f6rtgen olma zorunlulu\u011fu yok; bununla birlikte fazladan bir \u00e7izim daha yap\u0131l\u0131r.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"181\">sdl-painter&#8217;da ihtiya\u00e7 dikd\u00f6rtgen k\u0131rpmayla s\u0131n\u0131rl\u0131 oldu\u011fu i\u00e7in\u00a0<code>glScissor(x, y, width, height)<\/code>\u00a0bize yetiyor (\u015fimdilik): GPU&#8217;ya bir dikd\u00f6rtgen veriyoruz, o da d\u0131\u015far\u0131da kalan fragment&#8217;lar\u0131 rasterizasyon s\u0131ras\u0131nda hi\u00e7 i\u015flemeden eliyor. Ne fazladan ge\u00e7i\u015f var ne fazladan tampon.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"183\">Kullanan taraf i\u00e7in API iki fonksiyondan ibaret:<\/p>\n<pre class=\"lang:c++ decode:true\">painter.SetClipRect(Rect{200.0F, 150.0F, 300.0F, 200.0F});\r\npainter.FillCircle(300.0F, 250.0F, 120.0F);  \/\/ yalnizca kutuya denk gelen kismi cizilir\r\npainter.ClearClip();<\/pre>\n<p class=\"code-line\" dir=\"auto\" data-line=\"191\"><code>clip_rect<\/code>,\u00a0<code>RenderState<\/code>&#8216;in bir \u00fcyesi oldu\u011fu i\u00e7in k\u0131rpma da\u00a0<code>Save<\/code>\/<code>Restore<\/code>\u00a0kapsam\u0131nda: bir blokta k\u0131rp\u0131p\u00a0<code>Restore()<\/code>\u00a0ile d\u0131\u015ftaki k\u0131rpmaya geri d\u00f6nebiliyoruz.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"193\"><code>SetClipRect<\/code>&#8216;in i\u00e7i \u015f\u00f6yle:<\/p>\n<pre class=\"lang:c++ decode:true\">void Painter::SetClipRect(const Rect&amp; rect) {\r\n  if (mRenderer == nullptr) return;\r\n  if (mBatcher != nullptr) mBatcher-&gt;Flush();  \/\/ kirpma bir GPU durumu oldugu icin yap\u0131yoruz\r\n  mCurrentState.clip_rect = rect;\r\n  mCurrentState.has_clip = true;\r\n  ApplyScissor(rect);\r\n}\r\n<\/pre>\n<p class=\"code-line\" dir=\"auto\" data-line=\"205\">Buradaki\u00a0<code>Flush()<\/code>, bir \u00f6nceki b\u00f6l\u00fcmden sonra tuhaf g\u00f6r\u00fcnebilir \u2014 d\u00f6n\u00fc\u015f\u00fcm\u00fc vertex&#8217;lere g\u00f6merek flush&#8217;lardan kurtulmu\u015ftuk. K\u0131rpmada ayn\u0131 numaray\u0131 yapam\u0131yoruz: scissor kutusu vertex verisinin bir par\u00e7as\u0131 de\u011fil, GPU&#8217;nun kendi durumu. Tek bir draw call i\u00e7indeki \u015fekiller farkl\u0131 k\u0131rpma kutular\u0131 kullanamaz. Bu y\u00fczden k\u0131rpma her de\u011fi\u015fti\u011finde o ana kadar birikeni g\u00f6ndermek zorunday\u0131z; <code>ClearClip<\/code>\u00a0de ayn\u0131 sebeple flush ediyor.<\/p>\n<h3 id=\"applyscissor-iki-koordinat-d\u00fczeltmesi\" class=\"code-line\" dir=\"auto\" data-line=\"207\"><span style=\"color: #0000ff;\"><strong>ApplyScissor: iki koordinat d\u00fczeltmesi<\/strong><\/span><\/h3>\n<p class=\"code-line\" dir=\"auto\" data-line=\"209\">K\u0131rpma dikd\u00f6rtgenini GPU&#8217;ya oldu\u011fu gibi veremiyoruz, \u00e7\u00fcnk\u00fc\u00a0<code>Rect<\/code>&#8216;in ve\u00a0<code>glScissor<\/code>&#8216;\u0131n konu\u015ftu\u011fu koordinat sistemleri ayn\u0131 de\u011fil. Arada iki d\u00fczeltme var; ikisi de unutuldu\u011funda derleyici uyarm\u0131yor, ekranda garip bir sonu\u00e7 olarak kar\u015f\u0131n\u0131za \u00e7\u0131k\u0131yor.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"211\"><span style=\"color: #0000ff;\"><strong>1) Viewport ofseti \u2014 &#8220;hangi (0,0)?&#8221;<\/strong><\/span><\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"213\">\u00c7a\u011f\u0131ran taraf k\u0131rpma dikd\u00f6rtgenini \u00e7izim koordinatlar\u0131yla verir. Bir sonraki b\u00f6l\u00fcmde anlataca\u011f\u0131m\u00a0<code>SetViewport<\/code>, \u00e7izim koordinatlar\u0131n\u0131n ba\u015flang\u0131c\u0131n\u0131 pencerenin herhangi bir k\u00f6\u015fesine ta\u015f\u0131yabiliyor; yani \u00e7izim koordinatlar\u0131\u00a0<strong>viewport&#8217;a g\u00f6re yerel<\/strong>.\u00a0<code>glScissor<\/code>\u00a0ise daima\u00a0<strong>pencerenin<\/strong>\u00a0kendi koordinatlar\u0131n\u0131 bekler. Aradaki fark\u0131 kapatmak i\u00e7in viewport&#8217;un konumunu eklemek gerekiyor:<\/p>\n<pre class=\"lang:c++ decode:true \">const int32_t kWindowX = mViewportX + static_cast&lt;int32_t&gt;(rect.x); \r\nconst int32_t kWindowY = mViewportY + static_cast&lt;int32_t&gt;(rect.y);<\/pre>\n<p class=\"code-line\" dir=\"auto\" data-line=\"220\">Bu iki sat\u0131r olmasa tam ekran \u00e7izen bir programda hi\u00e7bir \u015fey de\u011fi\u015fmez, \u00e7\u00fcnk\u00fc\u00a0<code>mViewportX\/Y<\/code>\u00a0zaten s\u0131f\u0131rd\u0131r. B\u00f6l\u00fcnm\u00fc\u015f ekrana ge\u00e7ti\u011finiz g\u00fcn ise sa\u011f paneldeki k\u0131rpma sol panele d\u00fc\u015fer.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"222\"><span style=\"color: #0000ff;\"><strong>2) Y ekseninin y\u00f6n\u00fc<\/strong><\/span><\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"224\">sdl-painter, pencere sistemlerinin (QPainter&#8217;\u0131n da takip etti\u011fi,\u00a0<strong><span style=\"color: #008000;\"><a style=\"color: #008000;\" href=\"https:\/\/doc.qt.io\/qt-6\/coordsys.html\" data-href=\"https:\/\/doc.qt.io\/qt-6\/coordsys.html\">https:\/\/doc.qt.io\/qt-6\/coordsys.html<\/a>)<\/span><\/strong> yakla\u015f\u0131m\u0131n\u0131 izleyip Y=0&#8217;\u0131\u00a0<strong>\u00fcstte<\/strong>\u00a0tan\u0131ml\u0131yor; Vulkan&#8217;\u0131n clip uzay\u0131 da \u00f6yle. OpenGL&#8217;in ekran framebuffer&#8217;\u0131nda ise Y=0\u00a0<strong>altta<\/strong>. Yani GL&#8217;de scissor kutusunu \u00e7evirmemiz gerekiyor:<\/p>\n<pre class=\"lang:c++ decode:true \">const int32_t kScissorY =\r\n    YAxisMatchesGpu()\r\n        ? kWindowY\r\n        : (SurfaceHeight() - kWindowY - static_cast&lt;int32_t&gt;(rect.h));<\/pre>\n<p class=\"code-line\" dir=\"auto\" data-line=\"233\">Form\u00fcl\u00fcn g\u00f6zden ka\u00e7an k\u0131sm\u0131 <em>rect.h<\/em> \u00e7evirdi\u011fimiz \u015fey, bir nokta de\u011fil bir kutu: biz kutuyu <strong>\u00fcst<\/strong>\u00a0kenar\u0131ndan tan\u0131ml\u0131yoruz,\u00a0<code>glScissor<\/code>\u00a0ise\u00a0<strong>alt<\/strong> kenar\u0131ndan. 600 piksel y\u00fcksekli\u011findeki bir pencerede, \u00fcstten 50 piksel a\u015fa\u011f\u0131da ba\u015flayan 120 piksel y\u00fcksekli\u011finde bir k\u0131rpma i\u00e7in:<\/p>\n<pre class=\"lang:c++ decode:true \">                sdl-painter        OpenGL\r\npencere ustu    y =   0    \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500  y_gl = 600\r\n                y =  50    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510  y_gl = 430  \u2190 glScissor'a verilen\r\n                           \u2502  kirpma kutusu\u2502\r\n                y = 170    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518  y_gl = 310\r\npencere alti    y = 600    \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500  y_gl =   0\r\n\r\ny_gl = 600 - 50 - 120 = 430\r\n<\/pre>\n<p class=\"code-line\" dir=\"auto\" data-line=\"233\"><em>rect.h<\/em> unutulursa kutu kendi y\u00fcksekli\u011fi kadar kayar: k\u00fc\u00e7\u00fck k\u0131rpmalarda &#8220;biraz oynam\u0131\u015f&#8221; gibi g\u00f6r\u00fcn\u00fcr, b\u00fcy\u00fcklerinde ise ekrandan \u00e7\u0131kar.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"248\">Bir ayr\u0131nt\u0131 daha: \u00e7evirmeyi\u00a0<strong>y\u00fczeyin tamam\u0131na<\/strong>\u00a0g\u00f6re yap\u0131yoruz (<code>SurfaceHeight()<\/code>), viewport y\u00fcksekli\u011fine g\u00f6re de\u011fil. \u00d6l\u00e7\u00fc penceredir, \u00e7\u00fcnk\u00fc\u00a0<code>glScissor<\/code> pencere koordinat\u0131 \u00fczerinden \u00e7al\u0131\u015f\u0131r. Yanl\u0131\u015fl\u0131kla viewport y\u00fcksekli\u011fi kullan\u0131l\u0131rsa, \u00fcst yar\u0131ya yerle\u015fmi\u015f bir viewport&#8217;ta k\u0131rpma alt yar\u0131ya kayar.<\/p>\n<p id=\"xZCmlAX\"><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"460\" class=\"size-full wp-image-3243 aligncenter\" src=\"https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dcbd6ce13f.png\" alt=\"\" srcset=\"https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dcbd6ce13f.png 640w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dcbd6ce13f-300x216.png 300w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dcbd6ce13f-500x359.png 500w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dcbd6ce13f-150x108.png 150w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dcbd6ce13f-400x288.png 400w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dcbd6ce13f-200x144.png 200w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/p>\n<h2 id=\"viewport-k\u0131rpman\u0131n-kar\u0131\u015ft\u0131r\u0131ld\u0131\u011f\u0131-karde\u015fi\" class=\"code-line\" dir=\"auto\" data-line=\"256\"><span style=\"color: #0000ff;\"><strong>Viewport<\/strong><\/span><\/h2>\n<p class=\"code-line\" dir=\"auto\" data-line=\"258\">Faz 2&#8217;den sonra eklenen ama tam olarak bu b\u00f6l\u00fcme ait bir di\u011fer kabiliyetimiz:\u00a0<code>SetViewport<\/code>. K\u0131rpma pikselleri maskeler, koordinat sistemine dokunmaz; viewport ise\u00a0<strong>koordinat sisteminin kendisini<\/strong>\u00a0yeniden tan\u0131mlar \u2014 ayarland\u0131ktan sonra\u00a0<code>(0, 0)<\/code>\u00a0art\u0131k panelin sol \u00fcst k\u00f6\u015fesidir.<\/p>\n<pre class=\"lang:c++ decode:true \">painter.SetViewport(0, 0, w \/ 2, h \/ 2);\r\nDrawScene(painter, camera_a);   \/\/ hicbir ofset hesabi yok\r\npainter.SetViewport(w \/ 2, 0, w \/ 2, h \/ 2);\r\nDrawScene(painter, camera_b);   \/\/ ayni fonksiyon, farkli kamera\r\npainter.ResetViewport();<\/pre>\n<p class=\"code-line\" dir=\"auto\" data-line=\"268\">Bu kabiliyetin en \u00e7ok kullan\u0131ld\u0131\u011f\u0131 yerler: b\u00f6l\u00fcnm\u00fc\u015f ekranlar, mini harita ve panelli ara\u00e7 aray\u00fczleridir. D\u00f6rt panel de ayn\u0131 \u00e7izim fonksiyonunu \u00e7a\u011f\u0131rabiliyor, aralar\u0131ndaki tek fark kamera konumu. Tabi ki, bu API her \u00e7a\u011fr\u0131ld\u0131\u011f\u0131nda, flush API&#8217;sini te tekrar \u00e7a\u011f\u0131r\u0131yoruz. Panel say\u0131s\u0131 kadar taban draw call maliyeti olu\u015fuyor ve\u00a0<code>examples\/basics\/viewports.cpp<\/code> bunu gizlemek yerine istatistik katman\u0131nda g\u00f6steriyor.<\/p>\n<h2 id=\"demo\" class=\"code-line\" dir=\"auto\" data-line=\"272\"><span style=\"color: #0000ff;\"><strong>Demo<\/strong><\/span><\/h2>\n<p class=\"code-line\" dir=\"auto\" data-line=\"274\">Faz 2 demosu bug\u00fcn\u00a0<code>examples\/basics\/transforms.cpp<\/code>\u00a0(eski ad\u0131\u00a0<code>phase2_demo<\/code>). Yedi hususun hepsi bir arada:<\/p>\n<table class=\"code-line\" dir=\"auto\" data-line=\"276\">\n<thead class=\"code-line\" dir=\"auto\" data-line=\"276\">\n<tr class=\"code-line\" dir=\"auto\" data-line=\"276\">\n<th>\u015eekil<\/th>\n<th>Ne g\u00f6steriyor<\/th>\n<\/tr>\n<\/thead>\n<tbody class=\"code-line\" dir=\"auto\" data-line=\"278\">\n<tr class=\"code-line\" dir=\"auto\" data-line=\"278\">\n<td>1<\/td>\n<td>Kademeli\u00a0<code>Translate<\/code>\u00a0\u2014 \u00fc\u00e7 dikd\u00f6rtgen, her biri bir \u00f6ncekine g\u00f6re ofsetli<\/td>\n<\/tr>\n<tr class=\"code-line\" dir=\"auto\" data-line=\"279\">\n<td>2<\/td>\n<td><code>Translate<\/code>\u00a0+\u00a0<code>Rotate<\/code>\u00a0\u2014 dikd\u00f6rtgen kendi merkezi etraf\u0131nda d\u00f6ner<\/td>\n<\/tr>\n<tr class=\"code-line\" dir=\"auto\" data-line=\"280\">\n<td>3<\/td>\n<td><code>Translate<\/code>\u00a0+\u00a0<code>Scale<\/code>\u00a0\u2014 daire\u00a0<code>sin(angle)<\/code>\u00a0ile nefes al\u0131r<\/td>\n<\/tr>\n<tr class=\"code-line\" dir=\"auto\" data-line=\"281\">\n<td>4<\/td>\n<td>\u00dc\u00e7 seviyeli i\u00e7 i\u00e7e\u00a0<code>Save<\/code>\/<code>Restore<\/code>, her katman farkl\u0131 h\u0131zda<\/td>\n<\/tr>\n<tr class=\"code-line\" dir=\"auto\" data-line=\"282\">\n<td>5<\/td>\n<td>Scissor k\u0131rpma \u2014 ta\u015fan daire ve d\u00f6nen dikd\u00f6rtgen<\/td>\n<\/tr>\n<tr class=\"code-line\" dir=\"auto\" data-line=\"283\">\n<td>6<\/td>\n<td><code>ResetTransform<\/code>\u00a0\u2014 bozuk transform sonras\u0131 s\u0131f\u0131rlama<\/td>\n<\/tr>\n<tr class=\"code-line\" dir=\"auto\" data-line=\"284\">\n<td>7<\/td>\n<td>X ve Y&#8217;de ba\u011f\u0131ms\u0131z\u00a0<code>Scale<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p id=\"UgunleL\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-3244 \" src=\"https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dccaa0e56f.png\" alt=\"\" width=\"779\" height=\"641\" srcset=\"https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dccaa0e56f.png 893w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dccaa0e56f-300x247.png 300w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dccaa0e56f-768x632.png 768w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dccaa0e56f-500x412.png 500w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dccaa0e56f-150x123.png 150w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dccaa0e56f-400x329.png 400w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dccaa0e56f-800x658.png 800w, https:\/\/yazilimperver.com\/wp-content\/uploads\/2026\/09\/img_6a9dccaa0e56f-200x165.png 200w\" sizes=\"auto, (max-width: 779px) 100vw, 779px\" \/><\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"286\"><em>K\u00fc\u00e7\u00fck bir not: demoda\u00a0<code>Painter<\/code>&#8216;\u0131n \u00f6mr\u00fcn\u00fc bilerek bir scope blo\u011funda tutuyoruz. Pencere \u00f6nce silinirse GL context&#8217;i de gider ve destructor&#8217;daki <code>glDelete*<\/code>\u00a0\u00e7a\u011fr\u0131lar\u0131\u00a0<code>1282 (GL_INVALID_OPERATION)<\/code> verir; s\u0131ran\u0131n \u00f6nemli oldu\u011funu g\u00f6stermek i\u00e7in g\u00fczel bir \u00f6rnek.<\/em><\/p>\n<h2 id=\"sonu\u00e7\" class=\"code-line\" dir=\"auto\" data-line=\"292\"><span style=\"color: #0000ff;\"><strong>Sonu\u00e7<\/strong><\/span><\/h2>\n<p class=\"code-line\" dir=\"auto\" data-line=\"294\">Faz 2 kabiliyetleri ile birlikte k\u00fct\u00fcphanemizle, art\u0131k \u015fekilleri raks ettirebilece\u011fiz. Burada, farkl\u0131 bir yakla\u015f\u0131ma tekrar de\u011finiyorum o da d\u00f6n\u00fc\u015f\u00fcm\u00fcn art\u0131k shader&#8217;da de\u011fil, CPU&#8217;da uygulanmas\u0131.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"303\">Faz 3&#8217;te, oyunlar ve di\u011fer uygulamalar i\u00e7in kritik olan, resim\/g\u00f6rsel\/dokulara giri\u015f yapaca\u011f\u0131z.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"303\">Bir sonraki yaz\u0131da g\u00f6r\u00fc\u015fmek dile\u011fiyle bol kodlu g\u00fcnler. K\u00fct\u00fcphaneyi be\u011fendiyseniz, takip etmeyi l\u00fctfen unutmay\u0131n.<\/p>\n<p class=\"code-line\" dir=\"auto\" data-line=\"305\">Kaynak kod:\u00a0<span style=\"color: #339966;\"><strong><a style=\"color: #339966;\" href=\"https:\/\/github.com\/yazilimperver\/sdl-painter\" data-href=\"https:\/\/github.com\/yazilimperver\/sdl-painter\">GitHub<\/a><\/strong>\u00a0\u00b7\u00a0<strong><a style=\"color: #339966;\" href=\"https:\/\/gitlab.com\/yazilimperver\/sdl-painter\" data-href=\"https:\/\/gitlab.com\/yazilimperver\/sdl-painter\">GitLab<\/a><\/strong>.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Tekrar merhaba dostlar. sdl-painter&#8217;\u0131 tan\u0131mak i\u00e7in fazlara b\u00f6lerek kabiliyetleri anlatnaya devam ediyorum.\u00a0Bir \u00f6nceki yaz\u0131da\u00a0OpenGL \u00fczerinde temel \u015fekilleri nas\u0131l \u00e7izebilece\u011fimize bakm\u0131\u015ft\u0131k: \u00e7izgi, dikd\u00f6rtgen, daire, elips ve konkav poligon. \u015eimdi de, \u015fekillerimizi nas\u0131l hareket ettirece\u011fimize ili\u015fkin transformasyon hususlar\u0131na bak\u0131yor olaca\u011f\u0131z. Bir \u00f6nceki yaz\u0131mda, t\u00fcm \u015fekiller sabit koordinatlarda g\u00f6rselle\u015ftiriliyordu. Bu yaz\u0131mda, bunlar\u0131 nas\u0131l hareket ettirip\/\u00f6teleyip, d\u00f6nd\u00fcr\u00fcp ya da&#8230; <a class=\"more-link\" href=\"https:\/\/yazilimperver.com\/index.php\/2026\/09\/06\/sdl-painter-transformasyonlar-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":{"_seopress_titles_title":"","_seopress_titles_desc":"","_seopress_robots_index":"","_seopress_robots_follow":"","_seopress_robots_imageindex":"","_seopress_robots_snippet":"","_seopress_robots_primary_cat":"10","_seopress_robots_breadcrumbs":"","_seopress_robots_freeze_modified_date":"","_seopress_robots_custom_modified_date":"","_seopress_robots_canonical":"","_seopress_social_fb_title":"","_seopress_social_fb_desc":"","_seopress_social_fb_img":"","_seopress_social_fb_img_attachment_id":0,"_seopress_social_fb_img_width":0,"_seopress_social_fb_img_height":0,"_seopress_social_twitter_title":"","_seopress_social_twitter_desc":"","_seopress_social_twitter_img":"","_seopress_social_twitter_img_attachment_id":0,"_seopress_social_twitter_img_width":0,"_seopress_social_twitter_img_height":0,"_seopress_redirections_value":"","_seopress_redirections_enabled":"","_seopress_redirections_enabled_regex":"","_seopress_redirections_logged_status":"","_seopress_redirections_param":"","_seopress_redirections_type":0,"_seopress_analysis_target_kw":"","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,1228,13,1229,334,1230,1155,1227,1231],"class_list":["post-3237","post","type-post","status-publish","format-standard","hentry","category-c","category-modern-c","category-oyun-gelistirme","category-yazilim-muhendisligi","tag-2d-grafik","tag-affine-matris","tag-c","tag-glm","tag-opengl","tag-scissor-clipping","tag-sdl3","tag-transform-stack","tag-viewport"],"_links":{"self":[{"href":"https:\/\/yazilimperver.com\/index.php\/wp-json\/wp\/v2\/posts\/3237","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/yazilimperver.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/yazilimperver.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/yazilimperver.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/yazilimperver.com\/index.php\/wp-json\/wp\/v2\/comments?post=3237"}],"version-history":[{"count":5,"href":"https:\/\/yazilimperver.com\/index.php\/wp-json\/wp\/v2\/posts\/3237\/revisions"}],"predecessor-version":[{"id":3247,"href":"https:\/\/yazilimperver.com\/index.php\/wp-json\/wp\/v2\/posts\/3237\/revisions\/3247"}],"wp:attachment":[{"href":"https:\/\/yazilimperver.com\/index.php\/wp-json\/wp\/v2\/media?parent=3237"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/yazilimperver.com\/index.php\/wp-json\/wp\/v2\/categories?post=3237"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/yazilimperver.com\/index.php\/wp-json\/wp\/v2\/tags?post=3237"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}