解像度ぴったりで背景を書く方法

background-true-resolution.png

ポイント

  • 行列は恒等行列にする(つまり何も渡さない)により±1.0渡すだけの楽な頂点セットアップ
  • 使用した画像。やはり、なぜか2のべき乗テクスチャじゃないとうまくいかなかった。使用した画像ファイル→paper64.jpg

ソースコード

#include "BackGround.h"
 
#include <opencv/cv.h>
#include <opencv/highgui.h>
 
#include <miffy/gl/shaderutility.h>
 
BackGround::BackGround()
{
}
 
BackGround::~BackGround()
{
}
 
void BackGround::init()
{
    cv::Mat image = cv::imread("paper64.jpg");
    if (image.empty()) assert(!"OpenCV load image error");
    cv::cvtColor(image, image, CV_BGR2RGB);
    cout << "depth:" << image.depth() << " channel:" << image.channels() << endl;
    glActiveTexture(GL_TEXTURE0);
    glGenTextures(1, &textureId);
    glBindTexture(GL_TEXTURE_2D, textureId);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.cols, image.rows, 0, GL_RGB, GL_UNSIGNED_BYTE, image.data);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
 
    id = miffy::CreateShaderFromFile("backGroundShader.vert", "backGroundShader.frag");
    glUseProgram(id);
    sampler = glGetUniformLocation(id, "uTex");
    winSizeLoc = glGetUniformLocation(id, "uWinsize");
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
 
    GLuint vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    int imageresoloc = glGetUniformLocation(id, "uImageResolution");
    glUniform2f(imageresoloc,(float)image.cols, (float)image.rows);
    static const GLfloat quad_data[] = {
        0.0f,0.0f,
        1.0, 0.0,
        1.0, 1.0,
        0.0f,1.0,
    };
    glBufferData(GL_ARRAY_BUFFER, sizeof(quad_data), quad_data, GL_STATIC_DRAW);
 
    int pos = glGetAttribLocation(id, "inPosition");
    glVertexAttribPointer(pos, 2, GL_FLOAT, GL_FALSE, 0, 0);//位置
    glEnableVertexAttribArray(pos);
    glUseProgram(0);
}
 
void BackGround::draw()
{
    glUseProgram(id);
    glBindVertexArray(vao);
    glActiveTexture(GL_TEXTURE0);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, textureId);
    glUniform1i(sampler, 0);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    glDisable(GL_TEXTURE_2D);
    glUseProgram(0);
}
 
void BackGround::update(float _width, float _height)
{
    glUseProgram(id);
    glUniform2f(winSizeLoc,_width,_height);
    glUseProgram(0);
}

頂点シェーダ

#version 400
out vec2 vUV;
in vec2 inPosition;
void main() {
    vec2 pos = (inPosition - vec2(0.5, 0.5))*2.0;
    gl_Position = vec4(pos, 0.0, 1.0);
    vUV = inPosition;
}

フラグメントシェーダ

#version 400
in vec2 vUV;
uniform sampler2D uTex;
out vec4 frag_color;
uniform vec2 uImageResolution;//画像の解像度
uniform vec2 uWinsize;
void main() {
    vec2 scale = uWinsize / uImageResolution;
    frag_color = texture2D(uTex, vUV*scale);
}

background opengl-background

サポートサイト Wikidot.com backgroundopengl-background