00001 #include <cl.h>
00002
00003 static void clRawLoadLight(const CLlight* light);
00004 static void clRawLoadMaterial(const CLmaterial* material);
00005 static void clRawSetupTexture(const CLtexture* texture);
00006 static void clRawLoadTexture(const CLtexture* texture);
00007 static void clRawRenderPrimitiveSet(const CLprimitiveset* primitiveset);
00008 static void clRawRenderMesh(const CLmesh* mesh);
00009 static void clRawRenderMeshVisible(const CLmesh* mesh,
00010 const bool** flags);
00011
00012 static void clRawLoadLight(const CLlight* light)
00013 {
00014
00015 glLightfv(light->id, GL_AMBIENT, (GLfloat*)&light->ambient);
00016 glLightfv(light->id, GL_DIFFUSE, (GLfloat*)&light->diffuse);
00017 glLightfv(light->id, GL_SPECULAR, (GLfloat*)&light->specular);
00018 glLightfv(light->id, GL_POSITION, (GLfloat*)&light->position);
00019 glLightfv(light->id, GL_SPOT_DIRECTION, (GLfloat*)&light->spot_direction);
00020 glLightfv(light->id, GL_SPOT_EXPONENT, &light->spot_exponent);
00021 glLightfv(light->id, GL_SPOT_CUTOFF, &light->spot_cutoff);
00022 glLightfv(light->id, GL_CONSTANT_ATTENUATION, &light->constant_attenuation);
00023 glLightfv(light->id, GL_LINEAR_ATTENUATION, &light->linear_attenuation);
00024 glLightfv(light->id, GL_QUADRATIC_ATTENUATION,
00025 &light->quadratic_attenuation);
00026 }
00027
00028 static void clRawLoadMaterial(const CLmaterial* material)
00029 {
00030
00031 glMaterialfv(material->face, GL_AMBIENT, (GLfloat*)&material->ambient);
00032 glMaterialfv(material->face, GL_DIFFUSE, (GLfloat*)&material->diffuse);
00033 glMaterialfv(material->face, GL_SPECULAR, (GLfloat*)&material->specular);
00034 glMaterialfv(material->face, GL_EMISSION, (GLfloat*)&material->emission);
00035 glMaterialf(material->face, GL_SHININESS, material->shininess);
00036 }
00037
00038 static void clRawSetupTexture(const CLtexture* texture)
00039 {
00040 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00041 }
00042
00043 static void clRawLoadTexture(const CLtexture* texture)
00044 {
00045
00046 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texture->min_filter);
00047 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texture->mag_filter);
00048
00049
00050 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, texture->wrap_s);
00051 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, texture->wrap_t);
00052
00053
00054 if ((texture->min_filter == GL_NEAREST) ||
00055 (texture->min_filter == GL_LINEAR))
00056
00057 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
00058 texture->image.width, texture->image.height, 0,
00059 texture->image.format, texture->image.type,
00060 texture->image.data);
00061 else
00062
00063 gluBuild2DMipmaps (GL_TEXTURE_2D, GL_RGBA,
00064 texture->image.width, texture->image.height,
00065 texture->image.format, texture->image.type,
00066 texture->image.data);
00067 }
00068
00069 static void clRawSetupMesh(const CLmesh* mesh)
00070 {
00071 if (clIsEnabled(CL_VERTICES) && (mesh->vertices))
00072 {
00073 glEnableClientState(GL_VERTEX_ARRAY);
00074 glVertexPointer(3, GL_FLOAT, 0, mesh->vertices);
00075 }
00076 else
00077 glDisableClientState(GL_VERTEX_ARRAY);
00078
00079 if (clIsEnabled(CL_COLOURS) && (mesh->colours))
00080 {
00081 glEnableClientState(GL_COLOR_ARRAY);
00082 glColorPointer(4, GL_FLOAT, 0, mesh->colours);
00083 }
00084 else
00085 glDisableClientState(GL_COLOR_ARRAY);
00086
00087 if (clIsEnabled(CL_NORMALS) && (mesh->normals))
00088 {
00089 glEnableClientState(GL_NORMAL_ARRAY);
00090 glNormalPointer(GL_FLOAT, 0, mesh->normals);
00091 }
00092 else
00093 glDisableClientState(GL_NORMAL_ARRAY);
00094
00095 if (clIsEnabled(CL_TEXCOORDS) && (mesh->texcoords))
00096 {
00097 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00098 glTexCoordPointer(2, GL_FLOAT, 0, mesh->texcoords);
00099 }
00100 else
00101 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
00102
00103 if (clIsEnabled(CL_EDGEFLAGS) && (mesh->edgeflags))
00104 {
00105 glEnableClientState(GL_EDGE_FLAG_ARRAY);
00106 glEdgeFlagPointer(0, mesh->edgeflags);
00107 }
00108 else
00109 glDisableClientState(GL_EDGE_FLAG_ARRAY);
00110 }
00111
00112 static void clRawRenderPrimitiveSet(const CLprimitiveset* primitiveset)
00113 {
00114 glDrawElements(primitiveset->mode, primitiveset->num_indices,
00115 GL_UNSIGNED_INT, primitiveset->indices);
00116 }
00117
00118 static void clRawRenderMesh(const CLmesh* mesh)
00119 {
00120 unsigned int i;
00121
00122
00123 glPushAttrib(GL_CURRENT_BIT);
00124
00125 if (clIsEnabled(CL_COLOUR) && (mesh->colour))
00126 glColor4fv((GLfloat*)mesh->colour);
00127
00128 if (clIsEnabled(CL_MATERIAL) && (mesh->material_index != -1))
00129 clLoadMaterial(mesh->context->materials[mesh->material_index]);
00130
00131 if (clIsEnabled(CL_TEXTURE))
00132 {
00133 if (mesh->texture_index != -1)
00134 clLoadTexture(mesh->context->textures[mesh->texture_index]);
00135
00136 if (clIsEnabled(CL_TEXTURE_ENV_MODE))
00137 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mesh->texture_env_mode);
00138 }
00139
00140
00141 for (i = 0; i < mesh->num_primitivesets; i++)
00142 clRawRenderPrimitiveSet(mesh->primitivesets[i]);
00143
00144 glPopAttrib();
00145 }
00146
00147 static void clRawRenderMeshVisible(const CLmesh* mesh, const bool** flags)
00148 {
00149
00150 glPushAttrib(GL_CURRENT_BIT);
00151
00152 if (clIsEnabled(CL_COLOUR) && (mesh->colour))
00153 glColor4fv((GLfloat*)mesh->colour);
00154
00155 if (clIsEnabled(CL_MATERIAL) && (mesh->material_index != -1))
00156 clLoadMaterial(mesh->context->materials[mesh->material_index]);
00157
00158 if (clIsEnabled(CL_TEXTURE))
00159 {
00160 if (mesh->texture_index != -1)
00161 clLoadTexture(mesh->context->textures[mesh->texture_index]);
00162
00163 if (clIsEnabled(CL_TEXTURE_ENV_MODE))
00164 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mesh->texture_env_mode);
00165 }
00166
00167
00168 {
00169 CLprimitiveset* set = 0;
00170 GLuint* indices = 0;
00171 const bool* flag = 0;
00172 unsigned int offset = 0;
00173 unsigned int i = 0;
00174 unsigned int j = 0;
00175
00176 for (i = 0 ; i < mesh->num_primitivesets ; i++)
00177 {
00178 set = mesh->primitivesets[i];
00179 indices = set->indices;
00180 flag = flags[i];
00181
00182 switch(set->mode)
00183 {
00184 case GL_POINTS:
00185 offset = 1;
00186 break;
00187
00188 case GL_LINES:
00189 offset = 2;
00190 break;
00191
00192 case GL_LINE_STRIP:
00193 case GL_LINE_LOOP:
00194 offset = 1;
00195 break;
00196
00197 case GL_TRIANGLES:
00198 offset = 3;
00199 break;
00200
00201 case GL_TRIANGLE_STRIP:
00202 case GL_TRIANGLE_FAN:
00203 offset = 1;
00204 break;
00205
00206 case GL_QUADS:
00207 offset = 4;
00208 break;
00209
00210 case GL_QUAD_STRIP:
00211 offset = 1;
00212 break;
00213
00214 case GL_POLYGON:
00215
00216 default:
00217 offset = -1;
00218 break;
00219 }
00220
00221 if (offset == -1)
00222 {
00223 if (flag[j])
00224 glDrawElements(set->mode, set->num_indices, GL_UNSIGNED_INT, indices);
00225 }
00226 else
00227 {
00228 unsigned int num_primitives = set->num_indices / offset;
00229 for (j = 0; j < num_primitives; j++)
00230 {
00231 if (flag[j])
00232 glDrawElements(set->mode, offset, GL_UNSIGNED_INT, indices);
00233 indices += offset;
00234 }
00235 }
00236 }
00237 }
00238 glPopAttrib();
00239 }
00240
00244 void clDrawImage(const CLimage* const image)
00245 {
00246
00247 glDrawPixels(image->width,
00248 image->height,
00249 image->format,
00250 image->type,
00251 image->data);
00252 }
00253
00254 void clUpdateLight(CLlight* light)
00255 {
00256
00257 if (clIsEnabled(CL_LIGHT_DISPLAY_LIST))
00258 {
00259
00260 if (!light->display_list)
00261 light->display_list = glGenLists(1);
00262
00263
00264 glNewList(light->display_list, GL_COMPILE);
00265 clRawLoadLight(light);
00266 glEndList();
00267 }
00268 else
00269 {
00270
00271 glDeleteLists(light->display_list, 1);
00272
00273
00274 light->display_list = 0;
00275 }
00276 }
00277
00278 void clUpdateMaterial(CLmaterial* material)
00279 {
00280
00281 if (clIsEnabled(CL_MATERIAL_DISPLAY_LIST))
00282 {
00283
00284 if (!material->display_list)
00285 material->display_list = glGenLists(1);
00286
00287
00288 glNewList(material->display_list, GL_COMPILE);
00289 clRawLoadMaterial(material);
00290 glEndList();
00291 }
00292 else
00293 {
00294
00295 glDeleteLists(material->display_list, 1);
00296
00297
00298 material->display_list = 0;
00299 }
00300 }
00301
00302 void clUpdateTexture(CLtexture* texture)
00303 {
00304
00305 if (clIsEnabled(CL_TEXTURE_OBJECT))
00306 {
00307
00308 if (texture->texture_object == 0)
00309 glGenTextures(1, &texture->texture_object);
00310
00311
00312 glBindTexture(GL_TEXTURE_2D, texture->texture_object);
00313
00314 glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
00315 clRawSetupTexture(texture);
00316 clRawLoadTexture(texture);
00317 glPopClientAttrib();
00318 }
00319 else
00320 {
00321
00322 glDeleteTextures(1, &texture->texture_object);
00323
00324
00325 texture->texture_object = 0;
00326 }
00327 }
00328
00329 void clUpdateMesh(CLmesh* mesh)
00330 {
00331 if (clIsEnabled(CL_MESH_DISPLAY_LIST))
00332 {
00333 if (mesh->display_list == 0)
00334 mesh->display_list = glGenLists(1);
00335
00336 glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
00337 clRawSetupMesh(mesh);
00338
00339 glNewList(mesh->display_list, GL_COMPILE);
00340 clRawRenderMesh(mesh);
00341 glEndList();
00342
00343 glPopClientAttrib();
00344 }
00345 else
00346 {
00347 glDeleteLists(mesh->display_list, 1);
00348 mesh->display_list = 0;
00349 }
00350 }
00351
00353 void clUpdateModel(CLmodel* model)
00354 {
00355 unsigned int i;
00356
00357 for (i = 0; i < model->num_meshes; i++)
00358 {
00359 clUpdateMesh(model->meshes[i]);
00360 }
00361 }
00362
00364 void clUpdateContext(CLcontext* context)
00365 {
00366 unsigned int i;
00367
00368 for (i = 0; i < context->num_materials; i++)
00369 {
00370 clUpdateMaterial(context->materials[i]);
00371 }
00372
00373 for (i = 0; i < context->num_textures; i++)
00374 {
00375 clUpdateTexture(context->textures[i]);
00376 }
00377
00378 for (i = 0; i < context->num_lights; i++)
00379 {
00380 clUpdateLight(context->lights[i]);
00381 }
00382
00383 for (i = 0; i < context->num_models; i++)
00384 {
00385 clUpdateModel(context->models[i]);
00386 }
00387 }
00388
00389 void clLoadLight(const CLlight* light)
00390 {
00391
00392 if (light->display_list)
00393 {
00394 glCallList(light->display_list);
00395 }
00396 else
00397 {
00398 clRawLoadLight(light);
00399 }
00400 }
00401
00402 void clLoadMaterial(const CLmaterial* material)
00403 {
00404
00405 if (material->display_list)
00406 {
00407 glCallList(material->display_list);
00408 }
00409 else
00410 {
00411 clRawLoadMaterial(material);
00412 }
00413 }
00414
00415 void clLoadTexture(const CLtexture* texture)
00416 {
00417
00418 if (texture->texture_object)
00419 {
00420 glBindTexture(GL_TEXTURE_2D, texture->texture_object);
00421 }
00422 else
00423 {
00424
00425 glBindTexture(GL_TEXTURE_2D, texture->texture_object);
00426
00427 glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
00428 clRawSetupTexture(texture);
00429 clRawLoadTexture(texture);
00430 glPopClientAttrib();
00431 }
00432 }
00433
00434 void clRenderMesh(const CLmesh* mesh)
00435 {
00436
00437 if (mesh->display_list)
00438 {
00439 glCallList(mesh->display_list);
00440 }
00441 else
00442 {
00443 glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
00444 clRawSetupMesh(mesh);
00445 clRawRenderMesh(mesh);
00446 glPopClientAttrib();
00447 }
00448 }
00449
00450
00451 void clRenderMeshVisible(const CLmesh* mesh, const bool** flags)
00452 {
00453 glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
00454 clRawSetupMesh(mesh);
00455 clRawRenderMeshVisible(mesh, flags);
00456 glPopClientAttrib();
00457 }
00458
00459
00460 void clRenderModel(const CLmodel* model)
00461 {
00462 unsigned int i;
00463
00464 for (i = 0; i < model->num_meshes; i++)
00465 clRenderMesh(model->meshes[i]);
00466 }