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_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;

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_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);

View file

@ -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)

View file

@ -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);
}
}

View file

@ -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);
}

View file

@ -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)

View file

@ -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;
GLuint buffer;
enum gs_index_type type;
GLuint gl_type;
device_t device;
void *data;
size_t num;
size_t size;
bool dynamic;
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,

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_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");
}