SCE_RShaderGLSL* SCE_RCreateShaderGLSL (SCE_RShaderType type) { SCE_RShaderGLSL *shader = NULL; shader = SCE_malloc (sizeof *shader); if (!shader) { SCEE_LogSrc (); return NULL; } shader->data = NULL; shader->compiled = SCE_FALSE; shader->type = type; shader->gltype = sce_gltype[type]; shader->id = glCreateShader (shader->gltype); if (shader->id == 0) { SCEE_Log (SCE_ERROR); SCEE_LogMsg ("failed to create shader: %s", SCE_RGetError ()); SCE_free (shader); return NULL; } return shader; }
int SCE_RBuildShaderGLSL (SCE_RShaderGLSL *shader) { int compile_status = GL_TRUE; int loginfo_size = 0; char *loginfo = NULL; glShaderSource (shader->id, 1, (const GLchar**)&shader->data, NULL); glCompileShader (shader->id); glGetShaderiv (shader->id, GL_COMPILE_STATUS, &compile_status); if (compile_status != GL_TRUE) { SCEE_Log (SCE_INVALID_OPERATION); glGetShaderiv (shader->id, GL_INFO_LOG_LENGTH, &loginfo_size); loginfo = SCE_malloc (loginfo_size + 1); if (!loginfo) { SCEE_LogSrc (); return SCE_ERROR; } memset (loginfo, '\0', loginfo_size + 1); glGetShaderInfoLog (shader->id, loginfo_size, &loginfo_size, loginfo); SCEE_LogMsg ("error while compiling GLSL %s shader :\n%s", sce_typename[shader->type], loginfo); SCE_free (loginfo); return SCE_ERROR; } shader->compiled = SCE_TRUE; return SCE_OK; }
SCE_RProgram* SCE_RCreateProgram (void) { int i; SCE_RProgram *prog = NULL; prog = SCE_malloc (sizeof *prog); if (!prog) { SCEE_LogSrc (); return NULL; } prog->id = glCreateProgram (); prog->linked = SCE_FALSE; SCE_RInitVertexAttributesMap (prog->map); prog->map_built = SCE_FALSE; prog->use_vmap = SCE_FALSE; for (i = 0; i < SCE_NUM_MATRICES; i++) { prog->funs[i] = SCE_RSetProgramNoneMatrix; prog->mat_map[i] = -1; } prog->use_mmap = SCE_FALSE; prog->use_tess = SCE_FALSE; prog->patch_vertices = 0; prog->fb_enabled = SCE_FALSE; prog->fb_mode = SCE_FEEDBACK_INTERLEAVED; prog->fb_varyings = NULL; prog->n_varyings = 0; for (i = 0; i < SCE_MAX_ATTACHMENT_BUFFERS; i++) memset (prog->outputs[i], 0, SCE_SHADER_OUTPUT_LENGTH); return prog; }
int SCE_RValidateProgram (SCE_RProgram *prog) { int status = GL_TRUE; int loginfo_size = 0; char *loginfo = NULL; glValidateProgram (prog->id); glGetProgramiv (prog->id, GL_VALIDATE_STATUS, &status); if (status != GL_TRUE) { /* TODO: add program name */ glGetProgramiv (prog->id, GL_INFO_LOG_LENGTH, &loginfo_size); loginfo = SCE_malloc (loginfo_size + 1); if (!loginfo) { SCEE_LogSrc (); return SCE_ERROR; } memset (loginfo, '\0', loginfo_size + 1); glGetProgramInfoLog (prog->id, loginfo_size, &loginfo_size, loginfo); SCEE_LogMsg ("can't validate program, reason: %s", loginfo); return SCE_ERROR; } return SCE_OK; }
/** * \brief Specify which varying should be written to the feedback stream(s) * \param prog a shader * \param n number of varyings * \param varyings names of the varyings that will be written onto the buffers * \param mode storage mode */ int SCE_RSetProgramFeedbackVaryings (SCE_RProgram *prog, SCEuint n, const char **varyings, SCE_RFeedbackStorageMode mode) { size_t i; if (n == 0) { prog->fb_enabled = SCE_FALSE; for (i = 0; i < prog->n_varyings; i++) SCE_free (prog->fb_varyings[i]); SCE_free (prog->fb_varyings); } else { prog->n_varyings = n; if (!(prog->fb_varyings = SCE_malloc (n * sizeof *prog->fb_varyings))) goto fail; for (i = 0; i < n; i++) prog->fb_varyings[i] = NULL; for (i = 0; i < prog->n_varyings; i++) { if (!(prog->fb_varyings[i] = SCE_String_Dup (varyings[i]))) goto fail; } prog->fb_enabled = SCE_TRUE; prog->fb_mode = mode; prog->linked = SCE_FALSE; /* link will be needed */ } return SCE_OK; fail: SCEE_LogSrc (); return SCE_ERROR; }
/** * \brief Creates a skybox */ SCE_SSkybox* SCE_Skybox_Create (void) { SCE_SSceneEntityProperties *props = NULL; SCE_SSkybox *skybox = NULL; if (!(skybox = SCE_malloc (sizeof *skybox))) goto fail; SCE_Skybox_Init (skybox); if (!(skybox->mesh = SCE_Mesh_Create ())) goto fail; if (!(skybox->entity = SCE_SceneEntity_Create ())) goto fail; if (!(skybox->instance = SCE_SceneEntity_CreateInstance ())) goto fail; SCE_SceneEntity_AddInstanceToEntity (skybox->entity, skybox->instance); props = SCE_SceneEntity_GetProperties (skybox->entity); props->cullface = SCE_FALSE; props->depthtest = SCE_FALSE; props->alphatest = SCE_FALSE; return skybox; fail: SCE_Skybox_Delete (skybox); SCEE_LogSrc (); return NULL; }
/** * \brief Allocates memory for the base vertices (4D vectors) * \param attrib vertex attribute of the vectors * \param local are the vectors in local position from their joints? * \returns SCE_ERROR on error, SCE_OK otherwise */ int SCE_AnimGeom_AllocateBaseVertices (SCE_SAnimatedGeometry *ageom, SCE_EVertexAttribute attrib, int local) { float *data = NULL; size_t i, n, id; if (local) n = ageom->n_weights; else n = ageom->n_vertices; #ifdef SCE_DEBUG if (ageom->n_vertices == 0) { SCEE_Log (SCE_INVALID_OPERATION); SCEE_LogMsg ("you must call SCE_AnimGeom_AllocateVertices() " "before calling this function"); return SCE_ERROR; } else if (n == 0) { SCEE_Log (SCE_INVALID_OPERATION); SCEE_LogMsg ("you must call SCE_AnimGeom_AllocateWeights() " "before calling this function"); return SCE_ERROR; } #endif id = SCE_AnimGeom_GetVerticesID (attrib); if (!(data = SCE_malloc (n * 4 * sizeof *data))) { SCEE_LogSrc (); return SCE_ERROR; } ageom->output[id] = SCE_malloc (ageom->n_vertices * 3 * sizeof *data); if (!ageom->output[id]) { SCE_free (data); SCEE_LogSrc (); return SCE_ERROR; } for (i = 0; i < n; i++) { data[i] = ageom->output[id][i] = 0.0f; data[i + 1] = ageom->output[id][i + 1] = 0.0f; data[i + 2] = ageom->output[id][i + 2] = 0.0f; data[i + 3] = 0.0f; } SCE_free (ageom->base[id]); ageom->base[id] = data; ageom->local[id] = local; return SCE_OK; }
SCE_RPointSprite* SCE_RCreatePointSprite (void) { SCE_RPointSprite *point = NULL; if (!(point = SCE_malloc (sizeof *point))) SCEE_LogSrc (); else SCE_RInitPointSprite (point); return point; }
SCE_STexData* SCE_TexData_Create (void) { SCE_STexData *d = NULL; if (!(d = SCE_malloc (sizeof *d))) SCEE_LogSrc (); else SCE_TexData_Init (d); return d; }
SCE_SParticleEmitter* SCE_ParticleEmit_Create (void) { SCE_SParticleEmitter *emit = NULL; if (!(emit = SCE_malloc (sizeof *emit))) SCEE_LogSrc (); else SCE_ParticleEmit_Init (emit); return emit; }
SCE_SVoxelGrid* SCE_VGrid_Create (void) { SCE_SVoxelGrid *vg = NULL; if (!(vg = SCE_malloc (sizeof *vg))) SCEE_LogSrc (); else SCE_VGrid_Init (vg); return vg; }
SCE_SVoxelStorage* SCE_VStore_Create (void) { SCE_SVoxelStorage *vs = NULL; if (!(vs = SCE_malloc (sizeof *vs))) SCEE_LogSrc (); else SCE_VStore_Init (vs); return vs; }
SCE_RMaterial* SCE_RCreateMaterial (void) { SCE_RMaterial *mat = SCE_malloc (sizeof *mat); if (!mat) SCEE_LogSrc (); else SCE_RInitMaterial (mat); return mat; }
SCE_RLight* SCE_RCreateLight (void) { SCE_RLight *light = NULL; if (!(light = SCE_malloc (sizeof *light))) SCEE_LogSrc (); else SCE_RInitLight (light); return light; }
int SCE_RBuildProgram (SCE_RProgram *prog) { const int modes[2] = {GL_INTERLEAVED_ATTRIBS, GL_SEPARATE_ATTRIBS}; int status = GL_TRUE; int loginfo_size = 0; char *loginfo = NULL; int i, j; if (prog->linked) return SCE_OK; /* setting transform feedback up */ if (prog->fb_enabled) { glTransformFeedbackVaryings (prog->id, prog->n_varyings, (const GLchar**)prog->fb_varyings, modes[prog->fb_mode]); } /* TODO: follows the same pattern as SCE_RSetDrawBuffers */ j = 0; for (i = 0; i < SCE_MAX_ATTACHMENT_BUFFERS; i++) { if (*prog->outputs[i]) glBindFragDataLocation (prog->id, j++, prog->outputs[i]); } glLinkProgram (prog->id); glGetProgramiv (prog->id, GL_LINK_STATUS, &status); if (status != GL_TRUE) { SCEE_Log (SCE_INVALID_OPERATION); glGetProgramiv (prog->id, GL_INFO_LOG_LENGTH, &loginfo_size); loginfo = SCE_malloc (loginfo_size + 1); if (!loginfo) { SCEE_LogSrc (); return SCE_ERROR; } memset (loginfo, '\0', loginfo_size + 1); glGetProgramInfoLog (prog->id, loginfo_size, &loginfo_size, loginfo); /* TODO: add program name */ SCEE_LogMsg ("can't link program, reason: %s", loginfo); SCE_free (loginfo); return SCE_ERROR; } prog->linked = SCE_TRUE; /* if the map was previously built, rebuild it */ if (prog->map_built) SCE_RSetupProgramAttributesMapping (prog); return SCE_OK; }
int SCE_VGrid_Build (SCE_SVoxelGrid *vg) { size_t size; size = vg->n_cmp * SCE_VGrid_GetNumVoxels (vg); if (!(vg->data = SCE_malloc (size))) { SCEE_LogSrc (); return SCE_ERROR; } /* NOTE: fill the voxels with an empty pattern... ? */ return SCE_OK; }
/** * \brief Allocates memory for vertex weights * \returns SCE_ERROR on error, SCE_OK otherwise * \sa SCE_AnimGeom_SetWeights(), SCE_AnimGeom_AllocateVertices() */ int SCE_AnimGeom_AllocateWeights (SCE_SAnimatedGeometry *ageom, size_t n) { size_t i; SCE_free (ageom->weights); if (!(ageom->weights = SCE_malloc (n * sizeof *ageom->weights))) { SCEE_LogSrc (); return SCE_ERROR; } ageom->n_weights = n; for (i = 0; i < n; i++) SCE_AnimGeom_InitWeight (&ageom->weights[i]); return SCE_OK; }
/** * \brief Allocates memory for vertices * \returns SCE_ERROR on error, SCE_OK otherwise * \sa SCE_AnimGeom_AllocateWeights() */ int SCE_AnimGeom_AllocateVertices (SCE_SAnimatedGeometry *ageom, size_t n) { size_t i; SCE_free (ageom->vertices); if (!(ageom->vertices = SCE_malloc (n * sizeof *ageom->vertices))) { SCEE_LogSrc (); return SCE_ERROR; } ageom->n_vertices = n; for (i = 0; i < n; i++) SCE_AnimGeom_InitVertex (&ageom->vertices[i]); return SCE_OK; }
/** * \brief Creates a new animated geometry */ SCE_SAnimatedGeometry* SCE_AnimGeom_Create (void) { SCE_SAnimatedGeometry *ageom = NULL; if (!(ageom = SCE_malloc (sizeof *ageom))) SCEE_LogSrc (); else { SCE_AnimGeom_Init (ageom); if (!(ageom->geom = SCE_Geometry_Create ())) { SCE_free (ageom), ageom = NULL; SCEE_LogSrc (); } } return ageom; }
/* also vacuum in void, dog. */ int SCE_VStore_Build (SCE_SVoxelStorage *vs, const void *vacuum) { SCEuint i; if (!(vs->vacuum = SCE_malloc (vs->data_size))) goto fail; memcpy (vs->vacuum, vacuum, vs->data_size); for (i = 0; i < vs->n_lod; i++) { if (SCE_VStore_BuildLevel (vs, i) < 0) goto fail; } return SCE_OK; fail: SCEE_LogSrc (); return SCE_ERROR; }
/** * \brief Duplicates a texture data * \param d the texture data to copy * * This function duplicates the data of the texture but not the image. * \returns the copy of \p d */ SCE_STexData* SCE_TexData_Dup (const SCE_STexData *d) { SCE_STexData *data = NULL; if (!(data = SCE_TexData_Create ())) { SCEE_LogSrc (); return NULL; } SCE_TexData_Copy (data, d); data->data_user = SCE_FALSE; data->data = NULL; if (data->data_size > 0 && d->data) { if (!(data->data = SCE_malloc (data->data_size))) { SCE_TexData_Delete (data); SCEE_LogSrc (); return NULL; } memcpy (data->data, d->data, data->data_size); } return data; }
static int SCE_VStore_BuildLevel (SCE_SVoxelStorage *vs, SCEuint level) { SCEuint i; size_t size, offset, num; SCE_SVoxelStorageLevel *sl = NULL; sl = &vs->levels[level]; size = SCE_VStore_GetSize (vs, level); if (!(sl->data = SCE_malloc (size))) { SCEE_LogSrc (); return SCE_ERROR; } /* fill voxels with the given vaccum data */ num = SCE_VStore_GetNumPoints (vs, level); size = vs->data_size; for (i = 0; i < num; i++) memcpy (&sl->data[i * size], vs->vacuum, size); return SCE_OK; }
int SCE_TexData_SetImage (SCE_STexData *d, SCE_SImage *img, int canfree) { d->data_size = SCE_Image_GetDataSize (img); d->data_user = SCE_FALSE; if (!(d->data = SCE_malloc (d->data_size))) { SCEE_LogSrc (); return SCE_ERROR; } memcpy (d->data, SCE_Image_GetData (img), d->data_size); d->img = img; d->canfree = canfree; d->target = SCE_Image_GetType (img); d->level = SCE_Image_GetMipmapLevel (img); d->w = SCE_Image_GetWidth (img); d->h = SCE_Image_GetHeight (img); d->d = SCE_Image_GetDepth (img); /* NOTE: warning, not calling SCE_TexData_SetPixelFormat() */ d->pxf = SCE_Image_GetPixelFormat (img); d->data_fmt = SCE_Image_GetFormat (img); d->data_type = SCE_Image_GetDataType (img); d->comp = SCE_Image_IsCompressed (img); return SCE_OK; }
/** * \brief Set the vertices in global position * \param bpose the bind pose skeleton * \sa SCE_AnimGeom_SetGlobal() * \todo manage the w component */ int SCE_AnimGeom_SetGlobal (SCE_SAnimatedGeometry *ageom) { size_t i; for (i = 0; i < SCE_MAX_ANIMATED_VERTEX_ATTRIBUTES; i++) { if (ageom->local[i] && ageom->base[i]) { SCEvertices *vert = NULL; size_t j; /* alloc new base */ if (!(vert = SCE_malloc (ageom->n_vertices * 4 * sizeof *vert))) { SCEE_LogSrc (); return SCE_ERROR; } SCE_AnimGeom_ApplySkeletonLocal (ageom, i, ageom->baseskel); for (j = 0; j < ageom->n_vertices; j++) { SCE_Vector3_Copy (&vert[j * 4], &ageom->output[i][j * 3]); } SCE_free (ageom->base[i]); ageom->base[i] = vert; ageom->local[i] = SCE_FALSE; } } return SCE_OK; }