あかすくぱるふぇ

同人サークル「あかすくぱるふぇ」のブログです。

2016年08月

・その1
glBindAttribLocation()の第二引数が0の場合、.vertファイル内の変数名が第三引数と異なっていてもたまたまうまく動作してしまう場合がある。
1以上の値を用いた方が良い?

・その2
glEnableClientState()を使ってはいけない。
その代わりとしてglEnableVertexAttribArray()が存在する。

やっと全貌が見え始めてきたので。

・頂点描画方法
以下の記事の続き、補足です。
http://akasuku.blog.jp/archives/62740578.html
http://akasuku.blog.jp/archives/44623464.html

これについては、わかりやすくまとめられたページがあります。
http://mklearning.blogspot.jp/2014/08/opengl.html

glBegin()/glEnd()を用いる描画はOpenGL1.0のみであって、その後はずっとglVertex(Attrib)Pointerを使っているのですね。
そして、VBOまではOpenGL1.xの範疇。
OpenGL2.0でシェーダー対応、OpenGL3.0でVAO。

・シェーダー変数の変遷。
以下の記事の続き、補足です。
http://akasuku.blog.jp/archives/50856177.html

参考ページ
http://wlog.flatlib.jp/item/1633
http://marina.sys.wakayama-u.ac.jp/~tokoi/?date=20090827

OpenGL3.0(glsl ver1.3)以前はattribute/varying, 以降は.in/out。
glGetAttribLocationとglBindAttribLocationはどちらもOpenGL2.0から使えるようですね。

GLSLプログラムの最小構成です。
床井先生のページを参考にしています。
http://marina.sys.wakayama-u.ac.jp/~tokoi/?date=20051006

vertファイルとfragファイルは適当にどうぞ。
#include <stdio.h>
#include <gl/glew.h>
#include <gl/glut.h>

int readShaderSource(GLuint shader, const char *file)
{
FILE *fp;
const GLchar *source;
GLsizei length;
int ret;

/* ファイルを開く */
fp = fopen(file, "rb");
if (fp == NULL) {
perror(file);
return -1;
}

/* ファイルの末尾に移動し現在位置(つまりファイルサイズ)を得る */
fseek(fp, 0L, SEEK_END);
length = ftell(fp);

/* ファイルサイズのメモリを確保 */
source = (GLchar *)malloc(length);
if (source == NULL) {
fprintf(stderr, "Could not allocate read buffer.\n");
return -1;
}

/* ファイルを先頭から読み込む */
fseek(fp, 0L, SEEK_SET);
ret = fread((void *)source, 1, length, fp) != (size_t)length;
fclose(fp);

/* シェーダのソースプログラムのシェーダオブジェクトへの読み込み */
if (ret)
fprintf(stderr, "Could not read file: %s.\n", file);
else
glShaderSource(shader, 1, &source, &length);

/* 確保したメモリの開放 */
free((void *)source);

return ret;
}

void init(void)
{
glClearColor(0.0f, 0.0f, 1.0f, 0.0f);

// shaderオブジェクトを作成
GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);
GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);

// shaderソースを入力
readShaderSource(vertShader, "basic.vert");
readShaderSource(fragShader, "basic.frag");

// shaderソースをコンパイル
glCompileShader(vertShader);
glCompileShader(fragShader);

// shaderプログラムを作成
GLuint shaderProgram = glCreateProgram();

// shaderプログラムにコンパイルしたshaderをアタッチ
glAttachShader(shaderProgram, vertShader);
glAttachShader(shaderProgram, fragShader);

// shaderプログラムをリンク
glLinkProgram(shaderProgram);

// shaderプログラムの適用
glUseProgram(shaderProgram);
}

void display(void)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_QUADS);
glVertex2d(-0.9, -0.9);
glVertex2d(0.9, -0.9);
glVertex2d(0.9, 0.9);
glVertex2d(-0.9, 0.9);
glEnd();

glutSwapBuffers();
}

void resize(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
}

int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH);
glutCreateWindow(argv[0]);
glewInit();
glutReshapeFunc(resize);
glutDisplayFunc(display);
init();
glutMainLoop();
return 0;
}

ついでに、Visual StudioでGLSLのシンタックスハイライトを行うには以下のページにある.vsixファイルを実行すればよいです。
https://github.com/samizzo/nshader/releases/download/2.0/NShader.vsix

↑このページのトップヘ