第6回 ソフトウェアレンダリングを実装してみる(設計編)

カンデラの開発者による連載コラムです。 第6回は、「ソフトウェアレンダリングを実装してみる(設計編)」です。

前回までの内容で、OpenGL ESやOpenVGなどの描画APIを用いて簡単な図形を描画することはできました。しかし、組み込みの世界には、独自の描画APIで動作するGPUを搭載したターゲットや、GPUは存在しないもののビデオメモリへのビットブロック転送( ビットブリット )のみ対応しているターゲットが存在します。そういったターゲットに汎用的なグラフィックの処理を実装するにはどうすればいいでしょうか。その方法を考えてみたいと思います。
 

汎用的なグラフィックの処理とは

GPUが搭載されておらず、一般的な描画APIに対応していない環境でも、画面出力が搭載されているターゲットならば図1のような構成になっているはずです。この何らかのメモリに色を乗せていく処理を特定のプラットフォームに依存しないような形で実装すると汎用的なグラフィック処理を実装したことになります。このようにして実装された処理はすべてCPU側で動作するプログラムとなりますのでこうした描画の仕組みをソフトウェアレンダリングと呼ぶこともあります。今回を含め2回に渡りこのソフトウェアレンダリングを実装してみましょう。

ターゲット

それでは、まずは図1の構成を持つ装置を探すところから始めます。最も身近なのはパソコンです。GPUを使わずに描画面をソフトウェアで生成し、そこに色を乗せた後にビットブロック転送を行うようなアプリケーションを作成するとソフトウェアレンダリングの仕組みができあがります。しかし、せっかくですので、もう少しこれをモデル化してみたいと思います。そこで、ここまでの内容 を図2にまとめてみます。ここから読み取れるのは、最終的な描画( ビットブロック転送 )はOSなどのプラットフォーム依存の何かに任せるとして、その直前までの処理で重要なのは、何らかのメモリを持つことができて、そのメモリに読み書きができる仕組みがあることです。ではこのメモリとはどういう形であることが望ましいでしょうか?それは、単位あたりに、赤、緑、青( とできれば 不透明度 )を設定できるもので、ある程度自由に大きさの設定ができるものとなります( 図3 )。これが、ピクセルになります。ではこのメモリの並べ方のルールを決めます。このメモリは2次元的にアクセスが可能で、最も若いアドレスは描画面の左上を表し、右下に向かい延伸します。1次元的に表す場合は水平方向に並んでいて、指定の列幅を超えると次の行さの先頭を指すものとします( 図4 )。ここまでの内容をすべてまとめると、図5のようになります。つまり、2次元的にアクセスできて、そこをプログラムで指定色に塗りつぶせるような環境ならば何でも大丈夫ということになります。私達がよく使うアプリケーションでそういった機能を持っているものがありますよね?今回は、表計算ソフトであるExcelをターゲットに簡易的なソフトウェアレンダリングを実装してみます。
 


図1. GPUが搭載されていない環境
 

図2. GPU非搭載の環境で行われる処理
 

図3. 想定されるメモリの形( 単位あたりの構造 )
 

図4. 想定されるメモリの形( 全体図 )
 

図5. 想定されるメモリの形( まとめ )

目標地点

さて、このExcelを使ったソフトウェアレンダリングの仕組みですが、本気でやってしまうと色々大変なことになります。ですので、今回は回転もスケールも考慮しない、最も基本的な四角の描画を実装することにします( 図6 )。


図6. 目標は四角形を描画すること

構造

今回実装する仕組みの構造を決めましょう。全体としては図7の流れを実装していくことになります。まずはあるボタンを押下して、描画処理を走らせるための、いわゆるエントリポイントを作成します。そして、エントリポイント内では、実際の描画処理を走らせます。まずは、画面全体を指定範囲でクリアする処理、そして設定された四角形を描画する処理をそれぞれ実装した後にエントリポイントから呼び出すことになります。


図7. 実装する処理

実装

それでは実装を始めていきましょう。今回はエントリポイントを作成して、動作確認をするという入り口の部分のみを準備します。

描画面の準備

まずは描画面を用意します。今回はExcelが最終的なビットブロック転送の処理を担ってくれます( セルの 色をそのまま描画してくれます )ので、その直前のメモリをExcelで用意することになります( 図8 ) 。領域などは後に設定しますので、まずは、Excelのワークブックを用意します。次にframebufferというシートを作成し、行の高さ11に、列の幅を1に設定します( 図9 )。これでなんとなく各ピクセルが正方形に見えるようになります。そして、次にconfigurationというシートを作成します。そこで、描画面の幅と高さ、クリアするときの色を設定できるようにしておきます( 図10 )。


図8. 今回の実装範囲
 

図9. 幅と高さを一斉に変更
 

図10. configurationシートの追加

エントリポイントの作成

前述のconfigurationシートにエントリポイントを呼び出すためのボタンを用意します( 図11 )。念の為に動作も確認しておきます( リスト1 )。


図11. ボタンの用意と動作確認
 
エントリポイントの作成( ソースコードを見る )

Sub Main()
    MsgBox ("Main関数に到達した")
End Sub
リスト1. エントリポイントの作成( ボタン押下時にこれを呼び出す )

今回は、ソフトウェアレンダリングの基本的な考え方と、その実現方法を検討し、実装の準備段階としてエントリポイントの作成までを行いました。次回は本格的に機能を実装していきましょう。