ソースを参照

added shader attributes and added vertex buffer loading

jp9000 12 年 前
コミット
aeea0eadc9

+ 1 - 1
libobs-d3d11/d3d11-subsystem.hpp

@@ -575,8 +575,8 @@ struct gs_device {
 	gs_texture                  *curTextures[GS_MAX_TEXTURES];
 	gs_sampler_state            *curSamplers[GS_MAX_TEXTURES];
 	gs_vertex_buffer            *curVertexBuffer;
-	gs_vertex_shader            *curVertexShader;
 	gs_index_buffer             *curIndexBuffer;
+	gs_vertex_shader            *curVertexShader;
 	gs_pixel_shader             *curPixelShader;
 	gs_swap_chain               *curSwapChain;
 

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

@@ -60,10 +60,6 @@ EXPORT enum gs_texture_type device_gettexturetype(device_t device,
 EXPORT void device_load_vertexbuffer(device_t device, vertbuffer_t vertbuffer);
 EXPORT void device_load_indexbuffer(device_t device, indexbuffer_t indexbuffer);
 EXPORT void device_load_texture(device_t device, texture_t tex, int unit);
-EXPORT void device_load_cubetexture(device_t device, texture_t cubetex,
-		int unit);
-EXPORT void device_load_volumetexture(device_t device, texture_t voltex,
-		int unit);
 EXPORT void device_load_samplerstate(device_t device,
 		samplerstate_t samplerstate, int unit);
 EXPORT void device_load_vertexshader(device_t device, shader_t vertshader);

+ 69 - 3
libobs-opengl/gl-shader.c

@@ -108,13 +108,69 @@ static inline void gl_add_samplers(struct gs_shader *shader,
 		struct gl_shader_parser *glsp)
 {
 	size_t i;
-
 	for (i = 0; i < glsp->parser.samplers.num; i++) {
 		struct shader_sampler *sampler = glsp->parser.samplers.array+i;
 		gl_add_sampler(shader, sampler);
 	}
 }
 
+static void get_attrib_type(const char *mapping, enum attrib_type *type,
+		size_t *index)
+{
+	if (strcmp(mapping, "POSITION") == 0) {
+		*type  = ATTRIB_POSITION;
+
+	} else if (strcmp(mapping, "NORMAL") == 0) {
+		*type  = ATTRIB_NORMAL;
+
+	} else if (strcmp(mapping, "TANGENT") == 0) {
+		*type  = ATTRIB_TANGENT;
+
+	} else if (strcmp(mapping, "COLOR") == 0) {
+		*type  = ATTRIB_COLOR;
+
+	} else if (astrcmp_n(mapping, "TEXCOORD", 8) == 0) {
+		*type  = ATTRIB_TEXCOORD;
+		*index = (*(mapping+8)) - '0';
+		return;
+
+	} else if (strcmp(mapping, "TARGET") == 0) {
+		*type  = ATTRIB_TARGET;
+	}
+
+	*index = 0;
+}
+
+static inline bool gl_add_attrib(struct gs_shader *shader,
+		struct gl_parser_attrib *pa)
+{
+	struct shader_attrib attrib = {0};
+	get_attrib_type(pa->mapping, &attrib.type, &attrib.index);
+
+	attrib.attrib = glGetAttribLocation(shader->program, pa->name.array);
+	if (!gl_success("glGetAttribLocation"))
+		return false;
+
+	if (attrib.attrib == -1)
+		return false;
+
+	da_push_back(shader->attribs, &attrib);
+	return true;
+}
+
+static inline bool gl_add_attribs(struct gs_shader *shader,
+		struct gl_shader_parser *glsp)
+{
+	size_t i;
+	for (i = 0; i < glsp->attribs.num; i++) {
+		struct gl_parser_attrib *pa = glsp->attribs.array+i;
+		if (!gl_add_attrib(shader, pa))
+			return false;
+	}
+
+	return true;
+}
+
 static bool gl_shader_init(struct gs_shader *shader,
 		struct gl_shader_parser *glsp,
 		const char *file, char **error_string)
@@ -140,6 +196,8 @@ static bool gl_shader_init(struct gs_shader *shader,
 
 	if (success)
 		success = gl_add_params(shader, glsp);
+	if (success)
+		success = gl_add_attribs(shader, glsp);
 	if (success)
 		gl_add_samplers(shader, glsp);
 
@@ -176,14 +234,22 @@ shader_t device_create_vertexshader(device_t device,
 		const char *shader, const char *file,
 		char **error_string)
 {
-	return shader_create(device, SHADER_VERTEX, shader, file, error_string);
+	struct gs_shader *ptr;
+	ptr = shader_create(device, SHADER_VERTEX, shader, file, error_string);
+	if (!ptr)
+		blog(LOG_ERROR, "device_create_vertexshader (GL) failed");
+	return ptr;
 }
 
 shader_t device_create_pixelshader(device_t device,
 		const char *shader, const char *file,
 		char **error_string)
 {
-	return shader_create(device, SHADER_PIXEL, shader, file, error_string);
+	struct gs_shader *ptr;
+	ptr = shader_create(device, SHADER_PIXEL, shader, file, error_string);
+	if (!ptr)
+		blog(LOG_ERROR, "device_create_pixelshader (GL) failed");
+	return ptr;
 }
 
 void shader_destroy(shader_t shader)

+ 10 - 3
libobs-opengl/gl-shaderparser.c

@@ -146,17 +146,24 @@ static void gl_write_storage_var(struct gl_shader_parser *glsp,
 	if (st) {
 		gl_unwrap_storage_struct(glsp, st, var->name, storage, prefix);
 	} else {
+		struct gl_parser_attrib attrib = {0};
+
 		if (storage) {
 			dstr_cat(&glsp->gl_string, storage);
 			dstr_cat(&glsp->gl_string, " ");
 		}
 
+		if (prefix)
+			dstr_cat(&attrib.name, prefix);
+		dstr_cat(&attrib.name, var->name);
+
 		gl_write_type(glsp, var->type);
 		dstr_cat(&glsp->gl_string, " ");
-		if (prefix)
-			dstr_cat(&glsp->gl_string, prefix);
-		dstr_cat(&glsp->gl_string, var->name);
+		dstr_cat_dstr(&glsp->gl_string, &attrib.name);
 		dstr_cat(&glsp->gl_string, ";\n");
+
+		attrib.mapping = var->mapping;
+		da_push_back(glsp->attribs, &attrib);
 	}
 }
 

+ 23 - 4
libobs-opengl/gl-shaderparser.h

@@ -27,21 +27,40 @@
 #include "util/dstr.h"
 #include "graphics/shader-parser.h"
 
-struct gl_shader_parser {
-	struct dstr          gl_string;
-	struct shader_parser parser;
+struct gl_parser_attrib {
+	struct dstr name;
+	const char  *mapping;
+};
 
-	DARRAY(uint32_t)     texture_samplers;
+static inline gl_parser_attrib_free(struct gl_parser_attrib *attr)
+{
+	dstr_free(&attr->name);
+}
+
+struct gl_shader_parser {
+	struct shader_parser            parser;
+	struct dstr                     gl_string;
+                                       
+	DARRAY(uint32_t)                texture_samplers;
+	DARRAY(struct gl_parser_attrib) attribs;
 };
 
 static inline void gl_shader_parser_init(struct gl_shader_parser *glsp)
 {
 	shader_parser_init(&glsp->parser);
 	dstr_init(&glsp->gl_string);
+	da_init(glsp->texture_samplers);
+	da_init(glsp->attribs);
 }
 
 static inline void gl_shader_parser_free(struct gl_shader_parser *glsp)
 {
+	size_t i;
+	for (i = 0; i < glsp->attribs.num; i++)
+		gl_parser_attrib_free(glsp->attribs.array+i);
+
+	da_free(glsp->attribs);
+	da_free(glsp->texture_samplers);
 	dstr_free(&glsp->gl_string);
 	shader_parser_free(&glsp->parser);
 }

+ 10 - 14
libobs-opengl/gl-subsystem.c

@@ -115,10 +115,7 @@ samplerstate_t device_create_samplerstate(device_t device,
 enum gs_texture_type device_gettexturetype(device_t device,
 		texture_t texture)
 {
-}
-
-void device_load_vertexbuffer(device_t device, vertbuffer_t vertbuffer)
-{
+	return texture->type;
 }
 
 void device_load_indexbuffer(device_t device, indexbuffer_t indexbuffer)
@@ -129,16 +126,6 @@ void device_load_texture(device_t device, texture_t tex, int unit)
 {
 }
 
-void device_load_cubetexture(device_t device, texture_t cubetex,
-		int unit)
-{
-}
-
-void device_load_volumetexture(device_t device, texture_t voltex,
-		int unit)
-{
-}
-
 void device_load_samplerstate(device_t device,
 		samplerstate_t samplerstate, int unit)
 {
@@ -331,22 +318,31 @@ void swapchain_destroy(swapchain_t swapchain)
 
 void volumetexture_destroy(texture_t voltex)
 {
+	/* TODO */
 }
 
 uint32_t volumetexture_getwidth(texture_t voltex)
 {
+	/* TODO */
+	return 0;
 }
 
 uint32_t volumetexture_getheight(texture_t voltex)
 {
+	/* TODO */
+	return 0;
 }
 
 uint32_t volumetexture_getdepth(texture_t voltex)
 {
+	/* TODO */
+	return 0;
 }
 
 enum gs_color_format volumetexture_getcolorformat(texture_t voltex)
 {
+	/* TODO */
+	return GS_UNKNOWN;
 }
 
 void samplerstate_destroy(samplerstate_t samplerstate)

+ 56 - 33
libobs-opengl/gl-subsystem.h

@@ -185,37 +185,54 @@ extern void convert_sampler_info(struct gs_sampler_state *sampler,
 		struct gs_sampler_info *info);
 
 struct gs_sampler_state {
-	GLint min_filter;
-	GLint mag_filter;
-	GLint address_u;
-	GLint address_v;
-	GLint address_w;
-	GLint max_anisotropy;
+	GLint                min_filter;
+	GLint                mag_filter;
+	GLint                address_u;
+	GLint                address_v;
+	GLint                address_w;
+	GLint                max_anisotropy;
 };
 
 struct shader_param {
-	char                   *name;
 	enum shader_param_type type;
-	GLint                  param;
-	GLint                  texture_id;
-	size_t                 sampler_id;
-	int                    array_count;
 
-	struct gs_texture      *texture;
+	char                 *name;
+	GLint                param;
+	GLint                texture_id;
+	size_t               sampler_id;
+	int                  array_count;
 
-	DARRAY(uint8_t)        cur_value;
-	DARRAY(uint8_t)        def_value;
-	bool                   changed;
+	struct gs_texture    *texture;
+
+	DARRAY(uint8_t)      cur_value;
+	DARRAY(uint8_t)      def_value;
+	bool                 changed;
+};
+
+enum attrib_type {
+	ATTRIB_POSITION,
+	ATTRIB_NORMAL,
+	ATTRIB_TANGENT,
+	ATTRIB_COLOR,
+	ATTRIB_TEXCOORD,
+	ATTRIB_TARGET
+};
+
+struct shader_attrib {
+	GLint                attrib;
+	size_t               index;
+	enum attrib_type     type;
 };
 
 struct gs_shader {
-	device_t            device;
-	enum shader_type    type;
-	GLuint              program;
+	device_t             device;
+	enum shader_type     type;
+	GLuint               program;
 
-	struct shader_param *viewproj;
-	struct shader_param *world;
+	struct shader_param  *viewproj;
+	struct shader_param  *world;
 
+	DARRAY(struct shader_attrib)    attribs;
 	DARRAY(struct gs_sampler_state) samplers;
 	DARRAY(struct shader_param)     params;
 };
@@ -226,6 +243,7 @@ struct gs_vertex_buffer {
 	GLuint               tangent_buffer;
 	GLuint               color_buffer;
 	DARRAY(GLuint)       uv_buffers;
+	DARRAY(size_t)       uv_sizes;
 
 	device_t             device;
 	bool                 dynamic;
@@ -233,15 +251,15 @@ struct gs_vertex_buffer {
 };
 
 struct gs_index_buffer {
-	GLuint                buffer;
-	enum gs_index_type    type;
-	GLuint                gl_type;
-
-	device_t              device;
-	void                  *data;
-	size_t                num;
-	size_t                size;
-	bool                  dynamic;
+	GLuint               buffer;
+	enum gs_index_type   type;
+	GLuint               gl_type;
+
+	device_t             device;
+	void                 *data;
+	size_t               num;
+	size_t               size;
+	bool                 dynamic;
 };
 
 struct gs_texture {
@@ -302,11 +320,16 @@ struct gs_device {
 	struct gl_platform   *plat;
 	enum copy_type       copy_type;
 
-	struct gs_texture    *cur_render_texture;
+	texture_t            cur_render_target;
+	zstencil_t           cur_zstencil_buffer;
 	int                  cur_render_side;
-	struct gs_texture    *cur_textures[GS_MAX_TEXTURES];
-	struct gs_sampler    *cur_samplers[GS_MAX_TEXTURES];
-	struct gs_swap_chain *cur_swap;
+	texture_t            cur_textures[GS_MAX_TEXTURES];
+	samplerstate_t       cur_samplers[GS_MAX_TEXTURES];
+	vertbuffer_t         cur_vertex_buffer;
+	indexbuffer_t        cur_index_buffer;
+	shader_t             cur_vertex_shader;
+	shader_t             cur_pixel_shader;
+	swapchain_t          cur_swap;
 };
 
 extern struct gl_platform   *gl_platform_create(device_t device,

+ 83 - 0
libobs-opengl/gl-vertexbuffer.c

@@ -50,6 +50,7 @@ static bool init_vb(struct gs_vertex_buffer *vb)
 	}
 
 	da_reserve(vb->uv_buffers, vb->data->num_tex);
+	da_reserve(vb->uv_sizes,   vb->data->num_tex);
 
 	for (i = 0; i < vb->data->num_tex; i++) {
 		GLuint tex_buffer;
@@ -61,6 +62,7 @@ static bool init_vb(struct gs_vertex_buffer *vb)
 			return false;
 
 		da_push_back(vb->uv_buffers, &tex_buffer);
+		da_push_back(vb->uv_sizes,   &tv->width);
 	}
 
 	if (!vb->dynamic) {
@@ -109,6 +111,7 @@ void vertexbuffer_destroy(vertbuffer_t vb)
 			gl_delete_buffers((GLsizei)vb->uv_buffers.num,
 					vb->uv_buffers.array);
 
+		da_free(vb->uv_sizes);
 		da_free(vb->uv_buffers);
 		vbdata_destroy(vb->data);
 
@@ -170,3 +173,83 @@ struct vb_data *vertexbuffer_getdata(vertbuffer_t vb)
 {
 	return vb->data;
 }
+
+static inline GLuint get_vb_buffer(struct gs_vertex_buffer *vb,
+		enum attrib_type type, size_t index, GLint *width,
+		GLenum *gl_type)
+{
+	*gl_type = GL_FLOAT;
+	*width   = 4;
+
+	if (type == ATTRIB_POSITION) {
+		return vb->vertex_buffer;
+	} else if (type == ATTRIB_NORMAL) {
+		return vb->normal_buffer;
+	} else if (type == ATTRIB_TANGENT) {
+		return vb->tangent_buffer;
+	} else if (type == ATTRIB_COLOR) {
+		*gl_type = GL_UNSIGNED_BYTE;
+		return vb->color_buffer;
+	} else if (type == ATTRIB_TEXCOORD) {
+		if (vb->uv_buffers.num <= index)
+			return 0;
+
+		*width = (GLint)vb->uv_sizes.array[index];
+		return vb->uv_buffers.array[index];
+	}
+
+	return 0;
+}
+
+static bool load_vb_buffer(struct gs_shader *shader,
+		struct shader_attrib *attrib,
+		struct gs_vertex_buffer *vb)
+{
+	GLenum type;
+	GLint width;
+	GLuint buffer;
+	bool success = true;
+
+	buffer = get_vb_buffer(vb, attrib->type, attrib->index, &width, &type);
+	if (!buffer) {
+		blog(LOG_ERROR, "Vertex buffer does not have the required "
+		                "inputs for vertex shader");
+		return false;
+	}
+
+	if (!gl_bind_buffer(GL_ARRAY_BUFFER, buffer))
+		return false;
+
+	glVertexAttribPointer(attrib->attrib, width, type, GL_TRUE, 0, 0);
+	if (!gl_success("glVertexAttribPointer"))
+		success = false;
+
+	gl_bind_buffer(GL_ARRAY_BUFFER, 0);
+	return success;
+}
+
+static inline bool load_vb_buffers(struct gs_shader *shader,
+		struct gs_vertex_buffer *vb)
+{
+	size_t i;
+	for (i = 0; i < shader->attribs.num; i++) {
+		struct shader_attrib *attrib = shader->attribs.array+i;
+		if (!load_vb_buffer(shader, attrib, vb))
+			return false;
+	}
+
+	return true;
+}
+
+void device_load_vertexbuffer(device_t device, vertbuffer_t vb)
+{
+	if (device->cur_vertex_buffer == vb)
+		return;
+
+	device->cur_vertex_buffer = vb;
+	if (!device->cur_vertex_shader)
+		return;
+
+	if (!load_vb_buffers(device->cur_vertex_shader, vb))
+		blog(LOG_ERROR, "device_load_vertexbuffer (GL) failed");
+}