【実行】
【Hello_Triangle.c】
//
// Book: OpenGL(R) ES 2.0 Programming Guide
// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
// ISBN-10: 0321502795
// ISBN-13: 9780321502797
// Publisher: Addison-Wesley Professional
// URLs: http://safari.informit.com/9780321563835
// http://www.opengles-book.com
//
// Hello_Triangle.c
//
// This is a simple example that draws a single triangle with
// a minimal vertex/fragment shader. The purpose of this
// example is to demonstrate the basic concepts of
// OpenGL ES 2.0 rendering.
#include <stdlib.h>
#include "esUtil.h"
typedef struct
{
// Handle to a program object
GLuint programObject;
} UserData;
///
// Create a shader object, load the shader source, and
// compile the shader.
//
GLuint LoadShader ( GLenum type, const char *shaderSrc )
{
GLuint shader;
GLint compiled;
// Create the shader object
shader = glCreateShader ( type ); // シェーダオブジェクトの作成を行う
// typeには、GL_VERTEX_SHADERかGL_FRAGMENT_SHADERのいずれかを指定する
// GL_VERTEX_SHADERの場合、頂点シェーダが作成される。
// GL_FRAGMENT_SHADERの場合、フラグメントシェーダが作成される。
if ( shader == 0 )
return 0;
// Load the shader source
glShaderSource ( // シェーダソースコードをロードする。
shader, // シェーダオブジェクトへのハンドル
1, // シェーダのソース文字列数
&shaderSrc, // シェーダのソース
NULL // それぞれ対応するシェーダソース文字列のサイズを指定する。NULL指定の場合、各文字列はNULLで終了していると仮定する。
);
// Compile the shader
glCompileShader ( shader ); // シェーダのコンパイルを行う。(実装されているOpenGL ESがコンパイル機能がある場合)
// ※バイナリーフォーマットは完全にベンダーに一任されている
// Check the compile status
glGetShaderiv ( shader, GL_COMPILE_STATUS, &compiled ); // 正常にコンパイルされたかの情報を取得する
if ( !compiled )
{
GLint infoLen = 0;
glGetShaderiv ( shader, GL_INFO_LOG_LENGTH, &infoLen ); //
if ( infoLen > 1 )
{
char* infoLog = malloc (sizeof(char) * infoLen );
glGetShaderInfoLog ( shader, infoLen, NULL, infoLog ); // infoログを取り出す
esLogMessage ( "Error compiling shader:\n%s\n", infoLog );
free ( infoLog );
}
glDeleteShader ( shader ); // シェーダオブジェクトを削除を行う
// すぐに削除されるわけではなく、どのプログラムオブジェクトにも
// アタッチされなくなった時に使用しているメモリが解放される。
return 0;
}
return shader;
}
///
// Initialize the shader and program object
//
int Init ( ESContext *esContext )
{
UserData *userData = esContext->userData;
GLbyte vShaderStr[] = // 頂点シェーダ
"attribute vec4 vPosition; \n"
"void main() \n"
"{ \n"
" gl_Position = vPosition; \n"
"} \n";
GLbyte fShaderStr[] = // フラグメントシェーダ
"precision mediump float;\n"\
"void main() \n"
"{ \n"
" gl_FragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 );\n"
"} \n";
GLuint vertexShader;
GLuint fragmentShader;
GLuint programObject;
GLint linked;
// Load the vertex/fragment shaders
vertexShader = LoadShader ( GL_VERTEX_SHADER, vShaderStr );
fragmentShader = LoadShader ( GL_FRAGMENT_SHADER, fShaderStr );
// Create the program object
programObject = glCreateProgram ( ); // プログラムオブジェクトを作成する
if ( programObject == 0 )
return 0;
glAttachShader ( programObject, vertexShader ); // シェーダオブジェクト(頂点シェーダ)をアタッチする
glAttachShader ( programObject, fragmentShader ); // シェーダオブジェクト(フラグメントシェーダ)をアタッチする
// Bind vPosition to attribute 0
glBindAttribLocation (
programObject, // プログラムオブジェクトの名前
0, // 頂点属性のインデックス
"vPosition" // attribute変数の名前
);
// Link the program
glLinkProgram ( programObject ); // リンクする。(ハードウェア命令が生成される。)
// Check the link status
glGetProgramiv ( programObject, GL_LINK_STATUS, &linked ); // 正常にリンクされたかの情報を取得する
if ( !linked )
{
GLint infoLen = 0;
glGetProgramiv ( programObject, GL_INFO_LOG_LENGTH, &infoLen );
if ( infoLen > 1 )
{
char* infoLog = malloc (sizeof(char) * infoLen );
glGetProgramInfoLog ( programObject, infoLen, NULL, infoLog );
esLogMessage ( "Error linking program:\n%s\n", infoLog );
free ( infoLog );
}
glDeleteProgram ( programObject ); // プログラムオブジェクトを削除する
return FALSE;
}
// Store the program object
userData->programObject = programObject;
glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
return TRUE;
}
///
// Draw a triangle using the shader pair created in Init()
//
void Draw ( ESContext *esContext )
{
UserData *userData = esContext->userData;
GLfloat vVertices[] = { 0.0f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f };
// Set the viewport
glViewport ( 0, 0, esContext->width, esContext->height );
// Clear the color buffer
glClear ( GL_COLOR_BUFFER_BIT );
// Use the program object
glUseProgram ( userData->programObject );
// Load the vertex data
glVertexAttribPointer ( // 頂点データをロードする
0, // 頂点属性のインデックス(0~最大の頂点属性数-1まで)
3, // 頂点配列内で指定される成分の数。1~4でなければならない。
GL_FLOAT, // データフォーマット
GL_FALSE, // 浮動少数点データ型以外のものが、浮動少数点に変換された時に、正規化するかどうかを指定する
0, // strideが0の場合、すべての頂点の属性データは連続して格納されます。
vVertices // 頂点属性データを保持するバッファへのポインタ
);
glEnableVertexAttribArray ( 0 );
glDrawArrays ( GL_TRIANGLES, 0, 3 );
eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface );
}
int main ( int argc, char *argv[] )
{
ESContext esContext;
UserData userData;
esInitContext ( &esContext );
esContext.userData = &userData;
esCreateWindow ( &esContext, "Hello Triangle", 320, 240, ES_WINDOW_RGB );
if ( !Init ( &esContext ) )
return 0;
esRegisterDrawFunc ( &esContext, Draw );
esMainLoop ( &esContext );
}
0 件のコメント:
コメントを投稿