added shader attributes and added vertex buffer loading

This commit is contained in:
jp9000 2013-10-11 20:14:26 -07:00
parent 3951babc93
commit aeea0eadc9
8 changed files with 251 additions and 61 deletions

View file

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

View file

@ -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_vertexbuffer(device_t device, vertbuffer_t vertbuffer);
EXPORT void device_load_indexbuffer(device_t device, indexbuffer_t indexbuffer); 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_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, EXPORT void device_load_samplerstate(device_t device,
samplerstate_t samplerstate, int unit); samplerstate_t samplerstate, int unit);
EXPORT void device_load_vertexshader(device_t device, shader_t vertshader); EXPORT void device_load_vertexshader(device_t device, shader_t vertshader);

View file

@ -108,13 +108,69 @@ static inline void gl_add_samplers(struct gs_shader *shader,
struct gl_shader_parser *glsp) struct gl_shader_parser *glsp)
{ {
size_t i; size_t i;
for (i = 0; i < glsp->parser.samplers.num; i++) { for (i = 0; i < glsp->parser.samplers.num; i++) {
struct shader_sampler *sampler = glsp->parser.samplers.array+i; struct shader_sampler *sampler = glsp->parser.samplers.array+i;
gl_add_sampler(shader, sampler); 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, static bool gl_shader_init(struct gs_shader *shader,
struct gl_shader_parser *glsp, struct gl_shader_parser *glsp,
const char *file, char **error_string) const char *file, char **error_string)
@ -140,6 +196,8 @@ static bool gl_shader_init(struct gs_shader *shader,
if (success) if (success)
success = gl_add_params(shader, glsp); success = gl_add_params(shader, glsp);
if (success)
success = gl_add_attribs(shader, glsp);
if (success) if (success)
gl_add_samplers(shader, glsp); gl_add_samplers(shader, glsp);
@ -176,14 +234,22 @@ shader_t device_create_vertexshader(device_t device,
const char *shader, const char *file, const char *shader, const char *file,
char **error_string) 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, shader_t device_create_pixelshader(device_t device,
const char *shader, const char *file, const char *shader, const char *file,
char **error_string) 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) void shader_destroy(shader_t shader)

View file

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

View file

@ -27,21 +27,40 @@
#include "util/dstr.h" #include "util/dstr.h"
#include "graphics/shader-parser.h" #include "graphics/shader-parser.h"
struct gl_shader_parser { struct gl_parser_attrib {
struct dstr gl_string; struct dstr name;
struct shader_parser parser; 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) static inline void gl_shader_parser_init(struct gl_shader_parser *glsp)
{ {
shader_parser_init(&glsp->parser); shader_parser_init(&glsp->parser);
dstr_init(&glsp->gl_string); 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) 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); dstr_free(&glsp->gl_string);
shader_parser_free(&glsp->parser); shader_parser_free(&glsp->parser);
} }

View file

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

View file

@ -185,37 +185,54 @@ extern void convert_sampler_info(struct gs_sampler_state *sampler,
struct gs_sampler_info *info); struct gs_sampler_info *info);
struct gs_sampler_state { struct gs_sampler_state {
GLint min_filter; GLint min_filter;
GLint mag_filter; GLint mag_filter;
GLint address_u; GLint address_u;
GLint address_v; GLint address_v;
GLint address_w; GLint address_w;
GLint max_anisotropy; GLint max_anisotropy;
}; };
struct shader_param { struct shader_param {
char *name;
enum shader_param_type type; 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; struct gs_texture *texture;
DARRAY(uint8_t) def_value;
bool changed; 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 { struct gs_shader {
device_t device; device_t device;
enum shader_type type; enum shader_type type;
GLuint program; GLuint program;
struct shader_param *viewproj; struct shader_param *viewproj;
struct shader_param *world; struct shader_param *world;
DARRAY(struct shader_attrib) attribs;
DARRAY(struct gs_sampler_state) samplers; DARRAY(struct gs_sampler_state) samplers;
DARRAY(struct shader_param) params; DARRAY(struct shader_param) params;
}; };
@ -226,6 +243,7 @@ struct gs_vertex_buffer {
GLuint tangent_buffer; GLuint tangent_buffer;
GLuint color_buffer; GLuint color_buffer;
DARRAY(GLuint) uv_buffers; DARRAY(GLuint) uv_buffers;
DARRAY(size_t) uv_sizes;
device_t device; device_t device;
bool dynamic; bool dynamic;
@ -233,15 +251,15 @@ struct gs_vertex_buffer {
}; };
struct gs_index_buffer { struct gs_index_buffer {
GLuint buffer; GLuint buffer;
enum gs_index_type type; enum gs_index_type type;
GLuint gl_type; GLuint gl_type;
device_t device; device_t device;
void *data; void *data;
size_t num; size_t num;
size_t size; size_t size;
bool dynamic; bool dynamic;
}; };
struct gs_texture { struct gs_texture {
@ -302,11 +320,16 @@ struct gs_device {
struct gl_platform *plat; struct gl_platform *plat;
enum copy_type copy_type; 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; int cur_render_side;
struct gs_texture *cur_textures[GS_MAX_TEXTURES]; texture_t cur_textures[GS_MAX_TEXTURES];
struct gs_sampler *cur_samplers[GS_MAX_TEXTURES]; samplerstate_t cur_samplers[GS_MAX_TEXTURES];
struct gs_swap_chain *cur_swap; 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, extern struct gl_platform *gl_platform_create(device_t device,

View file

@ -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_buffers, vb->data->num_tex);
da_reserve(vb->uv_sizes, vb->data->num_tex);
for (i = 0; i < vb->data->num_tex; i++) { for (i = 0; i < vb->data->num_tex; i++) {
GLuint tex_buffer; GLuint tex_buffer;
@ -61,6 +62,7 @@ static bool init_vb(struct gs_vertex_buffer *vb)
return false; return false;
da_push_back(vb->uv_buffers, &tex_buffer); da_push_back(vb->uv_buffers, &tex_buffer);
da_push_back(vb->uv_sizes, &tv->width);
} }
if (!vb->dynamic) { if (!vb->dynamic) {
@ -109,6 +111,7 @@ void vertexbuffer_destroy(vertbuffer_t vb)
gl_delete_buffers((GLsizei)vb->uv_buffers.num, gl_delete_buffers((GLsizei)vb->uv_buffers.num,
vb->uv_buffers.array); vb->uv_buffers.array);
da_free(vb->uv_sizes);
da_free(vb->uv_buffers); da_free(vb->uv_buffers);
vbdata_destroy(vb->data); vbdata_destroy(vb->data);
@ -170,3 +173,83 @@ struct vb_data *vertexbuffer_getdata(vertbuffer_t vb)
{ {
return vb->data; 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");
}