oFでのTextureMapping#01

はじめに

oFで実装されているofTextureなどの関数を使用してというよりかはopenGLレベルでのTextureMappingのやり方のメモを残しておく.テクスチャ系は色々パラメータとか多くて少し触らないと忘れてしまうから..

TextureMappingするまでの手順

Meshの生成

Meshに頂点情報と、それに対になるテクスチャ座標の代入を行う. またここで注意しなければいけないことは読み込まれた画像の座標系では左上が原点でテクスチャ座標空間では左下が原点だということ.

f:id:takaishi78:20190812200318p:plain
座標空間の違い
(↑床井先生のサイトから拝借させていただきました)

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;
}

結果

f:id:takaishi78:20190812202339p:plain

補足(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