2015-04-07 76 views
0

我需要能够创建纹理的副本并将该副本中的某些颜色更改为java中的其他颜色。我不是很熟悉OpenGL库,我不知道它提供什么方法​​来做到这一点。我需要知道改变纹理中单个像素的颜色以及如何获取纹理中单个像素的颜色以及如何复制纹理的好方法。如果这个问题太广泛,我很抱歉,但我正在寻找一个广泛的答案。使用OpenGL在Java中更改纹理中的某些颜色

回答

1

您可以使用glTexSubImage2D函数更改纹理中单个像素的颜色。下面是函数头:

void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, 
GLint yoffset, GLsizei width, GLsizei height, GLenum format, 
GLenum type, const GLvoid *data); 

这里:

  • 目标指定目标质感。
  • 级别指定详细程度编号。级别0是基本图像 级别。级别n是第m个缩减映像。
  • xoffset在 纹理数组中指定x方向上的纹理元素偏移量。
  • yoffset在 纹理数组中指定y方向上的纹理元素偏移量。
  • width指定纹理子图像的宽度。

  • 高度指定纹理子图像的高度

  • 格式指定的像素数据的格式。

  • 类型指定像素数据的数据类型。

参考:https://www.opengl.org/sdk/docs/man2/xhtml/glTexSubImage2D.xml

下面是如何使用它的代码片断我在底部参考的网站上找到:

void updateTexture(const chip8& c8) 
{ 
    // Update pixels 
    for(int y = 0; y < 32; ++y)  
     for(int x = 0; x < 64; ++x) 
      if(c8.gfx[(y * 64) + x] == 0) 
       screenData[y][x][0] = screenData[y][x][1] = screenData[y][x][2] = 0; // Disabled 
     else 
      screenData[y][x][0] = screenData[y][x][1] = screenData[y][x][2] = 255; // Enabled 

    // Update Texture 
    glTexSubImage2D(GL_TEXTURE_2D, 0 ,0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)screenData); 

    glBegin(GL_QUADS); 
     glTexCoord2d(0.0, 0.0);  glVertex2d(0.0,   0.0); 
     glTexCoord2d(1.0, 0.0);  glVertex2d(display_width, 0.0); 
     glTexCoord2d(1.0, 1.0);  glVertex2d(display_width, display_height); 
     glTexCoord2d(0.0, 1.0);  glVertex2d(0.0,   display_height); 
    glEnd(); 
} 

参考:http://www.multigesture.net/articles/how-to-draw-pixels-to-a-texture-opengl/

希望有帮助!

1

复制纹理的最简单方法是使用glCopyTexImage2D()。这使您可以将当前帧缓冲区的内容复制到纹理。如果您想使用其他纹理作为源,则可以将该纹理设置为帧缓冲区对象(FBO)的内容。

比方说,您已经有一个名称为srcTexId的纹理,您想将其用作复制操作的源。现在,你需要首先创建为您的目的地的新的纹理,我们将其称为dstTexId

GLuint dstTexId = 0; 
glGenTextures(1, &dstTexId); 
glBindTexture(GL_TEXTURE_2D, dstTexId); 
glTexParameteri(...); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, 
      GL_RGBA, GL_UNSIGNED_BYTE, NULL); 

注意的最后一个参数使用NULL。这意味着纹理内容是以给定的格式/大小分配的,但是纹理没有填充数据。

现在我们需要一个FBO,并与源纹理作为内容设置它:

GLuint fbo = 0; 
glGenFramebuffers(1, &fbo); 
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); 
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
         GL_TEXTURE_2D srcTexId, 0); 

一切准备就绪执行现在的副本:

glBindTexture(GL_TEXTURE_2D, dstTexId); 
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, width, height, 0); 

然后你就可以清理你的绑定,如果你想保持国家不受干扰:

glBindTexture(GL_TEXTURE_2D, 0); 
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); 

复制纹理的另一种选择是glBlitFramebuffer()。要使用它,你会创建两个FBO,一个用于阅读,一个用于写作。所以它需要更多的设置,但它也更加灵活。例如,它允许您将内容的大小(比例)作为副本的一部分进行调整(glCopyTexImage2D()不支持)。

要在创建副本后修改纹理的某些部分,请使用glTexSubImage2D()

+0

我忘了指定:我正在使用java。 – Entity1037