マルチテクスチャです。
今回のプログラムは地球の地表テクスチャと雲のテクスチャを合成し、
地表よりも雲を遅れて回転させています。
マウスの左ドラッグで視点を変更できます。
画像はNASAがフリーで配布している物を縮小して使用しています。
earth.png
cloud.png
vertex.shader
varying vec3 P; void main(void) |
flagment.shader
varying vec3 P; void main(void) |
GLSL.h
#pragma once #include <stdio.h> //GLSLクラス class GLSL{ public: GLuint ShaderProg; GLuint VertexShader, FragmentShader; void ReadShaderCompile(GLuint Shader, const char *File);//shader fileを読み込みコンパイルする void Link( GLuint Prog );//リンクする void InitGLSL(const char *VertexFile);//GLSLの初期化 void InitGLSL(const char *VertexFile, const char *FragmentFile);//GLSLの初期化 void ON();//シェーダー描画に切り替え void OFF();//シェーダー解除 ~GLSL(); }; void GLSL::ReadShaderCompile(GLuint Shader, const char *File){ FILE *fp; char *buf; GLsizei size, len; GLint compiled; fopen_s(&fp,File, "rb"); if(!fp) printf("ファイルを開くことができません %s\n", File); fseek(fp, 0, SEEK_END); size = ftell(fp); buf = (GLchar *)malloc(size); if (buf == NULL) { printf("メモリが確保できませんでした \n"); } fseek(fp, 0, SEEK_SET); fread(buf, 1, size, fp); glShaderSource(Shader, 1, (const GLchar **)&buf, &size); free(buf); fclose(fp); glCompileShader(Shader); glGetShaderiv( Shader, GL_COMPILE_STATUS, &compiled ); if ( compiled == GL_FALSE ) { printf( "コンパイルできませんでした!!: %s \n ", File); glGetProgramiv( Shader, GL_INFO_LOG_LENGTH, &size ); if ( size > 0 ) { buf = (char *)malloc(size); glGetShaderInfoLog( Shader, size, &len, buf); printf(buf); free(buf); } } } void GLSL::Link( GLuint Prog ){ GLsizei size, len; GLint linked; char *infoLog ; glLinkProgram( Prog ); glGetProgramiv( Prog, GL_LINK_STATUS, &linked ); if ( linked == GL_FALSE ){ printf("リンクできませんでした!! \n"); glGetProgramiv( Prog, GL_INFO_LOG_LENGTH, &size ); if ( size > 0 ){ infoLog = (char *)malloc(size); glGetProgramInfoLog( Prog, size, &len, infoLog ); printf(infoLog); free(infoLog); } } } void GLSL::InitGLSL(const char *VertexFile){ GLenum err = glewInit(); if (err != GLEW_OK) { printf("Error: %s\n", glewGetErrorString(err)); } printf("VENDOR= %s \n", glGetString(GL_VENDOR)); printf("GPU= %s \n", glGetString(GL_RENDERER)); printf("OpenGL= %s \n", glGetString(GL_VERSION)); printf("GLSL= %s \n", glGetString(GL_SHADING_LANGUAGE_VERSION)); VertexShader = glCreateShader(GL_VERTEX_SHADER); ReadShaderCompile(VertexShader, VertexFile); ShaderProg = glCreateProgram(); glAttachShader(ShaderProg, VertexShader); glDeleteShader(VertexShader); Link(ShaderProg); } void GLSL::InitGLSL(const char *VertexFile, const char *FragmentFile){ GLenum err = glewInit(); if (err != GLEW_OK) { printf("Error: %s\n", glewGetErrorString(err)); } printf("VENDOR= %s \n", glGetString(GL_VENDOR)); printf("GPU= %s \n", glGetString(GL_RENDERER)); printf("OpenGL= %s \n", glGetString(GL_VERSION)); printf("GLSL= %s \n", glGetString(GL_SHADING_LANGUAGE_VERSION)); VertexShader = glCreateShader(GL_VERTEX_SHADER); FragmentShader = glCreateShader(GL_FRAGMENT_SHADER); ReadShaderCompile(VertexShader, VertexFile); ReadShaderCompile(FragmentShader, FragmentFile); ShaderProg = glCreateProgram(); glAttachShader(ShaderProg, VertexShader); glAttachShader(ShaderProg, FragmentShader); glDeleteShader(VertexShader); glDeleteShader(FragmentShader); Link(ShaderProg); } void GLSL::ON(){ glUseProgram(ShaderProg); } void GLSL::OFF(){ glUseProgram(0); } GLSL::~GLSL(){ glDeleteProgram(ShaderProg); } |
PNG.h
#pragma once #include "lodepng.h" //テクスチャクラス class TEXTURE{ protected: LodePNG_Decoder decoder;//デコーダ unsigned char* buffer;//バッファ size_t buffersize, imagesize;//サイズ public: TEXTURE(); TEXTURE(const char* FileName);//コンストラクタ void LOAD_PNG(const char* FileName);//PNG読み込み unsigned char* image;//イメージポインタ unsigned int Width,Height;//画像サイズ }; TEXTURE::TEXTURE(){ } TEXTURE::TEXTURE(const char* FileName){ LOAD_PNG(FileName); } void TEXTURE::LOAD_PNG(const char* FileName){ LodePNG_Decoder_init(&decoder); //ロード LodePNG_loadFile(&buffer, &buffersize, FileName); //デコード LodePNG_decode(&decoder, &image, &imagesize, buffer, buffersize); //幅,高さ Width = decoder.infoPng.width;Height = decoder.infoPng.height; } |
main.cpp
#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup") #include <windows.h> float lightPos[] = {10.0f, 15.0f, 10.0f, 1.0f};//光源位置 struct View{ GLSL glsl; float cloudpos = 0.0f; #define PAI 3.141592f
for(j = 0; j < nStack; j++){ glBegin(GL_QUAD_STRIP); glNormal3dv(p[0]); glNormal3dv(p[1]); float diffuse[][4] = {{ 0.7f, 0.7f, 0.7f, 1.0f}, { 0.1f, 0.1f, 0.1f, 1.0f}
}; glNormal3f(0.0f, 1.0f, 0.0f); glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse[(i + j) & 1]); void drawTexSphere(double radius, int nSlice, int nStack, int nRepeatS, int
nRepeatT){ for(j = 0; j < nStack; j++){ t0 = (1.0 - t0) * nRepeatT; glEnable(GL_TEXTURE_2D); s *= nRepeatS; glTexCoord2d(s, t0); glTexCoord2d(s, t1); void resize(int w, int h){ void TexCreate(int NO,char* FileName){ glEnable(GL_LIGHT0); if(flagShadow){ glPushMatrix(); if(!flagShadow){ x = lightPos[0]; //光源の方向ベクトル //フロアの方向ベクトル(y方向) flagShadow = true; glDepthMask(GL_FALSE); glDepthMask(GL_TRUE); setCamera();//視点を求める void display(void){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLightfv(GL_LIGHT0, GL_POSITION, lightPos); glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); //texture unit と texture object の関連付け glsl.ON(); glsl.OFF(); drawFloor(20.0, 20.0, 20, 20); glutSwapBuffers();
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN){ void motion(int x, int y){ setCamera();
int main(int argc, char *argv[]) |