2016-07-26 15 views
-1

glTexImage2D()glGetTexImage()に関するいくつかの問題が発生しました。glTexImage2DとglGetTexImageを使用したいくつかの問題

私のコードでは、OpenCVのimread()を使用して画像をロードしようとしていて、それをtexture_idハンドルを持つテクスチャフォーマットに変換してから再びマトリックスタイプ(OpenCVのMat)に変換し直しています。途中で画像のデータが失われていると思われ、image.dataがNULLを返します。

私の問題は、matToTexture()の実装のどこかにあると考えられます。

私はVisual Studio 15でOpenCV 3.1とOpenGL 4.4を使ってC++で書いています。

Texture.cpp:

#include "Texture.h" 

Mat textureToMat(GLuint textureID); 
GLuint matToTexture(Mat image); 

GLuint matToTexture(Mat image) { 

    GLuint texture_id; 

    if (image.empty()) { 
     cout << "Image empty." << endl; 
    } 

    else { 

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

     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 

     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 

     glTexImage2D(GL_TEXTURE_2D, 
      0, 
      GL_RGB, 
      image.cols, 
      image.rows, 
      0, 
      GL_BGR, 
      GL_UNSIGNED_BYTE, 
      image.ptr()); 

    } 

    return texture_id; 
} 

Mat textureToMat(GLuint texture_id) { 

    glBindTexture(GL_TEXTURE_2D, texture_id); 
    GLenum texture_width, texture_height, texture_format; 

    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, (GLint*)&texture_width); 
    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, (GLint*)&texture_height); 
    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, (GLint*)&texture_format); 

    unsigned char* texture_bytes = (unsigned char*)malloc(sizeof(unsigned char)*texture_width*texture_height * 3); 

    glGetTexImage(GL_TEXTURE_2D, 0, GL_BGR, GL_UNSIGNED_BYTE, texture_bytes); 

    Mat out(texture_height, texture_width, CV_8UC3, texture_bytes); 

    free(texture_bytes); 

    return out; 

} 

とヘッダTexture.h:

#ifndef TEXTURE_H 
#define TEXTURE_H 

#include "glew.h" 
#include "glfw3.h" 

#include <string> 
#include <iostream> 
#include <sstream> 
#include <iterator> 
#include <vector> 
#include <opencv\highgui.h> 
#include <opencv\cv.h> 
#include <opencv2\opencv.hpp> 

using namespace std; 
using namespace cv; 

Mat textureToMat(GLuint textureID); 
GLuint matToTexture(Mat image); 

#endif /*!TEXTURE_H*/ 

そしてコール:

#include "Texture.h" 

int main(){ 

    glfwInit(); 
    glewExperimental = GL_TRUE; 
    glewInit(); 

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4); 
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); 

    GLFWwindow* offscreen_context = glfwCreateWindow(800, 600, "OpenGL", nullptr, nullptr); 
    glfwMakeContextCurrent(offscreen_context); 

    Mat dummy = imread("mini.jpg", CV_LOAD_IMAGE_COLOR); 

    GLuint tex = matToTexture(dummy); 

    glBindTexture(GL_TEXTURE_2D, tex); 

    Mat some = textureToMat(tex); 

    while (!glfwWindowShouldClose(offscreen_context)) { 

     glfwSwapBuffers(offscreen_context); 
     glfwPollEvents(); 

     if (glfwGetKey(offscreen_context, GLFW_KEY_ESCAPE) == GLFW_PRESS) { 
      glfwSetWindowShouldClose(offscreen_context, GL_TRUE); 
     } 
    } 

    glfwTerminate(); 


    } 
} 
+0

私は '' NULL'ness "のソースである' free(texture_bytes) 'を疑う:D。それをコメントアウトしてみてください。 – sarasvati

+1

@sarasvatiは正しいです。 'Mat out(texture_height、texture_width、CV_8UC3、texture_bytes)'はデータの浅いコピーを提供し、内部では 'texture_bytes'を指定します。この問題を解決するには 'Mat out = Mat(texture_height、texture_width、CV_8UC3、texture_bytes).clone()'を実行することができます。正しいサイズのMatを作成し、 'Mat'で' glGetTexImage'コピーを避ける。 – cxyzs7

+0

OpenGLコンテキストはどこに作成しますか?これらのGLテクスチャ操作のどれも現在のGLコンテキストなしでは動作しません。 [mcve]で編集します。 – genpfault

答えて

0

あなたはOpenGLのコンテキストを作成しないでください。そのような単純なプレーン。 OpenGLコンテキストが作成されておらず、現在のスレッドでアクティブになっていなければ、すべてのOpenGL関数呼び出しはno-opsです。

+0

ありがとう!あなたはおそらく私がOpenGLにはかなり新しいと言うことができるので、これは私には起こりませんでした。私は今それを読んでいる。 –

+0

私は自分の使用のためのコンテキストを作成するための情報を見つけようとしましたが、わかりにくいです。上のコードを更新して、.cpp、.h、および呼び出しセクションで区切られています。私はどこで文脈を述べなければならないのですか?これまでのところ、ウィンドウを描画するためのコンテキストを作成するためのチュートリアルは見つかりませんでしたが、これは私が望むものではありません。 –

+0

@ T.Soemod:OpenGLコンテキストを作成することは(残念ながら)重要ではありません。これは、それを扱ういくつかのアプリケーションフレームワークの存在を説明します(GLUT、GLFW、SMFL、SDL)。 OpenGLは常にリアルタイムレンダリングに焦点を当て、結果の画像をディスプレイに送信しました。 OpenGL自体はウィンドウシステムに中立ですが、OpenGLコンテキストを実際に作成するために必要なAPIは、ウィンドウシステム(WGL、GLX、NSOpenGLView)に関連付けられています。 – datenwolf

関連する問題