oFでのTextureMapping#01
はじめに
oFで実装されているofTextureなどの関数を使用してというよりかはopenGLレベルでのTextureMappingのやり方のメモを残しておく.テクスチャ系は色々パラメータとか多くて少し触らないと忘れてしまうから..
TextureMappingするまでの手順
Meshの生成
Meshに頂点情報と、それに対になるテクスチャ座標の代入を行う. またここで注意しなければいけないことは読み込まれた画像の座標系では左上が原点でテクスチャ座標空間では左下が原点だということ.
(↑床井先生のサイトから拝借させていただきました)
addTexCoord関数について
この関数の引数への渡すデータはテクスチャ空間での座標系ではなく画像空間での座標を渡すことに注意.
void ofApp::Setup(){ shader.load("Shaders/shader"); img.load("texSample.png"); //VboMesh mesh mesh.setMode(ofPrimitiveMode::OF_PRIMITIVE_TRIANGLE_FAN); float imgSize = img.getWidth(); float size = 100.0; mesh.addTexCoord(ofVec2f(0.0, 0.0)); mesh.addVertex(ofVec3f(-size, size, 0.0)); mesh.addTexCoord(ofVec2f(0, imgSize)); mesh.addVertex(ofVec3f(-size, -size, 0.0)); mesh.addTexCoord(ofVec2f(imgSize, imgSize)); mesh.addVertex(ofVec3f(size, -size, 0.0)); mesh.addTexCoord(ofVec2f(imgSize, 0.0)); mesh.addVertex(ofVec3f(size, size, 0.0)); }
TextureをShaderへ転送
img.getTexture().bind()をすることによってshader側で宣言されているsampler2D型で宣言されているuniform変数にテクスチャデータが転送される.
void ofApp::Draw(){
img.getTexture().bind();
cam.begin();
shader.begin();
mesh.draw();
shader.end();
cam.end();
img.getTexture().unbind();
}
//vertex shader #version 120 varying vec4 position; void main(void) { position = gl_ModelViewMatrix * gl_Vertex; gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; gl_Position = ftransform(); }
//fragment shader #version 120 uniform sampler2D tex0; void main(void) { // テクスチャ vec3 color_tex0 = texture2D(tex0, gl_TexCoord[0].st).xyz; gl_FragColor.rgb = color_tex0; gl_FragColor.a = 1.0; }
結果
補足(Sampler2D型とSampler2DRect型の違い)
ofDisableArbTex関数を呼ぶことによって画像座標空間が正規化される.そうした場合Shader側で受け取るuniform変数はsampler2D型としなければいけない.
void ofApp::Setup(){ ofBackground(0); ofDisableArbTex(); shader.load("Shaders/shader"); img.load("texture01.jpeg"); mesh.setMode(ofPrimitiveMode::OF_PRIMITIVE_TRIANGLE_FAN); float imgSize = 1.0; float size = 100.0; mesh.addTexCoord(ofVec2f(0.0, 0.0)); mesh.addVertex(ofVec3f(-size, size, 0.0)); mesh.addTexCoord(ofVec2f(0, imgSize)); mesh.addVertex(ofVec3f(-size, -size, 0.0)); mesh.addTexCoord(ofVec2f(imgSize, imgSize)); mesh.addVertex(ofVec3f(size, -size, 0.0)); mesh.addTexCoord(ofVec2f(imgSize, 0.0)); mesh.addVertex(ofVec3f(size, size, 0.0)); }
#version 120 //uniform sampler2DRect tex0; uniform sampler2D tex0; varying vec2 texCoordVarying; void main() { //gl_FragColor = vec4(1.0); gl_FragColor = texture2DRect(tex0, texCoordVarying); }
ソースコード
https://github.com/KeitoTakaishi/VolumeRendereringExpt/tree/master/TextureTest01