FC2ブログ

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

SDL2 「画像の色違いを作って描画」

using System;
using SDL2;

namespace Test {
static class Program {
//使用する画像のパス
const string loadImageName = "0.png";
//使用する画像の横幅
const int imageWidth = 20;
//使用する画像の縦幅
const int imageHeight = 20;

//使用するピクセルフォーマット
static readonly uint usePixelFormat = SDL.SDL_PIXELFORMAT_RGBA8888;

static void Main() {
if (SDL.SDL_Init(SDL.SDL_INIT_EVERYTHING) != 0) throw new Exception();
if (SDL_image.IMG_Init(SDL_image.IMG_InitFlags.IMG_INIT_PNG) != (int)SDL_image.IMG_InitFlags.IMG_INIT_PNG) throw new Exception();

Start();

SDL_image.IMG_Quit();
SDL.SDL_Quit();
}

static IntPtr CreateWindow() {
var title = "";
var x = SDL.SDL_WINDOWPOS_CENTERED;
var y = SDL.SDL_WINDOWPOS_CENTERED;
var width = 200;
var height = 200;
var flag = SDL.SDL_WindowFlags.SDL_WINDOW_SHOWN;

return SDL.SDL_CreateWindow(title, x, y, width, height, flag);
}

//テクスチャの作成
static IntPtr CreateTexture(IntPtr renderer) {
//使用フラグは必ず「SDL_TEXTUREACCESS_STREAMING」にする
//そうでないと、テキスチャの変更ができない
var flag = SDL.SDL_TextureAccess.SDL_TEXTUREACCESS_STREAMING;

//テキスチャの作成
return SDL.SDL_CreateTexture(renderer, usePixelFormat, (int)flag, imageWidth, imageHeight);
}
//テキスチャの変更
static void ChangeTexture(IntPtr texture) {
//使用するサーフェスの読み込み
var base_surface = SDL_image.IMG_Load(loadImageName);
//サーフェスの色を変更
SurfaceColorChange(base_surface);

//テクスチャに書き込むためのサーフェスを作成
var new_surface = SDL.SDL_ConvertSurfaceFormat(base_surface, usePixelFormat, 0);
//サーフェスの内容をテキスチャに書き込む
TextureColorChange(new_surface, texture);
}
//テキスチャの内容の更新
unsafe static void TextureColorChange(IntPtr surface_p, IntPtr texture_p) {
var pixels = default(IntPtr);
var pitch = 0;

//必ずテキスチャにロックをかける
SDL.SDL_LockTexture(texture_p, IntPtr.Zero, out pixels, out pitch);

//テキスチャのピクセル配列
var texture_pixels_p = (SDL.SDL_Color*)pixels;

//変換に使用するサーフェス
var surface = (SDL.SDL_Surface*)surface_p;
//変換に使用するサーフェスのピクセル配列
var surface_pixels = (SDL.SDL_Color*)surface->pixels;

//テクスチャに書き込み
//SDL.SDL_Color構造体が4バイトであるため、
//forループの回数は、画像の横幅と縦幅を掛けた数でよい
//
//(注)
//配列の境界チェックはなされないため、
//範囲外アクセスしないように気を付ける
for (var i = 0; i < imageWidth * imageHeight; i++) {
//サーフェスの色をテキスチャに書き込む
texture_pixels_p[i] = surface_pixels[i];
}

//終わったらロックの解除
SDL.SDL_UnlockTexture(texture_p);
}

//サーフェスの色変換
unsafe static void SurfaceColorChange(IntPtr surface_p) {
//サーフェス
var surface = (SDL.SDL_Surface*)surface_p;
//サーフェスのピクセルフォーマット
var format = (SDL.SDL_PixelFormat*)surface->format;
//サーフェスのパレット
var palette = (SDL.SDL_Palette*)format->palette;

//サーフェスのピクセル配列
var colors = (SDL.SDL_Color*)palette->colors;
//ピクセル配列の要素数
//
//(注)
var colorLength = palette->ncolors;

//サーフェスの色の書き換え
for(var i = 0; i < colorLength; i++) {
//色の書き換え
//これで色違いの画像を作れる
//
//(注)
//配列の境界チェックはなされないため、
//範囲外アクセスしないように気を付ける
colors[i].r -= (byte)(i * 100);
}
}

static void Start() {
var window = CreateWindow();
var renderer = SDL.SDL_CreateRenderer(window, -1, SDL.SDL_RendererFlags.SDL_RENDERER_ACCELERATED);
var texture = CreateTexture(renderer);

ChangeTexture(texture);

MainLoop(renderer, texture);
}
static void MainLoop(IntPtr renderer, IntPtr texture) {
while (true) {
var e = new SDL.SDL_Event();

Render(renderer, texture);

SDL.SDL_PollEvent(out e);
if (e.type == SDL.SDL_EventType.SDL_QUIT) break;
SDL.SDL_Delay(1000 / 30);
}
}

static void Render(IntPtr renderer, IntPtr texture) {
SDL.SDL_RenderClear(renderer);
SDL.SDL_RenderCopy(renderer, texture, IntPtr.Zero, IntPtr.Zero);
SDL.SDL_RenderPresent(renderer);
}
}
}
スポンサーサイト
プロフィール

みにおん

Author:みにおん
c#でゲームを作る人です
web小説なども書いています

低学歴で馬鹿なのパート従業員
ですが、よろしく

相互リンク・ブロとも募集中です
コメントなどご自由にどうぞ

ホームページを見る
Twitter(個人ページ)
PIXIV(個人ページ)

○自作ゲーム一覧
ふりーむ
フリーゲーム夢幻
100%ふりげストア

・web小説
最後の時の夢

最新記事
最新コメント
月別アーカイブ
カテゴリ
ブロとも一覧
検索フォーム
ブロとも申請フォーム

この人とブロともになる

RSSリンクの表示
リンク
アクセスランキング
QRコード
QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。