Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ OpenGL(ES)图像处理C++;_C++_Opengl Es_Shader_Opengl Es 2.0 - Fatal编程技术网

C++ OpenGL(ES)图像处理C++;

C++ OpenGL(ES)图像处理C++;,c++,opengl-es,shader,opengl-es-2.0,C++,Opengl Es,Shader,Opengl Es 2.0,我目前正在尝试使用OpenGL ES进行图像处理。我正在尝试一些基本的图像效果,比如模糊、切换颜色空间等等。 我想构建最简单的程序来执行以下操作: 图像加载 图像处理(使用着色器) 图像保存 我已成功构建以下设置: OpenGL上下文 我想做的图像效果加载使用魔鬼 两个着色器(一个顶点着色器和一个片段着色器) 我现在只能使用我加载的图像将数据发送到片段着色器。我试图做的是将图像作为一个sampler2D发送到片段着色器,并对其进行处理 我有多个问题,例如: 如果我只想做纯2D图像处理,

我目前正在尝试使用OpenGL ES进行图像处理。我正在尝试一些基本的图像效果,比如模糊、切换颜色空间等等。 我想构建最简单的程序来执行以下操作:

  • 图像加载
  • 图像处理(使用着色器)
  • 图像保存
我已成功构建以下设置:

  • OpenGL上下文
  • 我想做的图像效果加载使用魔鬼
  • 两个着色器(一个顶点着色器和一个片段着色器)
我现在只能使用我加载的图像将数据发送到片段着色器。我试图做的是将图像作为一个sampler2D发送到片段着色器,并对其进行处理

我有多个问题,例如:

  • 如果我只想做纯2D图像处理,是否需要顶点着色器
  • 如果我这样做了,在这个顶点着色器中应该做什么,因为我根本没有顶点。我是否应该创建四边形顶点(如(0,0)(1,0)(0,1)(1,1))?若然,原因为何
  • 我是否需要使用VBO(似乎与顶点着色器相关)、FBO或其他类似的东西
  • 我不能将图像加载到纹理中,然后等待片段着色器对该纹理执行我想要的所有操作吗
  • 有人能提供一些简单的“干净”代码来帮助我理解吗(没有任何使理解变得如此复杂的奇特类)
下面是我的片段着色器用于简单颜色交换的外观:

uniform int width;
uniform int height;
uniform sampler2D texture;

void main() {
    vec2 texcoord = vec2(gl_FragCoord.x/width, gl_FragCoord.y/height);
    vec4 texture_value = texture2D(texture, texcoord);
    gl_FragColor = texture_value.bgra;
}
还有我的main.cpp:

int main(int argc, char** argv)
{

    if (argc != 4) {
        std::cerr << "Usage: " << argv[0] << " <vertex shader path> <fragment shader path> <image path>" << std::endl;
        return EXIT_FAILURE;
    }

  // Get an EGL valid display
  EGLDisplay display;
  display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
  if (display == EGL_NO_DISPLAY) {
    std::cerr << "Failed to get EGL Display" << std::endl
              << "Error: " << eglGetError() << std::endl;
    return EXIT_FAILURE;
  }
  else {
    std::cerr << "Successfully get EGL Display." << std::endl;
  }


  // Create a connection to the display
  int minor, major;
  if (eglInitialize(display, &minor, &major) == EGL_FALSE) {
    std::cerr << "Failed to initialize EGL Display" << std::endl
              << "Error: " << eglGetError() << std::endl;
    eglTerminate(display);
    return EXIT_FAILURE;
  }
  else {
    std::cerr << "Successfully intialized display (OpenGL ES version " << minor << "." << major << ")." << std::endl;
  }

  // OpenGL ES Config are used to specify things like multi sampling, channel size, stencil buffer usage, & more
  // See the doc: https://www.khronos.org/registry/EGL/sdk/docs/man/html/eglChooseConfig.xhtml for more informations
  EGLConfig config;
  EGLint num_configs; 
  if (!eglChooseConfig(display, configAttribs, &config, 1, &num_configs)) {
    std::cerr << "Failed to choose EGL Config" << std::endl
              << "Error: " << eglGetError() << std::endl;
    eglTerminate(display);
    return EXIT_FAILURE;
  }
  else {
    std::cerr << "Successfully choose OpenGL ES Config ("<< num_configs << ")." << std::endl;
  }

  // Creating an OpenGL Render Surface with surface attributes defined above.
  EGLSurface surface = eglCreatePbufferSurface(display, config, pbufferAttribs);
  if (surface == EGL_NO_SURFACE) {
    std::cerr << "Failed to create EGL Surface." << std::endl
              << "Error: " << eglGetError() << std::endl;
  }
  else {
    std::cerr << "Successfully created OpenGL ES Surface." << std::endl;
  }

  eglBindAPI(EGL_OPENGL_API);
  EGLContext context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
  if (context == EGL_NO_CONTEXT) {
    std::cerr << "Failed to create EGL Context." << std::endl
              << "Error: " << eglGetError() << std::endl;
  }
  else {
    std::cerr << "Successfully created OpenGL ES Context." << std::endl;
  }

  //Bind context to surface
  eglMakeCurrent(display, surface, surface, context);

  // Create viewport and check if it has been created correctly
  glViewport(0, 0, WIDTH, HEIGHT);
  GLint viewport[4];
  glGetIntegerv(GL_VIEWPORT, viewport);

  if (viewport[2] != WIDTH || viewport[3] != HEIGHT) {
    std::cerr << "Failed to create the viewport. Size does not match (glViewport/glGetIntegerv not working)." << std::endl
              << "OpenGL ES might be faulty!" << std::endl
              << "If you are on Raspberry Pi, you should not updated EGL as it will install fake EGL." << std::endl;
    eglTerminate(display);
    return EXIT_FAILURE;
  }

  // Clear buffer and get ready to draw some things
  glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  // Create a shader program
  GLuint program = load_shaders(std::string(argv[1]), std::string(argv[2]));
  if (program == -1)
  {
      std::cerr << "Failed to create a shader program. See above for more details." << std::endl;
      eglTerminate(display);
      return EXIT_FAILURE;
  }

  /* Initialization of DevIL */
  if (ilGetInteger(IL_VERSION_NUM) < IL_VERSION) {
    std::cerr << "Failed to use DevIL: Wrong version." << std::endl;
    return EXIT_FAILURE;
  }

  ilInit(); 
  ILuint image = load_image(argv[3]);
  GLuint texId;
  glGenTextures(1, &texId); /* Texture name generation */
  glBindTexture(GL_TEXTURE_2D, texId); /* Binding of texture name */
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); /* We will use linear interpolation for magnification filter */
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); /* We will use linear interpolation for minifying filter */
  glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), 
               0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData()); /* Texture specification */
int main(int argc,char**argv)
{
如果(argc!=4){
标准:cerr
我是否需要一个顶点着色器,因为我只想做纯2D图像处理

在OpenGL ES 2中,必须使用顶点和片段着色器

如果我这样做了,在这个顶点着色器中应该做什么,因为我根本没有顶点。我应该创建四个顶点(比如(0,0)(1,0)(0,1)(1,1))?如果是,为什么

是的。因为这就是OpenGLES2的工作原理。否则您需要使用计算机着色器(OpenGLES3.1+支持)或OpenCL之类的工具

我是否需要使用VBO(似乎与顶点着色器相关)、FBO或其他类似的东西

使用VBO/IBO对您几乎没有任何影响,因为您只有4个顶点和2个基本体。您可能需要渲染到纹理,具体取决于您的需要

我不能将图像加载到纹理中,然后等待片段着色器对该纹理执行我想要的所有操作吗

没有

我是否需要一个顶点着色器,因为我只想做纯2D图像处理

在OpenGL ES 2中,必须使用顶点和片段着色器

如果我这样做了,在这个顶点着色器中应该做什么,因为我根本没有顶点。我应该创建四个顶点(比如(0,0)(1,0)(0,1)(1,1))?如果是,为什么

是的。因为这就是OpenGLES2的工作原理。否则您需要使用计算机着色器(OpenGLES3.1+支持)或OpenCL之类的工具

我是否需要使用VBO(似乎与顶点着色器相关)、FBO或其他类似的东西

使用VBO/IBO对您几乎没有任何影响,因为您只有4个顶点和2个基本体。您可能需要渲染到纹理,具体取决于您的需要

我不能将图像加载到纹理中,然后等待片段着色器对该纹理执行我想要的所有操作吗

没有