1
0
Эх сурвалжийг харах

add handling of GL_TEXTURE_RECTANGLE target, and add automatic handling if using it as a sprite

jp9000 12 жил өмнө
parent
commit
0781670ba2

+ 1 - 0
libobs-opengl/gl-exports.h

@@ -129,6 +129,7 @@ EXPORT uint32_t texture_getheight(texture_t tex);
 EXPORT enum gs_color_format texture_getcolorformat(texture_t tex);
 EXPORT bool     texture_map(texture_t tex, void **ptr, uint32_t *row_bytes);
 EXPORT void     texture_unmap(texture_t tex);
+EXPORT bool     texture_isrect(texture_t tex);
 
 EXPORT void     cubetexture_destroy(texture_t cubetex);
 EXPORT uint32_t cubetexture_getsize(texture_t cubetex);

+ 11 - 0
libobs-opengl/gl-texture2d.c

@@ -223,3 +223,14 @@ failed:
 	gl_bind_texture(GL_TEXTURE_2D, 0);
 	blog(LOG_ERROR, "texture_unmap (GL) failed");
 }
+
+bool texture_isrect(texture_t tex)
+{
+	struct gs_texture_2d *tex2d = (struct gs_texture_2d*)tex;
+	if (!is_texture_2d(tex, "texture_unmap")) {
+		blog(LOG_ERROR, "texture_isrect (GL) failed");
+		return false;
+	}
+
+	return tex2d->base.gl_target == GL_TEXTURE_RECTANGLE;
+}

+ 6 - 0
libobs/graphics/graphics-imports.c

@@ -30,6 +30,11 @@
 		} \
 	} while (false)
 
+#define GRAPHICS_IMPORT_OPTIONAL(func) \
+	do { \
+		exports->func = os_dlsym(module, #func); \
+	} while (false)
+
 bool load_graphics_imports(struct gs_exports *exports, void *module,
 		const char *module_name)
 {
@@ -108,6 +113,7 @@ bool load_graphics_imports(struct gs_exports *exports, void *module,
 	GRAPHICS_IMPORT(texture_getcolorformat);
 	GRAPHICS_IMPORT(texture_map);
 	GRAPHICS_IMPORT(texture_unmap);
+	GRAPHICS_IMPORT_OPTIONAL(texture_isrect);
 
 	GRAPHICS_IMPORT(cubetexture_destroy);
 	GRAPHICS_IMPORT(cubetexture_getsize);

+ 1 - 0
libobs/graphics/graphics-internal.h

@@ -140,6 +140,7 @@ struct gs_exports {
 	bool     (*texture_map)(texture_t tex, void **ptr,
 			uint32_t *row_bytes);
 	void     (*texture_unmap)(texture_t tex);
+	bool     (*texture_isrect)(texture_t tex);
 
 	void     (*cubetexture_destroy)(texture_t cubetex);
 	uint32_t (*cubetexture_getsize)(texture_t cubetex);

+ 52 - 7
libobs/graphics/graphics.c

@@ -644,6 +644,18 @@ texture_t gs_create_volumetexture_from_file(const char *file, uint32_t flags)
 	return NULL;
 }
 
+static inline void assign_sprite_rect(float *start, float *end, float size,
+		bool flip)
+{
+	if (!flip) {
+		*start = 0.0f;
+		*end   = size;
+	} else {
+		*start = size;
+		*end   = 0.0f;
+	}
+}
+
 static inline void assign_sprite_uv(float *start, float *end, bool flip)
 {
 	if (!flip) {
@@ -655,15 +667,11 @@ static inline void assign_sprite_uv(float *start, float *end, bool flip)
 	}
 }
 
-static inline void build_sprite(struct vb_data *data, float fcx, float fcy,
+static void build_sprite(struct vb_data *data, float fcx, float fcy,
+		float start_u, float end_u, float start_v, float end_v,
 		uint32_t flip)
 {
 	struct vec2 *tvarray = data->tvarray[0].array;
-	float start_u, end_u;
-	float start_v, end_v;
-
-	assign_sprite_uv(&start_u, &end_u, (flip & GS_FLIP_U) != 0);
-	assign_sprite_uv(&start_v, &end_v, (flip & GS_FLIP_V) != 0);
 
 	vec3_zero(data->points);
 	vec3_set(data->points+1,  fcx, 0.0f, 0.0f);
@@ -675,6 +683,30 @@ static inline void build_sprite(struct vb_data *data, float fcx, float fcy,
 	vec2_set(tvarray+3, end_u,   end_v);
 }
 
+static inline void build_sprite_norm(struct vb_data *data, float fcx, float fcy,
+		uint32_t flip)
+{
+	float start_u, end_u;
+	float start_v, end_v;
+
+	assign_sprite_uv(&start_u, &end_u, (flip & GS_FLIP_U) != 0);
+	assign_sprite_uv(&start_v, &end_v, (flip & GS_FLIP_V) != 0);
+	build_sprite(data, fcx, fcy, start_u, end_u, start_v, end_v, flip);
+}
+
+static inline void build_sprite_rect(struct vb_data *data, texture_t tex,
+		float fcx, float fcy, uint32_t flip)
+{
+	float start_u, end_u;
+	float start_v, end_v;
+	float width  = (float)texture_getwidth(tex);
+	float height = (float)texture_getheight(tex);
+
+	assign_sprite_rect(&start_u, &end_u, width,  (flip & GS_FLIP_U) != 0);
+	assign_sprite_rect(&start_v, &end_v, height, (flip & GS_FLIP_V) != 0);
+	build_sprite(data, fcx, fcy, start_u, end_u, start_v, end_v, flip);
+}
+
 void gs_draw_sprite(texture_t tex, uint32_t flip, uint32_t width,
 		uint32_t height)
 {
@@ -693,7 +725,11 @@ void gs_draw_sprite(texture_t tex, uint32_t flip, uint32_t width,
 	fcy = height ? (float)height : (float)texture_getheight(tex);
 
 	data = vertexbuffer_getdata(graphics->sprite_buffer);
-	build_sprite(data, fcx, fcy, flip);
+	if (texture_isrect(tex))
+		build_sprite_rect(data, tex, fcx, fcy, flip);
+	else
+		build_sprite_norm(data, fcx, fcy, flip);
+
 	vertexbuffer_flush(graphics->sprite_buffer, false);
 	gs_load_vertexbuffer(graphics->sprite_buffer);
 	gs_load_indexbuffer(NULL);
@@ -1408,6 +1444,15 @@ void texture_unmap(texture_t tex)
 	graphics->exports.texture_unmap(tex);
 }
 
+bool texture_isrect(texture_t tex)
+{
+	graphics_t graphics = thread_graphics;
+	if (graphics->exports.texture_isrect)
+		return graphics->exports.texture_isrect(tex);
+	else
+		return false;
+}
+
 void cubetexture_destroy(texture_t cubetex)
 {
 	graphics_t graphics = thread_graphics;

+ 4 - 0
libobs/graphics/graphics.h

@@ -641,6 +641,10 @@ EXPORT uint32_t texture_getheight(texture_t tex);
 EXPORT enum gs_color_format texture_getcolorformat(texture_t tex);
 EXPORT bool     texture_map(texture_t tex, void **ptr, uint32_t *row_bytes);
 EXPORT void     texture_unmap(texture_t tex);
+/** special-case function (GL only) - specifies whether the texture is a
+ * GL_TEXTURE_RECTANGLE type, which doesn't use normalized texture
+ * coordinates */
+EXPORT bool     texture_isrect(texture_t tex);
 
 EXPORT void     cubetexture_destroy(texture_t cubetex);
 EXPORT uint32_t cubetexture_getsize(texture_t cubetex);