glTexImage3D引发错误1282(无效操作)

时间:2019-08-02 08:44:01

标签: c++ c opengl textures

我正在尝试通过OpenGL将体积数据作为3D纹理上传。但是,当通过glTexImage3D指定格式和数据本身时,将引发GL_INVALID_OPERATION错误。

以下代码(包括我添加的用于发现错误来源的调试代码):

void Texture3D::upload()
{
  std::cout << "TEX GL ERROR: " << glGetError() << std::endl;

  glGenTextures(1, &_textureId);
  std::cout << "TEX GL ERROR: " << glGetError() << std::endl;

  glBindTexture(GL_TEXTURE_3D, _textureId);
  std::cout << "TEX GL ERROR: " << glGetError() << std::endl;

  glTexStorage3D(GL_TEXTURE_3D, 6, GL_R8, _width, _height, _depth);
  std::cout << "TEX GL ERROR: " << glGetError() << std::endl;

  glTexImage3D(GL_TEXTURE_3D, 0, GL_R8, _width, _height, _depth, 0,  GL_RED,  GL_UNSIGNED_BYTE, _data);
  std::cout << "TEX GL ERROR: " << glGetError() << std::endl;

  glGenerateMipmap(GL_TEXTURE_3D);

  std::cout << "TEX GL ERROR: " << glGetError() << std::endl;
  }

我认为对于glTexImage3D中指定的任何格式,内部格式或像素格式,它都可能是GL_INVALID_VALUE,但是我已经查看了glTexImage3D的文档,一切似乎都正确

我创建了一个最小的可验证示例(使用GLFW和GLEW)

#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>

GLFWwindow * _window = nullptr;
unsigned int _textureId = GL_INVALID_VALUE;

void initGLFWContext()
{
  if (!glfwInit())
    {
      std::cerr << "GLFW: Couldnt initialize" << std::endl;
      exit(-1);
    }

    glfwWindowHint(GLFW_SAMPLES, 4);

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);

    glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);

    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 

    _window = glfwCreateWindow(1024, 1024, "Test Window", NULL, NULL);
    if (!_window)
    {
      std::cerr << "GLFW Error: Couldnt create window" << std::endl;
      glfwTerminate();
      exit(-1);
    }

    //glfwSetKeyCallback(_window, kbCb);
    //glfwSetCursorPosCallback(_window, mmCb);
    //glfwSetMouseButtonCallback(_window, mCb);
    //glfwSetFramebufferSizeCallback(_window, resizeCb);

    glfwMakeContextCurrent(_window);

    glfwSetWindowPos(_window, 0, 0);

    glfwSwapInterval(1);

    // Initializes glew
    glewExperimental = GL_TRUE;
    GLenum err = glewInit();
    if (GLEW_OK != err)
    {
      std::cerr << "GLEW Error: " << glewGetErrorString(err) << std::endl;
      exit(-1);
    }
}

void initOpenGL()
{
  glEnable(GL_DEPTH_TEST);
  //glEnable(GL_BLEND);
  glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
  glFrontFace(GL_CCW);
  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  glEnable(GL_CULL_FACE);
}

void minimalVerifiableExample()
{
  initGLFWContext();
  initOpenGL();

  const unsigned int volSide = 256;
  const unsigned int volumeSize = volSide * volSide * volSide;
  unsigned char * volumeData = new unsigned char[volumeSize]();

  std::cout << "TEX GL ERROR: " << glGetError() << std::endl;

  glGenTextures(1, &_textureId);
  std::cout << "TEX GL ERROR: " << glGetError() << std::endl;

  glBindTexture(GL_TEXTURE_3D, _textureId);
  std::cout << "TEX GL ERROR: " << glGetError() << std::endl;

  glTexStorage3D(GL_TEXTURE_3D, 
                 6, 
                 GL_R8, 
                 volSide, 
                 volSide, 
                 volSide);
  std::cout << "TEX GL ERROR: " << glGetError() << std::endl;

  glTexImage3D(GL_TEXTURE_3D, 
               0, 
               GL_R8, 
               volSide, 
               volSide, 
               volSide, 
               0, 
               GL_RED, 
               GL_UNSIGNED_BYTE, 
               volumeData);
  std::cout << "TEX GL ERROR: " << glGetError() << std::endl;

  glGenerateMipmap(GL_TEXTURE_3D);
  std::cout << "TEX GL ERROR: " << glGetError() << std::endl;

  while(!glfwWindowShouldClose(_window))
  {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glfwPollEvents();
    glfwSwapBuffers(_window);
  }

  glfwDestroyWindow(_window);
  glfwTerminate();

  delete[] volumeData;
}

int main(int argc, char ** argv)
{
  (void) argc;
  (void) argv;
  minimalVerifiableExample();
  return 0;
}

这是我得到的输出:

TEX GL ERROR: 0
TEX GL ERROR: 0
TEX GL ERROR: 0
TEX GL ERROR: 0
TEX GL ERROR: 1282
TEX GL ERROR: 0

上传纹理或其他任何地方时我做错什么了吗?

1 个答案:

答案 0 :(得分:4)

1282是using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; //This line is important public class TextBehaviour : MonoBehaviour { //declare the text as a public variable public Text myText; //method for changing the text public void changeText() { myText.text = "my text will change to this"; } } ,由

的组合引起
GL_INVALID_OPERATION

不允许为不可变的存储纹理对象重新创建存储。调用glTexStorage3D glTexImage3D 之后,纹理将使用不可变的存储。 glTexStorage3D请求新的存储空间,该存储空间不再可用。

如果您尝试将数据上传到不可变的存储纹理对象,则必须使用glTexImage3D来上传数据,但不请求新的存储。