RID render_shader_create(struct render *R, struct shader_init_args *args) { struct shader * s = (struct shader *)array_alloc(&R->shader); if (s == NULL) { return 0; } s->glid = glCreateProgram(); if (!compile_link(R, s, args->vs, args->fs)) { glDeleteProgram(s->glid); array_free(&R->shader, s); return 0; } s->texture_n = args->texture; int i; for (i=0;i<s->texture_n;i++) { s->texture_uniform[i] = glGetUniformLocation(s->glid, args->texture_uniform[i]); } #ifdef VAO_ENABLE glGenVertexArrays(1, &s->glvao); for (i=0;i<MAX_VB_SLOT;i++) { s->vbslot[i] = 0; } s->ib = 0; #endif CHECK_GL_ERROR return array_id(&R->shader, s); }
// what should be VERTEXBUFFER or INDEXBUFFER RID render_buffer_create(struct render *R, enum RENDER_OBJ what, const void *data, int n, int stride) { GLenum gltype; switch(what) { case VERTEXBUFFER: gltype = GL_ARRAY_BUFFER; break; case INDEXBUFFER: gltype = GL_ELEMENT_ARRAY_BUFFER; break; default: return 0; } struct buffer * buf = (struct buffer *)array_alloc(&R->buffer); if (buf == NULL) return 0; glGenBuffers(1, &buf->glid); glBindBuffer(gltype, buf->glid); if (data && n > 0) { glBufferData(gltype, n * stride, data, GL_STATIC_DRAW); buf->n = n; } else { buf->n = 0; } buf->gltype = gltype; buf->stride = stride; CHECK_GL_ERROR return array_id(&R->buffer, buf); }
RID render_register_vertexlayout(struct render *R, int n, struct vertex_attrib * attrib) { assert(n <= MAX_ATTRIB); struct attrib * a = (struct attrib*)array_alloc(&R->attrib); if (a == NULL) return 0; a->n = n; memcpy(a->a, attrib, n * sizeof(struct vertex_attrib)); RID id = array_id(&R->attrib, a); R->attrib_layout = id; return id; }
// render target static RID create_rt(struct render *R, RID texid) { struct target *tar = (struct target *)array_alloc(&R->target); if (tar == NULL) return 0; tar->tex = texid; struct texture * tex = (struct texture *)array_ref(&R->texture, texid); if (tex == NULL) return 0; glGenFramebuffers(1, &tar->glid); glBindFramebuffer(GL_FRAMEBUFFER, tar->glid); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex->glid, 0); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { close_target(tar, R); return 0; } CHECK_GL_ERROR return array_id(&R->target, tar); }
RID render_shader_create(struct render *R, struct shader_init_args *args) { struct shader * s = (struct shader *)array_alloc(&R->shader); if (s == NULL) { return 0; } s->glid = glCreateProgram(); if (!compile_link(R, s, args->vs, args->fs)) { glDeleteProgram(s->glid); array_free(&R->shader, s); return 0; } s->texture_n = args->texture; int i; for (i=0;i<s->texture_n;i++) { s->texture_uniform[i] = glGetUniformLocation(s->glid, args->texture_uniform[i]); } CHECK_GL_ERROR return array_id(&R->shader, s); }
RID render_texture_create(struct render *R, int width, int height, enum TEXTURE_FORMAT format, enum TEXTURE_TYPE type, int mipmap) { struct texture * tex = (struct texture *)array_alloc(&R->texture); if (tex == NULL) return 0; glGenTextures(1, &tex->glid); tex->width = width; tex->height = height; tex->format = format; tex->type = type; assert(type == TEXTURE_2D || type == TEXTURE_CUBE); tex->mipmap = mipmap; int size = calc_texture_size(format, width, height); if (mipmap) { size += size / 3; } if (type == TEXTURE_CUBE) { size *= 6; } tex->memsize = size; CHECK_GL_ERROR return array_id(&R->texture, tex); }