質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.04%

opengl texture表示

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 413

miiichat

score 67

いつもありがとうございます!!

テクスチャについて調べてみますが、全然わからなくて、、

シェーダコンパイルでエラーが出ます。

texture2Dは削除されたとあるみたいですが、調べてみてもよくわかりませんでした、、

error
 
 #version 330 core
 in vec4 position;
 in vec2 uv;
 out vec2 vuv;
 void main()
 {
     gl_Position = position;
      vuv = uv;
 }
#version 330 core
in vec2 vuv;
out vec4 fragment;
uniform sampler2D tex;
void main(void){
         fragment  = texture(tex, vuv);
}
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <memory>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <opencv2/core.hpp> 
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>

#include "Object.h"
#include "Shape.h"

using std::vector;

GLboolean printShaderInfoLog(GLuint shader, const char *str)
{
      GLint status;
      glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
      if (status == GL_FALSE) std::cerr << "Compile Error in" << str << std::endl;

      GLsizei bufSize;
      glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &bufSize);

      if (bufSize > 1)
      {
            std::vector<GLchar> infoLog(bufSize);
            GLsizei length;
            glGetShaderInfoLog(shader, bufSize, &length, &infoLog[0]);
            std::cerr << &infoLog[0] << std::endl;
      }

      return static_cast<GLboolean>(status);
}

// プログラムオブジェクトのリンク結果を表示する
// program: プログラムオブジェクト名
GLboolean printProgramInfoLog(GLuint program)
{
      // リンク結果を取得する
      GLint status;
      glGetProgramiv(program, GL_LINK_STATUS, &status);
      if (status == GL_FALSE) std::cerr << "Link Error." << std::endl;
      // シェーダのリンク時のログの長さを取得する
      GLsizei bufSize;
      glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufSize);
      if (bufSize > 1)
      {
            // シェーダのリンク時のログの内容を取得する
            std::vector<GLchar> infoLog(bufSize);
            GLsizei length;
            glGetProgramInfoLog(program, bufSize, &length, &infoLog[0]);
            std::cerr << &infoLog[0] << std::endl;
      }
      return static_cast<GLboolean>(status);
}

//プログラムオブジェクト作成
//  vsrc: バーテックシェーダ
//  fsrc: フラグメントシェーダ
GLuint createProgram(const char *vsrc, const char *fsrc)
{
      const GLuint program(glCreateProgram());

      if (vsrc != NULL)
      {
            const GLuint vobj(glCreateShader(GL_VERTEX_SHADER));
            glShaderSource(vobj, 1, &vsrc, NULL);
            glCompileShader(vobj);

            if (printShaderInfoLog(vobj, "vertex shader"))
                  glAttachShader(program, vobj);
            glDeleteShader(vobj);
      }

      if (fsrc != NULL)
      {
            const GLuint fobj(glCreateShader(GL_FRAGMENT_SHADER));
            glShaderSource(fobj, 1, &fsrc, NULL);
            glCompileShader(fobj);

            if (printShaderInfoLog(fobj, "fragment shader"))
                  glAttachShader(program, fobj);
            glDeleteShader(fobj);
      }
          glBindFragDataLocation(program, 0, "fragment");
        glLinkProgram(program);

      if (printProgramInfoLog(program))
            return program;

      glDeleteProgram(program);
      return program;
}

bool readShaderSource(const char *name, std::vector<GLchar> &buffer)
{
      if (name == NULL) return  false;

      std::ifstream file(name, std::ios::binary);
      if (file.fail())
      {
            std::cerr << "Error: Can't open source file:" << name << std::endl;
            return false;
      }

      file.seekg(0L, std::ios::end);

      GLsizei length = static_cast<GLsizei>(file.tellg());

      buffer.resize(length + 1);

      file.seekg(0L, std::ios::beg);
      file.read(buffer.data(), length);
      buffer[length] = '\0';

      if (file.fail())
      {
            std::cerr << "Error: Could not read source file:" << name << std::endl;
            file.close();
            return false;
      }
}

GLuint loadProgram(const char *vert, const char *frag)
{
      // シェーダのソースファイルを読み込む
      std::vector<GLchar> vsrc;
      const bool vstat(readShaderSource(vert, vsrc));
      std::vector<GLchar> fsrc;
      const bool fstat(readShaderSource(frag, fsrc));
      // プログラムオブジェクトを作成する
      return vstat && fstat ? createProgram(vsrc.data(), fsrc.data()) : 0;
}

Object::Vertex vertex[] = {
      0.5f, 0.5f,
      -0.5f, 0.5f,
      -0.5f, -0.5f,
      0.5f, -0.5f
};

 Object::Vertex uv[] = {
      1, 0,
      0, 0,
      0, 1,
      1, 1,
};


int main()
{
      if (glfwInit() == GL_FALSE)
      {
            std::cerr << "Can't initialize GLFW" << std::endl;
            return 1;
      }

      atexit(glfwTerminate);

      glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
      glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
      glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
      glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

      GLFWwindow *const window = glfwCreateWindow(640, 480, "Hello!", NULL, NULL);

      if (window == NULL)
      {
            std::cerr << "Can't create GLFW Window." << std::endl;
            exit(1);
      }

      glfwMakeContextCurrent(window);

      glewExperimental = GL_TRUE;
      if (glewInit() != GLEW_OK)
      {
            std::cerr << "Can't, initialize GLEW" << std::endl;
            exit(1);
      }

      glfwSwapInterval(1);

      glClearColor(1.0f, 1.0f, 1.0f, 0.0f);

      const GLuint program(loadProgram("point.vert", "point.frag"));

      std::unique_ptr<const Shape> shape(new Shape(2, 4, vertex, program, uv,"texture0.png"));


      while (!(glfwWindowShouldClose(window)))
      {
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            glUseProgram(program);

            shape->draw();

            glfwSwapBuffers(window);
            glfwPollEvents();
      }
}
#pragma once
#include <GL/glew.h>
#include <vector>

class Object
{
      GLuint vao;
      GLuint vbo[2];

protected:

public:
      GLuint texID;
      struct Vertex
      {
            GLfloat position[2];
      };

      Object(GLint size, GLsizei vertexcount, const Vertex *vertex, const GLuint program, const Vertex *uv, std::string texname)
      {
            glGenVertexArrays(1, &vao);
            glBindVertexArray(vao);

            glGenBuffers(2, vbo);
            glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
            glBufferData(GL_ARRAY_BUFFER, vertexcount * sizeof(Vertex), vertex, GL_STATIC_DRAW);
            int positionLocation = glGetAttribLocation(program, "position");
            glVertexAttribPointer(positionLocation, size, GL_FLOAT, GL_FALSE, 0, 0);

            glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
            glBufferData(GL_ARRAY_BUFFER, 2 * sizeof(Vertex), uv, GL_STATIC_DRAW);
            int uvLocation = glGetAttribLocation(program, "uv");
            glVertexAttribPointer(uvLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);

            glEnableVertexAttribArray(positionLocation);
            glEnableVertexAttribArray(uvLocation);

            glGenTextures(1, &texID);
            glBindTexture(GL_TEXTURE_2D, texID);

            //画像の読み込み
            cv::Mat img = cv::imread(texname, cv::IMREAD_UNCHANGED);
            //BGRAからRGBAへ変換
            cv::cvtColor(img, img, cv::COLOR_BGRA2RGBA);

            //テクスチャにデータを紐付ける
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.cols, img.rows, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                  img.data);

            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

            glBindTexture(GL_TEXTURE_2D, 0);
            int textureLocation = glGetUniformLocation(program, "tex");
            glUniform1i(textureLocation, 0);
      }

      void bind() const
      {
            glBindVertexArray(vao);
      }

      virtual ~Object()
      {
            glDeleteBuffers(1, &vao);
            glDeleteBuffers(1, &vbo[0]);
            glDeleteBuffers(1, &vbo[1]);
      }

private:
      //コピーコンストラクタの禁止
      Object(const Object &o);
      //代入によるコピーの禁止
      Object &operator=(const Object &o);
};
#pragma once
#include <memory>
#include <vector>
#include "Object.h"

class Shape
{
      // 図形データ
      std::shared_ptr<const Object> object;

protected:
      const GLsizei vertexcount;

public:
      // コンストラクタ
      // size: 頂点の位置の次元
      // vertexcount: 頂点の数
      // vertex: 頂点属性を格納した配列

      Shape(GLint size, GLsizei vertexcount, const Object::Vertex *vertex, const GLuint program, const Object::Vertex *uv, std::string texname)
            : object(new Object(size, vertexcount, vertex, program, uv, texname))
            , vertexcount(vertexcount)
      {
      }

      // 描画
      void draw() const
      {
            object->bind();
            execute();
      }
      // 描画の実行
      virtual void execute() const
      {
            // 折れ線で描画する
            glBindTexture(GL_TEXTURE_2D, object->texID);
            glDrawArrays(GL_LINE_LOOP, 0, vertexcount);
      }
};
実行結果

四角は表示されます。

回答してくれると嬉しいです!!

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

GLSLは最近ご無沙汰なのでちょっと自信がないですが、pointfrag内で廃止された機能をいくつか使っているようですので...

#version 330 core
in vec2 vuv;
uniform sampler2D texture;
out vec4 fragColor; // gl_FragColorの代わりに自前で定義したout変数を使う
void main(void){
    fragColor = texture(texture, vuv); // texture2Dの代わりにtextureを使う
}

ではどうでしょうか。なにか他にエラーが発生するようでしたらコメントいただけると助かります。

追記

下記部分を変更してみたところ...

main

// 省略

bool readShaderSource(const char *name, std::vector<GLchar> &buffer)
{
    // 省略

    // 最後にストリームを閉じて戻る部分が欠落していたようなので追加しました
    file.close();
    return true;
}

// 省略

// 頂点位置の順序を逆Z字形に変更
Object::Vertex vertex[] = {
    0.5f, 0.5f,
    -0.5f, 0.5f,
    0.5f, -0.5f,
    -0.5f, -0.5f,
};

// UVの順序を逆Z字形に変更
Object::Vertex uv[] = {
    1.0f, 0.0f,
    0.0f, 0.0f,
    1.0f, 1.0f,
    0.0f, 1.0f,
};

// 省略

Object

    // 省略

    Object(GLint size, GLsizei vertexcount, const Vertex *vertex, const GLuint program, const Vertex *uv, std::string texname)
    {
        // 省略

        glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);

        // 2 * sizeof(Vertex)をvertexcount * sizeof(Vertex)に変更
        glBufferData(GL_ARRAY_BUFFER, vertexcount * sizeof(Vertex), uv, GL_STATIC_DRAW);

        int uvLocation = glGetAttribLocation(program, "uv");
        glVertexAttribPointer(uvLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);

        // 省略
    }

    // 省略

Shape

    // 省略

    virtual void execute() const
    {
        // 折れ線で描画する
        glBindTexture(GL_TEXTURE_2D, object->texID);

        // GL_LINE_LOOPをGL_TRIANGLE_STRIPに変更
        glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexcount);
    }

    // 省略

下図のような描画結果が得られました。

結果

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/04/23 21:45

    回答ありがとうございます!!
    更新しましたところerror全部消えました!!

    でもまだ画像が表示されなくて、しかくも消えました。

    fragmentは
    glBindFragDataLocation(program, 0, "fragment");
    は必要ですか?

    キャンセル

  • 2019/04/24 05:30

    いえ、必ずしも指定しなくても自動的にロケーション0番が割り当てられるはずですので不要かと思います。

    ご質問者さんのコードを実行してみましたが、描画はちゃんと行われているようでした(描画モードがGL_LINE_LOOPだったので枠線だけしか描かれませんでしたが...)。
    テクスチャの外周部が透明だったために何も描画されていないように見えてしまった...といった可能性はないでしょうか?

    描画モードをGL_TRIANGLE_STRIPに変えたほか、いくつかの変更を加えたものを追記しました。ご参考になりますでしょうか?

    キャンセル

  • 2019/04/24 15:57

    ありがとうございます!!できました!!

    三日ぐらい悩んでたので助かりました、、

    本当にありがとうございました!!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.04%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る