From 5c92f22f0df4f9f7ab13afc234bbf1006a4783b2 Mon Sep 17 00:00:00 2001 From: jp9000 Date: Sat, 5 Oct 2013 00:34:43 -0700 Subject: [PATCH] moved some stuff around to avoid code duplication and finish up gl 2D texture code --- libobs-d3d11/GS_D3D11SubSystem.hpp | 24 ------------ libobs-d3d11/GS_D3D11Texture2D.cpp | 8 ++-- libobs-opengl/gl-helpers.h | 6 +-- libobs-opengl/gl-subsystem.h | 6 +-- libobs-opengl/gl-texture2d.c | 59 ++++++++++++++++++++++++++++-- libobs/graphics/graphics.h | 29 +++++++++++++++ 6 files changed, 94 insertions(+), 38 deletions(-) diff --git a/libobs-d3d11/GS_D3D11SubSystem.hpp b/libobs-d3d11/GS_D3D11SubSystem.hpp index 5410dcdeb..118f55daa 100644 --- a/libobs-d3d11/GS_D3D11SubSystem.hpp +++ b/libobs-d3d11/GS_D3D11SubSystem.hpp @@ -58,30 +58,6 @@ static inline uint32_t GetWinVer() return (ovi.dwMajorVersion << 8) | (ovi.dwMinorVersion); } -static inline uint32_t GetFormatBPP(gs_color_format format) -{ - switch (format) { - case GS_A8: return 1; - case GS_R8: return 1; - case GS_RGBA: return 4; - case GS_BGRX: return 4; - case GS_BGRA: return 4; - case GS_R10G10B10A2: return 4; - case GS_RGBA16: return 8; - case GS_R16: return 2; - case GS_RGBA16F: return 8; - case GS_RGBA32F: return 16; - case GS_RG16F: return 4; - case GS_RG32F: return 8; - case GS_R16F: return 2; - case GS_R32F: return 4; - case GS_DXT1: return 0; - case GS_DXT3: return 0; - case GS_DXT5: return 0; - default: return 0; - } -} - static inline DXGI_FORMAT ConvertGSTextureFormat(gs_color_format format) { switch (format) { diff --git a/libobs-d3d11/GS_D3D11Texture2D.cpp b/libobs-d3d11/GS_D3D11Texture2D.cpp index 7bd4fb752..e3923cbdf 100644 --- a/libobs-d3d11/GS_D3D11Texture2D.cpp +++ b/libobs-d3d11/GS_D3D11Texture2D.cpp @@ -37,16 +37,18 @@ static inline uint32_t numActualLevels(uint32_t levels, uint32_t width, void gs_texture_2d::InitSRD(vector &srd, void **data) { - uint32_t rowSizeBytes = width * GetFormatBPP(format); - uint32_t texSizeBytes = height * rowSizeBytes; + uint32_t rowSizeBytes = width * get_format_bpp(format); + uint32_t texSizeBytes = height * rowSizeBytes / 8; size_t textures = type == GS_TEXTURE_2D ? 1 : 6; uint32_t actual_levels = numActualLevels(levels, width, height); + rowSizeBytes /= 8; + for (size_t i = 0; i < textures; i++) { uint32_t newRowSize = rowSizeBytes; uint32_t newTexSize = texSizeBytes; - for (size_t j = 0; j < actual_levels; j++) { + for (uint32_t j = 0; j < actual_levels; j++) { D3D11_SUBRESOURCE_DATA newSRD; newSRD.pSysMem = *data; newSRD.SysMemPitch = newRowSize; diff --git a/libobs-opengl/gl-helpers.h b/libobs-opengl/gl-helpers.h index ea5f98237..23a0fdcce 100644 --- a/libobs-opengl/gl-helpers.h +++ b/libobs-opengl/gl-helpers.h @@ -24,7 +24,7 @@ * make a bunch of helper functions to make it a bit easier to handle errors */ -static inline bool gl_error_occurred(const char *funcname) +static inline bool gl_success(const char *funcname) { GLenum errorcode = glGetError(); if (errorcode != GL_NO_ERROR) { @@ -39,13 +39,13 @@ static inline bool gl_error_occurred(const char *funcname) static inline bool gl_gen_textures(GLsizei num_texture, GLuint *textures) { glGenTextures(num_texture, textures); - return gl_error_occurred("glGenTextures"); + return gl_success("glGenTextures"); } static inline bool gl_bind_texture(GLenum target, GLuint texture) { glBindTexture(target, texture); - return gl_error_occurred("glBindTexture"); + return gl_success("glBindTexture"); } #endif diff --git a/libobs-opengl/gl-subsystem.h b/libobs-opengl/gl-subsystem.h index 687812347..fb1cddd27 100644 --- a/libobs-opengl/gl-subsystem.h +++ b/libobs-opengl/gl-subsystem.h @@ -73,11 +73,6 @@ static inline GLint convert_gs_internal_format(enum gs_color_format format) } } -static inline bool is_compressed_format(enum gs_color_format format) -{ - return (format == GS_DXT1 || format == GS_DXT3 || format == GS_DXT5); -} - static inline GLint convert_zstencil_format(enum gs_zstencil_format format) { switch (format) { @@ -96,6 +91,7 @@ struct gs_texture { GLenum gl_format; GLint gl_internal_format; GLuint texture; + uint32_t levels; }; struct gs_texture_2d { diff --git a/libobs-opengl/gl-texture2d.c b/libobs-opengl/gl-texture2d.c index ba9de4c79..adc8b43ab 100644 --- a/libobs-opengl/gl-texture2d.c +++ b/libobs-opengl/gl-texture2d.c @@ -17,17 +17,65 @@ #include "gl-subsystem.h" +static inline uint32_t num_actual_levels(struct gs_texture_2d *tex) +{ + uint32_t num_levels; + uint32_t size; + + if (tex->base.levels > 0) + return tex->base.levels; + + size = tex->width > tex->height ? tex->width : tex->height; + num_levels = 0; + + while (size > 1) { + size /= 2; + num_levels++; + } + + return num_levels; +} + static inline bool upload_texture_data(struct gs_texture_2d *tex, void **data) { + uint32_t row_size = tex->width * get_format_bpp(tex->base.format); + uint32_t tex_size = tex->height * row_size / 8; + uint32_t num_levels = num_actual_levels(tex); + bool success = true; + bool compressed = is_compressed_format(tex->base.format); + uint32_t i; + if (!gl_bind_texture(GL_TEXTURE_2D, tex->base.texture)) return false; - //if (is_compressed_format(tex->base.format)) + for (i = 0; i < num_levels; i++) { + uint32_t size = tex_size; + + if (compressed) { + glCompressedTexImage2D(GL_TEXTURE_2D, i, + tex->base.gl_internal_format, + tex->width, tex->height, 0, + size, *data); + if (!gl_success("glCompressedTexImage2D")) + success = false; + + } else { + glTexImage2D(GL_TEXTURE_2D, i, + tex->base.gl_internal_format, + tex->width, tex->height, 0, + tex->base.gl_format, GL_UNSIGNED_BYTE, + *data); + if (!gl_success("glTexImage2D")) + success = false; + } + + data++; + } if (!gl_bind_texture(GL_TEXTURE_2D, 0)) - return false; + success = false; - return true; + return success; } texture_t device_create_texture(device_t device, uint32_t width, @@ -60,4 +108,9 @@ fail: void texture_destroy(texture_t tex) { + if (!tex) + return; + + glDeleteTextures(1, &tex->texture); + bfree(tex); } diff --git a/libobs/graphics/graphics.h b/libobs/graphics/graphics.h index 8ea4acb68..b855d9300 100644 --- a/libobs/graphics/graphics.h +++ b/libobs/graphics/graphics.h @@ -226,6 +226,35 @@ struct gs_rect { int cy; }; +static inline uint32_t get_format_bpp(enum gs_color_format format) +{ + switch (format) { + case GS_A8: return 8; + case GS_R8: return 8; + case GS_RGBA: return 32; + case GS_BGRX: return 32; + case GS_BGRA: return 32; + case GS_R10G10B10A2: return 32; + case GS_RGBA16: return 64; + case GS_R16: return 16; + case GS_RGBA16F: return 64; + case GS_RGBA32F: return 128; + case GS_RG16F: return 32; + case GS_RG32F: return 64; + case GS_R16F: return 16; + case GS_R32F: return 32; + case GS_DXT1: return 4; + case GS_DXT3: return 8; + case GS_DXT5: return 8; + default: return 0; + } +} + +static inline bool is_compressed_format(enum gs_color_format format) +{ + return (format == GS_DXT1 || format == GS_DXT3 || format == GS_DXT5); +} + /* wrapped opaque data types */ struct gs_texture;