LoginSignup
0
0

More than 3 years have passed since last update.

[openFrameworks]ofDisableArbTexの挙動,samper2Dとsampler2DRectの違い

Last updated at Posted at 2019-04-30

はじめに

oFでTextureMappingなどを行うときにofDisableArbTexを呼ぶときと呼ばない場合があり,glsl内でも受け取り方が変わってくるのでそこら辺をまとめて行こうと思います.

結論

以下で説明を述べますが,結論から述べるsampler2D型であるとuvは正規化されている必要があり,sampler2DRectであるとuvは画像のテクセル数と対応させる必要があるといった感じです.

ofDisableArbTexを適応しなかった場合

ofDisableArbTexを呼ばないと内部ではGL_TEXTURE_RECTANGLE_ARBのモードでテクスチャが生成されます.そのためofApp.cppで見てわかる通りuv座標をmeshに対応させるのではなく,画像サイズをベースにしたテクセルの座標系を割り当てていることが特徴となります.

FragmentShader内部ではsampgler2DRect型でtextureを受け取ります.

ofApp.h
#pragma once
#include "ofMain.h"
class ofApp : public ofBaseApp {
public:
    void setup();
    void update();
    void draw();

    ofEasyCam cam;
    ofShader shader;
    ofVboMesh vboMesh;
    ofImage img;
    ofVec3f pos;
};
ofApp.cpp
#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup() {
    ofSetFrameRate(60);
    ofSetBackgroundColor(0);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);


    shader.load("shaders/shader");


    img.load("texture0.png");
    pos = ofVec3f(0.0, 0.0, 0.0);

    ofVec2f imgSize = ofVec2f(img.getWidth(), img.getHeight());
    vboMesh.addVertex(ofVec3f(-imgSize.x/2.0, -imgSize.y/2.0, 0.0));
    vboMesh.addVertex(ofVec3f(imgSize.x/2.0, -imgSize.y/2.0, 0.0));
    vboMesh.addVertex(ofVec3f(imgSize.x/2.0, imgSize.y/2.0, 0.0));
    vboMesh.addVertex(ofVec3f(-imgSize.x/2.0, imgSize.y/2.0, 0.0));

    vboMesh.addIndex(0);
    vboMesh.addIndex(1);
    vboMesh.addIndex(2);
    vboMesh.addIndex(2);
    vboMesh.addIndex(3);
    vboMesh.addIndex(0);

    //サンプリングする座標は画像サイズベース
    vboMesh.addTexCoord(ofVec2f(0.0, imgSize.y));
    vboMesh.addTexCoord(ofVec2f(imgSize.x, imgSize.y));
    vboMesh.addTexCoord(ofVec2f(imgSize.x, 0.0));
    vboMesh.addTexCoord(ofVec2f(0.0, 0.0));    
}

//--------------------------------------------------------------
void ofApp::update() {
    ofSetWindowTitle(ofToString(ofGetFrameRate()));
}

//--------------------------------------------------------------
void ofApp::draw() {
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClearDepth(1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    cam.begin();
    cam.lookAt(ofVec3f(0.0, 0.0, 0.0), ofVec3f(0.0, 1.0, 0.0));
    img.getTexture().bind();

    shader.begin();

    ofMatrix4x4 modelMatrix;
    ofMatrix4x4 viewMatrix;
    viewMatrix = ofGetCurrentViewMatrix();
    ofMatrix4x4 projectionMatrix;
    projectionMatrix = cam.getProjectionMatrix();
    ofMatrix4x4 mvpMatrix;
    mvpMatrix = modelMatrix * viewMatrix * projectionMatrix;

    shader.setUniformMatrix4f("model", modelMatrix);
    shader.setUniformMatrix4f("view", viewMatrix);
    shader.setUniformMatrix4f("projection", projectionMatrix);
    shader.setUniformMatrix4f("mvp", mvpMatrix);
    shader.setUniformTexture("tex0", img.getTexture(), 0);

    vboMesh.draw();
    shader.end();

    img.getTexture().unbind();
    cam.end()
}

shader.vert
#version 150
precision mediump float;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform mat4 mvp;

in vec2 texcoord;
in vec3 position;
in vec4 color;

out vec2 vTextureCoord;
out vec4 vColor;

void main() {
    vTextureCoord = texcoord;
    vColor = color;
    //gl_Position = projection * view * model * vec4(position, 1.0);
    gl_Position = mvp * vec4(position, 1.0);
}

shader.frag
#version 150
precision mediump float;
uniform sampler2DRect tex0;

in vec2 vTextureCoord;
in vec4 vColor;

out vec4 outputColor;

void main(){
    vec4 smpColor = texture(tex0, vTextureCoord);
    outputColor  = vColor * smpColor;
}

bandicam 2019-04-30 18-57-24-344.jpg

ofDisableArbTexを適応した場合

ofDisableArbTexを適応した場合,GL_TEXTURE_2Dモードでテクスチャが生成されます.
ofApp.cppではmeshにtextureのuv座標を割り当ててます.生openGLではこちらの方がメジャーだと思いますので,oFを使う際には注意が必要ですね..
またFragmentShader内部ではsampgler2D型でtextureを受け取ります.
(*下記に載せていない部分のコードは上のコードから変更はありません)

ofApp.cpp
#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup() {
    ofSetFrameRate(60);
    ofSetBackgroundColor(0);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);

    // shader setings
    shader.load("shaders/shader");


    // load image
    ofDisableArbTex();
    img.load("texture0.png");
    pos = ofVec3f(0.0, 0.0, 0.0);

    ofVec2f imgSize = ofVec2f(img.getWidth(), img.getHeight());

    vboMesh.addVertex(ofVec3f(-imgSize.x/2.0, -imgSize.y/2.0, 0.0));
    vboMesh.addVertex(ofVec3f(imgSize.x/2.0, -imgSize.y/2.0, 0.0));
    vboMesh.addVertex(ofVec3f(imgSize.x/2.0, imgSize.y/2.0, 0.0));
    vboMesh.addVertex(ofVec3f(-imgSize.x/2.0, imgSize.y/2.0, 0.0));

    vboMesh.addIndex(0);
    vboMesh.addIndex(1);
    vboMesh.addIndex(2);
    vboMesh.addIndex(2);
    vboMesh.addIndex(3);
    vboMesh.addIndex(0);

    //ofDisableArbTex()の場合
    //サンプリングする座標はuv座標系ベース
    vboMesh.addTexCoord(ofVec2f(0.0, 1.0));
    vboMesh.addTexCoord(ofVec2f(1.0, 1.0));
    vboMesh.addTexCoord(ofVec2f(1.0, 0.0));
    vboMesh.addTexCoord(ofVec2f(0.0, 0.0));
}

//--------------------------------------------------------------
void ofApp::update() {
    ofSetWindowTitle(ofToString(ofGetFrameRate()));
}

//--------------------------------------------------------------
void ofApp::draw() {
    glEnable(GL_TEXTURE_2D);

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClearDepth(1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    cam.begin();
    cam.lookAt(ofVec3f(0.0, 0.0, 0.0), ofVec3f(0.0, 1.0, 0.0));
    img.getTexture().bind();


    shader.begin();

    ofMatrix4x4 modelMatrix;
    ofMatrix4x4 viewMatrix;
    viewMatrix = ofGetCurrentViewMatrix();
    ofMatrix4x4 projectionMatrix;
    projectionMatrix = cam.getProjectionMatrix();
    ofMatrix4x4 mvpMatrix;
    mvpMatrix = modelMatrix * viewMatrix * projectionMatrix;

    shader.setUniformMatrix4f("model", modelMatrix);
    shader.setUniformMatrix4f("view", viewMatrix);
    shader.setUniformMatrix4f("projection", projectionMatrix);
    shader.setUniformMatrix4f("mvp", mvpMatrix);
    shader.setUniformTexture("tex0", img.getTexture(), 0);

    for (int j = 0; j<vboMesh.getVertices().size(); j++) {
        vboMesh.addColor(ofFloatColor(1.0, 1.0, 1.0, 1.0));
    }

    vboMesh.draw();
    shader.end();

    img.getTexture().unbind();
    cam.end();
}

shader.frag
#version 150
precision mediump float;

// this is how we receive the texture
uniform sampler2D tex0;

in vec2 vTextureCoord;
in vec4 vColor;

out vec4 outputColor;

void main(){
    vec4 smpColor = texture(tex0, vTextureCoord);
    outputColor  = vColor * smpColor;
}

bandicam 2019-04-30 18-57-24-344.jpg

まとめ

oFでtextureを扱うのは奥が深いなぁと思いながらも色々試してみるのが楽しいのでこれからも色々やっていきたいと思います.textureMapping周りでまた何か発見があれば更新をかけたいと思います.

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0