From f20132ecd9eb82ce5353e945e8eef3536c8baae1 Mon Sep 17 00:00:00 2001 From: Martin Pulec Date: Mon, 31 Oct 2011 13:09:48 +0100 Subject: [PATCH] Added support for RGB (not RGBA) to DXT, OpenGL * added possibility to encompress RGB * OpenGL display now displays RGB nativelly (TODO: add it also for SDL) --- dxt_compress/dxt_common.h | 7 +-- dxt_compress/dxt_encoder.c | 89 ++++++++++++++++++------------- ultragrid/src/dxt_glsl_compress.c | 20 +++++-- ultragrid/src/video_display/gl.c | 16 +++++- 4 files changed, 86 insertions(+), 46 deletions(-) diff --git a/dxt_compress/dxt_common.h b/dxt_compress/dxt_common.h index c79e014fe..7d06d204b 100644 --- a/dxt_compress/dxt_common.h +++ b/dxt_compress/dxt_common.h @@ -71,9 +71,10 @@ * DXT format */ enum dxt_format { - DXT_FORMAT_RGB = 0, - DXT_FORMAT_YUV = 1, - DXT_FORMAT_YUV422 = 2 + DXT_FORMAT_RGB, + DXT_FORMAT_RGBA, + DXT_FORMAT_YUV, + DXT_FORMAT_YUV422 }; /** diff --git a/dxt_compress/dxt_encoder.c b/dxt_compress/dxt_encoder.c index 45e806c47..aacbb4352 100644 --- a/dxt_compress/dxt_encoder.c +++ b/dxt_compress/dxt_encoder.c @@ -30,6 +30,10 @@ #include + +const int FORMAT_RGB = 0; +const int FORMAT_YUV = 1; + /** Documented at declaration */ struct dxt_encoder { @@ -188,7 +192,11 @@ dxt_encoder_create(enum dxt_type type, int width, int height, enum dxt_format fo glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, DXT_IMAGE_GL_FORMAT, encoder->width, encoder->height, 0, GL_RGBA, GL_BYTE, NULL); + if(format == DXT_FORMAT_RGB) { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, encoder->width, encoder->height, 0, GL_RGB, GL_BYTE, NULL); + } else { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, encoder->width, encoder->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + } //glActiveTexture(GL_TEXTURE0); glEnable(GL_TEXTURE_2D); @@ -207,10 +215,11 @@ dxt_encoder_create(enum dxt_type type, int width, int height, enum dxt_format fo // User compress program and set image size parameters glUseProgramObjectARB(encoder->program_compress); glUniform1i(glGetUniformLocation(encoder->program_compress, "image"), 0); - if(format == DXT_FORMAT_YUV422) { - glUniform1i(glGetUniformLocation(encoder->program_compress, "imageFormat"), DXT_FORMAT_YUV); + + if(format == DXT_FORMAT_YUV422 || format == DXT_FORMAT_YUV) { + glUniform1i(glGetUniformLocation(encoder->program_compress, "imageFormat"), FORMAT_YUV); } else { - glUniform1i(glGetUniformLocation(encoder->program_compress, "imageFormat"), encoder->format); + glUniform1i(glGetUniformLocation(encoder->program_compress, "imageFormat"), FORMAT_RGB); } glUniform2f(glGetUniformLocation(encoder->program_compress, "imageSize"), encoder->width, encoder->height); @@ -249,39 +258,47 @@ dxt_encoder_compress(struct dxt_encoder* encoder, DXT_IMAGE_TYPE* image, unsigne TIMER_INIT(); TIMER_START(); - if(encoder->format == DXT_FORMAT_YUV422) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, encoder->fbo444_id); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, encoder->texture_id, 0); - //assert(GL_FRAMEBUFFER_COMPLETE_EXT == glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)); - glBindTexture(GL_TEXTURE_2D, encoder->texture_yuv422); - - glPushAttrib(GL_VIEWPORT_BIT); - glViewport( 0, 0, encoder->width, encoder->height); - - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, encoder->width / 2, encoder->height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, image); - glUseProgramObjectARB(encoder->yuv422_to_444_program); - - //glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - - glBegin(GL_QUADS); - glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, -1.0); - glTexCoord2f(1.0, 0.0); glVertex2f(1.0, -1.0); - glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 1.0); - glTexCoord2f(0.0, 1.0); glVertex2f(-1.0, 1.0); - glEnd(); - - glPopAttrib(); - - //glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - - glUseProgramObjectARB(encoder->program_compress); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, encoder->fbo_id); - glBindTexture(GL_TEXTURE_2D, encoder->texture_id); - - //gl_check_error(); - } else { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, encoder->width, encoder->height, GL_RGBA, DXT_IMAGE_GL_TYPE, image); + switch(encoder->format) { + case DXT_FORMAT_YUV422: + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, encoder->fbo444_id); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, encoder->texture_id, 0); + //assert(GL_FRAMEBUFFER_COMPLETE_EXT == glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)); + glBindTexture(GL_TEXTURE_2D, encoder->texture_yuv422); + + glPushAttrib(GL_VIEWPORT_BIT); + glViewport( 0, 0, encoder->width, encoder->height); + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, encoder->width / 2, encoder->height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, image); + glUseProgramObjectARB(encoder->yuv422_to_444_program); + + //glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); + + glBegin(GL_QUADS); + glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, -1.0); + glTexCoord2f(1.0, 0.0); glVertex2f(1.0, -1.0); + glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 1.0); + glTexCoord2f(0.0, 1.0); glVertex2f(-1.0, 1.0); + glEnd(); + + glPopAttrib(); + + //glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + + glUseProgramObjectARB(encoder->program_compress); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, encoder->fbo_id); + glBindTexture(GL_TEXTURE_2D, encoder->texture_id); + + //gl_check_error(); + break; + case DXT_FORMAT_YUV: + case DXT_FORMAT_RGBA: + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, encoder->width, encoder->height, GL_RGBA, DXT_IMAGE_GL_TYPE, image); + break; + case DXT_FORMAT_RGB: + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, encoder->width, encoder->height, GL_RGB, GL_UNSIGNED_BYTE, image); + break; } + #ifdef DEBUG glFinish(); #endif diff --git a/ultragrid/src/dxt_glsl_compress.c b/ultragrid/src/dxt_glsl_compress.c index 4f298355d..29b477c68 100644 --- a/ultragrid/src/dxt_glsl_compress.c +++ b/ultragrid/src/dxt_glsl_compress.c @@ -368,16 +368,16 @@ static void configure_with(struct video_compress *s, struct video_frame *frame) switch (frame->color_spec) { case RGB: - s->decoder = (decoder_t) vc_copylineRGBtoRGBA; + s->decoder = (decoder_t) memcpy; format = DXT_FORMAT_RGB; break; case RGBA: s->decoder = (decoder_t) memcpy; - format = DXT_FORMAT_RGB; + format = DXT_FORMAT_RGBA; break; case R10k: s->decoder = (decoder_t) vc_copyliner10k; - format = DXT_FORMAT_RGB; + format = DXT_FORMAT_RGBA; break; case UYVY: case Vuy2: @@ -423,8 +423,18 @@ static void configure_with(struct video_compress *s, struct video_frame *frame) for (x = 0; x < frame->grid_width; ++x) { for (y = 0; y < frame->grid_height; ++y) { - tile_get(s->out, x, y)->linesize = s->out->tiles[0].width * - (format == DXT_FORMAT_RGB ? 4 /*RGBA*/: 2/*YUV 422*/); + tile_get(s->out, x, y)->linesize = s->out->tiles[0].width; + switch(format) { + case DXT_FORMAT_RGBA: + tile_get(s->out, x, y)->linesize *= 4; + break; + case DXT_FORMAT_RGB: + tile_get(s->out, x, y)->linesize *= 3; + break; + case DXT_FORMAT_YUV422: + tile_get(s->out, x, y)->linesize *= 2; + break; + } tile_get(s->out, x, y)->data_len = s->out->tiles[0].data_len; tile_get(s->out, x, y)->data = (char *) malloc(s->out->tiles[0].data_len); } diff --git a/ultragrid/src/video_display/gl.c b/ultragrid/src/video_display/gl.c index f432531aa..70d626bb6 100644 --- a/ultragrid/src/video_display/gl.c +++ b/ultragrid/src/video_display/gl.c @@ -290,7 +290,7 @@ void * display_gl_init(char *fmt, unsigned int flags, struct state_decoder *deco s->deinterlace = FALSE; s->video_aspect = 0.0; - codec_t native[] = {UYVY, RGBA, DXT1, DXT5}; + codec_t native[] = {UYVY, RGBA, RGB, DXT1, DXT5}; decoder_register_native_codecs(decoder, native, sizeof(native)); decoder_set_param(decoder, 0, 8, 16, 0); @@ -476,6 +476,7 @@ void gl_reconfigure_screen_post(void *arg, unsigned int width, unsigned int heig struct state_gl *s = (struct state_gl *) arg; assert (codec == RGBA || + codec == RGB || codec == UYVY || codec == DXT1 || codec == DXT5); @@ -560,13 +561,18 @@ void gl_reconfigure_screen(struct state_gl *s) s->tile->width, s->tile->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - } else if (s->frame->color_spec == RGBA) { glBindTexture(GL_TEXTURE_2D,s->texture_display); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, s->tile->width, s->tile->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + } else if (s->frame->color_spec == RGB) { + glBindTexture(GL_TEXTURE_2D,s->texture_display); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, + s->tile->width, s->tile->height, 0, + GL_RGB, GL_UNSIGNED_BYTE, + NULL); } else if (s->frame->color_spec == DXT5) { glUseProgramObjectARB(s->PHandle_dxt5); @@ -629,6 +635,12 @@ void glut_idle_callback(void) GL_RGBA, GL_UNSIGNED_BYTE, s->tile->data); break; + case RGB: + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, + s->tile->width, s->tile->height, + GL_RGB, GL_UNSIGNED_BYTE, + s->tile->data); + break; case DXT5: glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, s->tile->width, s->tile->height,