/***************************
描画管理
***************************/
#include "Renderer.h"
namespace sys
{
ShaderProgram* Renderer::shader; // シェーダプログラム
float Renderer::mat_projection[4*4]; // 透視変換行列
/************************************************
初期化
引数 width, height = 端末画面サイズ
************************************************/
void Renderer::init(int width, int height)
{
initShader(); // シェーダ初期化
for (int i = 0; i < 4*4; i++) { // 透視変換行列初期化
mat_projection[i] = 0.0f;
}
mat_projection[0] = 2.0f/SCREEN_WIDTH;
mat_projection[5] = -2.0f/SCREEN_HEIGHT;
mat_projection[10] = 1.0f;
mat_projection[15] = 1.0f;
int _w, _h;
if ( width*SCREEN_HEIGHT < height*SCREEN_WIDTH ) { // 横長(上下カット)
_w = width;
_h = width*SCREEN_HEIGHT/SCREEN_WIDTH;
}
else { // 縦長(左右カット)
_w = height*SCREEN_WIDTH/SCREEN_HEIGHT;
_h = height;
}
glViewport((width - _w)/2, (height - _h)/2, _w, _h); // ビューポート設定
}
/********************
シェーダ初期化
********************/
void Renderer::initShader(void)
{
shader = new ShaderProgram();
GLuint vert_shader, frag_shader;
static const
char gVertexShader[] = // 頂点シェーダプログラム
"attribute vec4 position;"
"attribute vec4 color;"
"varying vec4 vColor;"
"uniform mat4 projection;"
"void main() {"
"gl_Position = projection*position;"
"vColor = color;"
"}";
static const
char gFragmentShader[] = // フラグメントシェーダプログラム
"precision mediump float;"
"varying vec4 vColor;"
"void main() {"
"gl_FragColor = vColor;"
"}";
vert_shader = loadShader(GL_VERTEX_SHADER, gVertexShader); // 頂点シェーダ
frag_shader = loadShader(GL_FRAGMENT_SHADER, gFragmentShader); // フラグメントシェーダ
shader->init(vert_shader, frag_shader); // シェーダプログラム作成
glDeleteShader(vert_shader);
glDeleteShader(frag_shader);
}
/*******************************************
シェーダ作成
引数 type = シェーダ種類
source = プログラムソース
戻り値 シェーダオブジェクト
*******************************************/
GLuint Renderer::loadShader(GLenum type, const char* source)
{
GLuint _shader = glCreateShader(type); // シェーダオブジェクト作成
GLint _compiled = 0;
assert(_shader != 0);
glShaderSource(_shader, 1, &source, NULL); // プログラムソース設定
glCompileShader(_shader); // コンパイル
glGetShaderiv(_shader, GL_COMPILE_STATUS, &_compiled); // コンパイル結果取得
if ( !_compiled ) { // コンパイル失敗
GLchar* _buf;
GLint _len;
glGetShaderiv(_shader, GL_INFO_LOG_LENGTH, &_len);
if ( (_len > 0) && (_buf = new GLchar[_len]) ) {
glGetShaderInfoLog(_shader, _len, NULL, _buf); // エラーログ取得
LOGE("Could not compile shader %d:\n%s\n", type, _buf);
delete[] _buf;
}
glDeleteShader(_shader);
return 0;
}
return _shader;
}
/*************************************************
シェーダプログラム作成
引数 v_shader = 頂点シェーダ
f_shader = フラグメントシェーダ
*************************************************/
void ShaderProgram::init(GLuint v_shader, GLuint f_shader)
{
program = glCreateProgram(); // プログラムオブジェクト作成
assert(program != 0);
glAttachShader(program, v_shader); // 頂点シェーダアタッチ
glAttachShader(program, f_shader); // フラグメントシェーダアタッチ
GLint _linked = GL_FALSE;
glLinkProgram(program); // リンク
glGetProgramiv(program, GL_LINK_STATUS, &_linked); // リンク結果取得
if ( !_linked ) { // リンク失敗
GLchar* _buf;
GLint _len;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &_len);
if ( (_len > 0) && (_buf = new GLchar[_len]) ) {
glGetProgramInfoLog(program, _len, NULL, _buf); // エラーログ取得
LOGE("Could not link program:\n%s\n", _buf);
delete[] _buf;
}
glDeleteProgram(program);
program = 0;
return;
}
position = glGetAttribLocation(program, "position"); // 座標
color = glGetAttribLocation(program, "color"); // カラー
projection = glGetUniformLocation(program, "projection"); // 透視変換
}
/**********
終了
**********/
void Renderer::quit(void)
{
delete shader; // シェーダ削除
}
void ShaderProgram::quit(void)
{
if ( program ) {
glDeleteProgram(program);
}
}
/**********
稼働
**********/
void Renderer::update(void)
{
glEnable(GL_BLEND); // αブレンド初期化
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
/**************************
シェーダ使用
戻り値 シェーダ
**************************/
ShaderProgram* Renderer::use_shader(void)
{
shader->use(mat_projection);
return shader;
}
void ShaderProgram::use(const GLfloat* mat_projection)
{
glUseProgram(program);
glUniformMatrix4fv(projection, 1, GL_FALSE, mat_projection);
glEnableVertexAttribArray(position);
glEnableVertexAttribArray(color);
}
}
/**************** End of File ******************************************/
セコメントをする