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();
}
}
私は '' NULL'ness "のソースである' free(texture_bytes) 'を疑う:D。それをコメントアウトしてみてください。 – sarasvati
@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
OpenGLコンテキストはどこに作成しますか?これらのGLテクスチャ操作のどれも現在のGLコンテキストなしでは動作しません。 [mcve]で編集します。 – genpfault