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)
This commit is contained in:
Martin Pulec
2011-10-31 13:09:48 +01:00
parent 91140aa06e
commit f20132ecd9
4 changed files with 86 additions and 46 deletions

View File

@@ -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
};
/**

View File

@@ -30,6 +30,10 @@
#include <string.h>
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

View File

@@ -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);
}

View File

@@ -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,