glReadPixels GL_RGBAで動きました
こんな感じで動きました。
v_pixels_len = (int)Z_LVAL_P(width) * Z_LVAL_P(height)* sizeof(long); v_pixels = emalloc(v_pixels_len); glReadPixels((int)Z_LVAL_P(x),(int)Z_LVAL_P(y),(int)Z_LVAL_P(width),(int)Z_LVAL_P(height),(int)Z_LVAL_P(format),(int)Z_LVAL_P(type),v_pixels); long_array_to_php_array(v_pixels, v_pixels_len, pixels);
- 第7引数を参照渡しとして指定する
- 第7引数を元にバッファを作るのをやめて、渡されたサイズを元に emalloc する
- (C側の)glReadPixel の結果を第7引数に埋め込む。
glReadPixelsの使い方 (暫定)
- 関数の呼び方
$pixels = array(); // 空配列を渡す glReadPixels(0, 0, $width, $height, GL_RGBA, GL_UNSIGNED_BYTE, $pixels);
- 画像ファイル保存
GD で画像を生成する為にピクセルデータを構築するのは、signed long を RGBA として解釈するので、ちょっと面倒だけど。
以下ので出来ました。
// GD でキャンバスを作る $im = imagecreatetruecolor($width, $height); $i = 0; // pixels 配列を R, G, B, A(無視) の順で解釈してイメージを作成 for ($y = $height ; $y >= 0; $y--) { for ($x = 0; $x < $width ; $x++) { $rgb = $pixels[$i]; if ($rgb < 0) { $rgb += 4294967296; // integer => float } $blue = $rgb % 0x100 ; $rgb /= 0x100; $green = $rgb % 0x100 ; $rgb /= 0x100; $red = $rgb % 0x100 ; $rgb /= 0x100; $color = imagecolorallocate($im, $red, $green, $blue); imagesetpixel($im, $x, $y, $color); // pixel を埋めていく $i ++; } } imagepng($im, "output.png"); // PNG ファイルとして保存!!!
PHP の integer は 0x80000000 以上の正の値を扱えないので、
その場合は float に格上げして、ビット演算をあきらめて mod で処理してます。(unpack 使えって話ですね。すみません)