0001: //-----------------------------------------------------------------------------
0002: // File: GLSL.cpp
0003: //
0004: // Desc: Application class for the imagire's OprnGL samples framework library.
0005: //-----------------------------------------------------------------------------
0006: #define STRICT
0007: #include <windows.h>
0008: #include <tchar.h>
0009: #include <mmsystem.h>
0010: #include <stdio.h>
0011: #include <io.h>
0012: #include <fcntl.h>
0013: 
0014: #include "GLSL.h"
0015: 
0016: //-----------------------------------------------------------------------------
0017: //
0018: // OpenGL Shading Language 関数
0019: //
0020: //-----------------------------------------------------------------------------
0021: PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB;
0022: PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
0023: PFNGLDELETEOBJECTARBPROC glDeleteObjectARB;
0024: PFNGLDETACHOBJECTARBPROC glDetachObjectARB;
0025: PFNGLATTACHOBJECTARBPROC glAttachObjectARB;
0026: 
0027: PFNGLSHADERSOURCEARBPROC glShaderSourceARB;
0028: PFNGLCOMPILESHADERARBPROC glCompileShaderARB;
0029: PFNGLLINKPROGRAMARBPROC glLinkProgramARB;
0030: PFNGLGETINFOLOGARBPROC glGetInfoLogARB;
0031: PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB;
0032: 
0033: PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
0034: PFNGLGETOBJECTPARAMETERFVARBPROC glGetObjectParameterfvARB;
0035: PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB;
0036: 
0037: PFNGLUNIFORM1FARBPROC glUniform1fARB;
0038: PFNGLUNIFORM2FARBPROC glUniform2fARB;
0039: PFNGLUNIFORM3FARBPROC glUniform3fARB;
0040: PFNGLUNIFORM4FARBPROC glUniform4fARB;
0041: 
0042: PFNGLUNIFORM1IARBPROC glUniform1iARB;
0043: PFNGLUNIFORM2IARBPROC glUniform2iARB;
0044: PFNGLUNIFORM3IARBPROC glUniform3iARB;
0045: PFNGLUNIFORM4IARBPROC glUniform4iARB;
0046: 
0047: PFNGLUNIFORM1FVARBPROC glUniform1fvARB;
0048: PFNGLUNIFORM2FVARBPROC glUniform2fvARB;
0049: PFNGLUNIFORM3FVARBPROC glUniform3fvARB;
0050: PFNGLUNIFORM4FVARBPROC glUniform4fvARB;
0051: 
0052: PFNGLUNIFORM1IVARBPROC glUniform1ivARB;
0053: PFNGLUNIFORM2IVARBPROC glUniform2ivARB;
0054: PFNGLUNIFORM3IVARBPROC glUniform3ivARB;
0055: PFNGLUNIFORM4IVARBPROC glUniform4ivARB;
0056: 
0057: 
0058: 
0059: 
0060: 
0061: #define PADDR(functype,funcname) \
0062:     ((funcname = (functype) wglGetProcAddress( #funcname )) == NULL)
0063: 
0064: //-----------------------------------------------------------------------------
0065: // Name: InitGLSL()
0066: // Desc: GLSL の初期化
0067: //-----------------------------------------------------------------------------
0068: HRESULT GLSL::Init( )
0069: {
0070:     int error;
0071: 
0072:     error |= PADDR(PFNGLCREATEPROGRAMOBJECTARBPROC, glCreateProgramObjectARB);
0073:     error |= PADDR(PFNGLCREATESHADEROBJECTARBPROC, glCreateShaderObjectARB);
0074:     error |= PADDR(PFNGLDELETEOBJECTARBPROC, glDeleteObjectARB);
0075:     error |= PADDR(PFNGLDETACHOBJECTARBPROC, glDetachObjectARB);
0076:     error |= PADDR(PFNGLATTACHOBJECTARBPROC, glAttachObjectARB);
0077:     error |= PADDR(PFNGLSHADERSOURCEARBPROC, glShaderSourceARB);
0078:     error |= PADDR(PFNGLCOMPILESHADERARBPROC, glCompileShaderARB);
0079:     error |= PADDR(PFNGLLINKPROGRAMARBPROC, glLinkProgramARB);
0080:     error |= PADDR(PFNGLGETINFOLOGARBPROC, glGetInfoLogARB);
0081:     error |= PADDR(PFNGLUSEPROGRAMOBJECTARBPROC, glUseProgramObjectARB);
0082:     error |= PADDR(PFNGLGETOBJECTPARAMETERIVARBPROC, glGetObjectParameterivARB);
0083:     error |= PADDR(PFNGLGETOBJECTPARAMETERFVARBPROC, glGetObjectParameterfvARB);
0084:     error |= PADDR(PFNGLGETUNIFORMLOCATIONARBPROC, glGetUniformLocationARB);
0085:     error |= PADDR(PFNGLUNIFORM1FARBPROC, glUniform1fARB);
0086:     error |= PADDR(PFNGLUNIFORM2FARBPROC, glUniform2fARB);
0087:     error |= PADDR(PFNGLUNIFORM3FARBPROC, glUniform3fARB);
0088:     error |= PADDR(PFNGLUNIFORM4FARBPROC, glUniform4fARB);
0089:     error |= PADDR(PFNGLUNIFORM1IARBPROC, glUniform1iARB);
0090:     error |= PADDR(PFNGLUNIFORM2IARBPROC, glUniform2iARB);
0091:     error |= PADDR(PFNGLUNIFORM3IARBPROC, glUniform3iARB);
0092:     error |= PADDR(PFNGLUNIFORM4IARBPROC, glUniform4iARB);
0093:     error |= PADDR(PFNGLUNIFORM1FVARBPROC, glUniform1fvARB);
0094:     error |= PADDR(PFNGLUNIFORM2FVARBPROC, glUniform2fvARB);
0095:     error |= PADDR(PFNGLUNIFORM3FVARBPROC, glUniform3fvARB);
0096:     error |= PADDR(PFNGLUNIFORM4FVARBPROC, glUniform4fvARB);
0097:     error |= PADDR(PFNGLUNIFORM1IVARBPROC, glUniform1ivARB);
0098:     error |= PADDR(PFNGLUNIFORM2IVARBPROC, glUniform2ivARB);
0099:     error |= PADDR(PFNGLUNIFORM3IVARBPROC, glUniform3ivARB);
0100:     error |= PADDR(PFNGLUNIFORM4IVARBPROC, glUniform4ivARB);
0101:     if (error) {
0102:         return FALSE;
0103:     }
0104: 
0105:     return S_OK;
0106: }
0107: 
0108: 
0109: //-------------------------------------------------------------
0110: // Name: GetShaderSize
0111: // Desc: ファイルのサイズを調べる
0112: //-------------------------------------------------------------
0113: int GLSL::GetShaderSize(char *fileName)
0114: {
0115:     int fp;
0116:     int count;
0117: 
0118:     // ファイルを開く
0119:     fp = _open(fileName, _O_RDONLY);
0120:     if (fp == -1) return -1;// Open 失敗
0121: 
0122:     // 最後の位置を調べて、サイズを得る
0123:     count = _lseek(fp, 0, SEEK_END);
0124: 
0125:     // ファイルを閉じる
0126:     _close(fp);
0127: 
0128:     return count;
0129: }
0130: 
0131: 
0132: //-------------------------------------------------------------
0133: // Name: ReadShader
0134: // Desc: ファイルを読み込んで、shaderTextに格納する
0135: //-------------------------------------------------------------
0136: HRESULT GLSL::ReadShader(char *fileName, GLubyte *shaderText, int size)
0137: {
0138:     FILE *fp;
0139:     int count;
0140: 
0141:     // ファイルを開く
0142:     fp = fopen(fileName, "r");
0143:     if (!fp) return FALSE;
0144: 
0145:     // ファイルを読み込む
0146:     fseek(fp, 0, SEEK_SET);
0147:     count = fread(shaderText, 1, size, fp);
0148:     shaderText[count] = '\0';
0149: 
0150:     if (ferror(fp)) return FALSE;
0151: 
0152:     // ファイルを閉じる
0153:     fclose(fp);
0154: 
0155:     return count;
0156: }
0157: 
0158: //-------------------------------------------------------------
0159: // Name: readShaderSource
0160: // Desc: シェーダプログラムを読み込む
0161: //-------------------------------------------------------------
0162: HRESULT GLSL::readShaderSource(char *fileName, GLubyte **vertShader, GLubyte **fragShader)
0163: {
0164:     // -------------------------------------------------------
0165:     // ファイル名を決める
0166:     // -------------------------------------------------------
0167:     char vert_fileName[256];// 頂点プログラムのファイル名
0168:     char frag_fileName[256];// フラグメントプログラムのファイル名
0169: 
0170:     strcpy(vert_fileName, fileName); strcat(vert_fileName, ".vert");
0171:     strcpy(frag_fileName, fileName); strcat(frag_fileName, ".frag");
0172: 
0173:     // -------------------------------------------------------
0174:     // シェーダのためのメモリの確保
0175:     // -------------------------------------------------------
0176:     int vertSize = GetShaderSize(vert_fileName);
0177:     int fragSize = GetShaderSize(frag_fileName);
0178: 
0179:     if ((vertSize == -1) || (fragSize == -1)) {
0180:         return FALSE;// シェーダのサイズが決まらなかった
0181:     }
0182: 
0183:     *vertShader = (GLubyte *) malloc(vertSize);
0184:     *fragShader = (GLubyte *) malloc(fragSize);
0185: 
0186:     // -------------------------------------------------------
0187:     // シェーダのソースプログラムを読み込む
0188:     // -------------------------------------------------------
0189:     if (FAILED(ReadShader(vert_fileName, *vertShader, vertSize)))
0190:         return FALSE;// ファイルを読めなかった
0191: 
0192:     if (FAILED(ReadShader(frag_fileName, *fragShader, fragSize)))
0193:         return FALSE;// ファイルを読めなかった
0194: 
0195:     return S_OK;
0196: }
0197: 
0198: 
0199: //-------------------------------------------------------------
0200: // Name: handShadersToOpenGL
0201: // Desc: シェーダを OpenGL へセットアップする
0202: //-------------------------------------------------------------
0203: HRESULT GLSL::handShadersToOpenGL( GLhandleARB Program, GLubyte *vertShader,  GLubyte *fragShader )
0204: {
0205:     // -------------------------------------------------------
0206:     // シェーダに関するオブジェクトの生成
0207:     // -------------------------------------------------------
0208:     GLhandleARB hVertShaderObject = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
0209:     GLhandleARB hFragShaderObject = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
0210: 
0211:     // -------------------------------------------------------
0212:     // OpenGL システムにプログラム文字列を引き渡す
0213:     // -------------------------------------------------------
0214:     int vert_compiled = 0;
0215:     int frag_compiled = 0;
0216:     int linked = 0;
0217:     GLint     length;
0218: 
0219:     length = strlen((char*)vertShader);
0220:     glShaderSourceARB(hVertShaderObject, 1, (const GLcharARB**)&vertShader, &length);
0221: 
0222:     length = strlen((char*)fragShader);
0223:     glShaderSourceARB(hFragShaderObject, 1, (const GLcharARB**)&fragShader, &length);
0224: 
0225:     // -------------------------------------------------------
0226:     // 不必要になったメモリを開放する
0227:     // -------------------------------------------------------
0228:     free(vertShader);
0229:     free(fragShader);
0230: 
0231:     // -------------------------------------------------------
0232:     // シェーダプログラムをコンパイルする
0233:     // -------------------------------------------------------
0234:     glCompileShaderARB(hVertShaderObject);
0235:     glGetObjectParameterivARB(hVertShaderObject,
0236:             GL_OBJECT_COMPILE_STATUS_ARB, &vert_compiled);
0237: 
0238: 
0239:     glCompileShaderARB(hFragShaderObject);
0240:     glGetObjectParameterivARB(hFragShaderObject,
0241:             GL_OBJECT_COMPILE_STATUS_ARB, &frag_compiled);
0242: 
0243:     if (!vert_compiled || !frag_compiled) return FALSE;
0244: 
0245:     // -------------------------------------------------------
0246:     // Program のオブジェクトにそれぞれのシェーダを関連付ける
0247:     // -------------------------------------------------------
0248:     glAttachObjectARB(Program, hVertShaderObject);
0249:     glAttachObjectARB(Program, hFragShaderObject);
0250: 
0251:     // -------------------------------------------------------
0252:     // 不必要になったオブジェクトを削除する
0253:     // -------------------------------------------------------
0254:     glDeleteObjectARB(hVertShaderObject);
0255:     glDeleteObjectARB(hFragShaderObject);
0256: 
0257:     // -------------------------------------------------------
0258:     // 全てをリンクする
0259:     // -------------------------------------------------------
0260:     glLinkProgramARB(Program);
0261:     glGetObjectParameterivARB(Program, GL_OBJECT_LINK_STATUS_ARB, &linked);
0262: 
0263:     if (!vert_compiled || !frag_compiled || !linked) return FALSE;
0264: 
0265:     return S_OK;
0266: }
0267: 
0268: 
0269: //-----------------------------------------------------------------------------
0270: // Name: InitGLSL()
0271: // Desc: GLSL の初期化
0272: //-----------------------------------------------------------------------------
0273: 
0274: HRESULT GLSL::CreateShaderFromFile(char *fileName, GLhandleARB *pProgram)
0275: {
0276:     GLubyte *vertexShader;
0277:     GLubyte *fragmentShader;
0278:     GLhandleARB prog;
0279: 
0280:     // 失敗したときのために初期化
0281:     *pProgram = 0;
0282: 
0283:     // ファイルを読み込む
0284:     if (FAILED(readShaderSource(fileName, &vertexShader, &fragmentShader))) return FALSE;
0285: 
0286:     // シェーダを生成する
0287:     prog = glCreateProgramObjectARB();
0288: 
0289:     // シェーダを OpenGL へセットアップする
0290:     if (FAILED(handShadersToOpenGL( prog, vertexShader, fragmentShader))) return FALSE;
0291: 
0292:     *pProgram = prog;
0293: 
0294:     return S_OK;
0295: }
0296: 
0297: 
0298: 
0299: 
0300: 
0301: 
0302: 
0303: