Ver Fonte

moved some stuff around to avoid code duplication and finish up gl 2D texture code

jp9000 há 12 anos atrás
pai
commit
5c92f22f0d

+ 0 - 24
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) {

+ 5 - 3
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<D3D11_SUBRESOURCE_DATA> &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; 

+ 3 - 3
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

+ 1 - 5
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 {

+ 56 - 3
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);
 }

+ 29 - 0
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;