生成纹理的问题

Posted

技术标签:

【中文标题】生成纹理的问题【英文标题】:problems generating texture 【发布时间】:2013-10-28 09:13:43 【问题描述】:

更新 2 有效,这是一个错误的警报

更新 2(使用 vbo 顶点和片段着色器)但它仍然不起作用

#include "GL/glxew.h"
#include "GL/glext.h"
#include "GL/glu.h"
#include "GL/freeglut.h"

#include <iostream>

GLint attribute;
GLuint program;

void gen_texture(GLuint &texture, int width, int height)

   GLuint fb;

   glGenFramebuffers(1, &fb);
   glGenTextures(1, &texture);

   glBindFramebuffer(GL_FRAMEBUFFER, fb);

   glBindTexture(GL_TEXTURE_2D, texture);
   glTexImage2D(GL_TEXTURE_2D, 
                0,
                GL_RGBA,
                width, height,
                0,
                GL_RGBA,
                GL_UNSIGNED_BYTE,
                0);

   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);

   glBindTexture(GL_TEXTURE_2D, 0);
   glEnable(GL_TEXTURE_2D);
   glBindFramebuffer(GL_FRAMEBUFFER, fb);

   glClearColor(1,1,1,0);
   glClear(GL_COLOR_BUFFER_BIT);

   glUseProgram(program);
   glEnableVertexAttribArray(attribute);
   GLfloat vertex_data[]
   
      1.0f, 0.0f,
      0.0f, 0.0f,
      0.0f, 1.0f,

      1.0f, 0.0f,
      0.0f, 1.0f,
      1.0f, 1.0f
   ;

   glVertexAttribPointer(
      attribute,
      2,
      GL_FLOAT,
      GL_FALSE,
      0,
      vertex_data
   );

   glDrawArrays(GL_TRIANGLES, 0, 6);
   glDisableVertexAttribArray(attribute);


void init_layout()

   GLint compile_ok = GL_FALSE, link_ok = GL_FALSE;

   GLuint vs, fs;

   vs = glCreateShader(GL_VERTEX_SHADER);
   const char *vs_source =
   "#version 120\n"  // OpenGL 2.1
   "attribute vec2 coord2d;                  "
   "void main(void)                         "
   "  gl_Position = vec4(coord2d, 0.0, 1.0); "
   "";
   glShaderSource(vs, 1, &vs_source, 0);
   glCompileShader(vs);
   glGetShaderiv(vs, GL_COMPILE_STATUS, &compile_ok);
   if (0 == compile_ok)
   
      std::cerr << "[texture_layout/init_layout] fehler im vertex shader\n";
      exit(1);
   

   fs = glCreateShader(GL_FRAGMENT_SHADER);
   const char *fs_source =
   "#version 120\n"   // OpenGL 2.1
   "void main(void)         "
   "  gl_FragColor[0] = 0.8f; "
   "  gl_FragColor[1] = 0.5f;"
   "  gl_FragColor[2] = 0.0f; "
   "";
   glShaderSource(fs, 1, &fs_source, 0);
   glCompileShader(fs);
   glGetShaderiv(fs, GL_COMPILE_STATUS, &compile_ok);
   if (0 == compile_ok)
   
      std::cerr << "[texture_layout/init_layout] fehler im fragment shader\n";
      exit(1);
   

   program = glCreateProgram();
   glAttachShader(program, vs);
   glAttachShader(program, fs);
   glLinkProgram(program);
   glGetProgramiv(program, GL_LINK_STATUS, &link_ok);
   if (!link_ok)
   
      std::cerr << "[texture_layout/init_layout] fehler in glLinkProgram\n";
      exit(1);
   

   const char* attribute_name = "coord2d";
   attribute = glGetAttribLocation(program, attribute_name);
   if (attribute == -1) 
      std::cerr << "Could not bind attribute " << attribute_name << "\n";
      exit(1);
   



int main(int argc, char **argv)

   glutInit (&argc, argv);
   glutInitContextProfile(GLUT_CORE_PROFILE); 

   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA);
   glutInitWindowSize (500, 500);
   glutCreateWindow ("");

   glewExperimental=GL_TRUE;
   GLenum err=glewInit();
   if(err!=0)
   
      std::cerr << glewGetErrorString(err) << std::endl;
      exit(1);
   

   GLenum error;

   GLuint texture;

   while ( ( error = glGetError() ) != GL_NO_ERROR)
   
      std::cerr << std::hex << error << "\n";
   
   init_layout();
   gen_texture(texture, 200, 200);

   GLvoid *tex_data = new GLubyte[4*200*200];

   glBindTexture(GL_TEXTURE_2D, texture);
   glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_data);


   return 0;

更新 1(使用 vbo 代替 glBegin)

现在我的代码应该使用 vbo 绘制一个红色三角形,但它没有

void gen_texture(GLuint &color, int width, int height)

   GLuint fb;

   glGenFramebuffers(1, &fb);
   glGenTextures(1, &color);

   glBindFramebuffer(GL_FRAMEBUFFER, fb);

   glBindTexture(GL_TEXTURE_2D, color);
   glTexImage2D(GL_TEXTURE_2D,
      0,
      GL_RGBA,
      width, height,
      0,
      GL_RGBA,
      GL_UNSIGNED_BYTE,
      0);

   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);

   glBindTexture(GL_TEXTURE_2D, 0);
   glEnable(GL_TEXTURE_2D);
   glBindFramebuffer(GL_FRAMEBUFFER, fb);

   glMatrixMode(GL_PROJECTION);
   glLoadIdentity;
   glViewport(0,0,width,height);
   glOrtho(0,width,0,height,0,128);

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();


   glClearColor(0, 0, 0, 0);
   glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

   glDisable(GL_DEPTH_TEST);
   //glDisable(GL_CULL_FACE);

   glColor3f(1.f, .0f, .0f);   
   GLfloat vertices[6] =
   
      0, 0,
      0, (GLfloat)height,
      (GLfloat)width, (GLfloat)height,
   ;

   unsigned short indices[] = 0, 1, 2;

   GLuint vbo;

   glGenBuffersARB(1, &vbo);
   glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
   glBufferDataARB(GL_ARRAY_BUFFER_ARB, 6*sizeof(GLfloat), vertices, GL_STATIC_DRAW_ARB);

   glEnableClientState(GL_VERTEX_ARRAY);
   glVertexPointer(3, GL_FLOAT, 0, 0);
   glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, vertices);

原件2:

我有一个函数应该使用 glBegin 指令将红色方块绘制到纹理中。但我唯一要做的就是

glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

我已经用多种颜色对其进行了测试。但是那部分不起作用:

glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glViewport(0,0,width,height);
glOrtho(0,width,0,height,0,128);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glDisable(GL_DEPTH_TEST);

glColor3f(1.f, .0f, .0f);   
glBegin(GL_QUADS);
  glVertex2f(0, 0);
  glVertex2f(0, height);
  glVertex2f(width, height);
  glVertex2f(width, 0);
glEnd();

这是完整的功能:

void gen_texture(GLuint &color, int width, int height)

   GLuint fb;

   glGenFramebuffers(1, &fb);
   glGenTextures(1, &color);

   glBindFramebuffer(GL_FRAMEBUFFER, fb);

   glBindTexture(GL_TEXTURE_2D, color);
   glTexImage2D(GL_TEXTURE_2D,
      0,
      GL_RGBA,
      width, height,
      0,
      GL_RGBA,
      GL_UNSIGNED_BYTE,
      0);

   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);

   glBindTexture(GL_TEXTURE_2D, 0);
   glEnable(GL_TEXTURE_2D);
   glBindFramebuffer(GL_FRAMEBUFFER, fb);

   glMatrixMode(GL_PROJECTION);
   glLoadIdentity;
   glViewport(0,0,width,height);
   glOrtho(0,width,0,height,0,128);

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();


   glClearColor(0, 0, 0, 0);
   glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

   glDisable(GL_DEPTH_TEST);
   //glDisable(GL_CULL_FACE);

   glColor3f(1.f, .0f, .0f);   
   glBegin(GL_QUADS);
      glVertex2f(0, 0);
      glVertex2f(0, height);
      glVertex2f(width, height);
      glVertex2f(width, 0);
   glEnd();

原帖:

我有一个应该在纹理中绘制红色方块的函数,但是当我调用生成纹理的函数然后我想使用 glGetTexImage 函数检查生成的纹理数据时,我得到一个空指针。

#include "GL/glxew.h"
#include "GL/glext.h"
#include "GL/glu.h"
#include "GL/freeglut.h"

#include <iostream>

GLuint texture;
GLvoid *tex_data;


void gen_texture(GLuint &color, int width, int height)

   GLuint fb;

   glGenFramebuffers(1, &fb);
   glGenTextures(1, &color);

   glBindFramebuffer(GL_FRAMEBUFFER, fb);

   glTexImage2D(GL_TEXTURE_2D,
      0,
      GL_RGBA,
      width, height,
      0,
      GL_RGBA,
      GL_UNSIGNED_BYTE,
      0);

   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);

   glBindTexture(GL_TEXTURE_2D, 0);
   glEnable(GL_TEXTURE_2D);
   glBindFramebuffer(GL_FRAMEBUFFER, fb);

   glViewport(0, 0, width, height);

   glClearColor(1,1,1,0);
   glClear(GL_COLOR_BUFFER_BIT);

   glMatrixMode (GL_PROJECTION);

   glLoadIdentity ();

   glOrtho (0, width, height, 0, 0, 1);

   glMatrixMode (GL_MODELVIEW);

   glDisable(GL_DEPTH_TEST);
   glDisable(GL_CULL_FACE);

   glColor4f(1.f, .0f, .0f, .5f);   
   glBegin(GL_QUADS);
      glVertex2f(0, 0);
      glVertex2f(0, height);
      glVertex2f(width, height);
      glVertex2f(width, 0);
   glEnd();


int main(int argc, char **argv)

   glutInit (&argc, argv);
   glutInitContextVersion(3, 2);
   glutInitContextProfile(GLUT_CORE_PROFILE); 

   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA);
   glutInitWindowSize (500, 500);
   glutCreateWindow ("");

   glewExperimental=GL_TRUE;
   GLenum err=glewInit();
   if(err!=0)
   
      std::cerr << glewGetErrorString(err) << std::endl;
      exit(1);
   

   GLenum error;

   while ( ( error = glGetError() ) != GL_NO_ERROR)
   
      std::cerr << std::hex << error << "\n";
   

   gen_texture(texture, 200, 200);

   glBindTexture(GL_TEXTURE_2D, texture);

   glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_data);

   if (tex_data == 0)
      std::cerr << "Captain, eine Null an Board!\n";

   return 0;

tex_data 现在是一个空指针

我做错了什么???

【问题讨论】:

您是否实际填充了 tex_data,因为您将纹理变量传递给 gen_textures()。这是笔误吗? @Full Frontal Nudity 我填充了 tex_data 以便可以在调试器中检查纹理,并有一个指针来寻址纹理数据。在 gen_texture() 中应该生成纹理。 哦,我忘记在调用 glTexImage2d 之前调用 glBindTexture 了,我发现我必须自己为纹理数据分配内存。但是现在我的问题是glBegin和glEnd之间的绘图指令似乎对纹理没有影响 【参考方案1】:
glutInitContextVersion(3, 2);
glutInitContextProfile(GLUT_CORE_PROFILE);
                       ^^^^^^^^^^^^^^^^^ ok...
....
glBegin(GL_QUADS);
        ^^^^^^^^ wat

glBegin() 和朋友在 Core 上下文中不是有效的调用。

如果你坚持使用 Core,你将不得不开始使用着色器和 VBO。

【讨论】:

我更改了代码,但它不起作用,我认为我使用 vbo 的方式错误。 (见编辑过的问题帖) 我没有看到你设置任何着色器。 Core 中没有任何“默认”着色器。而且你仍然有固定功能的颜色和矩阵调用。

以上是关于生成纹理的问题的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL生成的纹理总是黑色的?

是否可以告诉 Xcode 不要在生成的纹理图集中旋转纹理?

为 2D 纹理数组生成 mip 级别

Unity shader - 如何根据纹理贴图生成法线贴图

生成 GL_INVALID_VALUE 错误。无效的纹理尺寸。立方体贴图纹理 427*240*6 [关闭]

带纹理3D网格的深度生成模型Gen-AI