使用OpenGL在Java中更改纹理中的某些颜色

时间:2015-04-07 20:39:46

标签: java opengl colors textures pixels

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

2 个答案:

答案 0 :(得分: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是第n个mipmap缩小图像。
  • xoffset 指定x方向内的纹素偏移量 纹理数组。
  • yoffset 指定内容中y方向的纹素偏移量 纹理数组。
  • width 指定纹理子图像的宽度。

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

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

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

参考: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 :(得分: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()