clrender.c

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     /* load light values into OpenGL */
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     /* load material values into OpenGL */
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); /* not sure if this is required! */
00041 }
00042 
00043 static void clRawLoadTexture(const CLtexture* texture)
00044 {
00045     /* set texture filtering parameters */
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     /* set texture wrapping parameters */
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     /* if texture filtering does not require mipmaps */
00054     if ((texture->min_filter == GL_NEAREST) || 
00055         (texture->min_filter == GL_LINEAR))
00056         /* load it normally */
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 /* if the texture does require mipmaps */
00062         /* use GLU to generate mipmaps */
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     /* push attribs we may affect */
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     /* render primitives */
00141     for (i = 0; i < mesh->num_primitivesets; i++) 
00142         clRawRenderPrimitiveSet(mesh->primitivesets[i]);
00143     
00144     glPopAttrib(); /* GL_CURRENT_BIT */
00145 }
00146 
00147 static void clRawRenderMeshVisible(const CLmesh* mesh, const bool** flags)
00148 {
00149     /* push attribs we may affect */
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     /* actually render stuff */
00168     {
00169         CLprimitiveset*   set = 0;          /* current primitive set pointer */
00170         GLuint*           indices = 0;      /* current index pointer */
00171         const bool*       flag = 0;         /* current flags pointer */
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(); /* GL_CURRENT_BIT */
00239 }
00240 
00244 void clDrawImage(const CLimage* const image)
00245 {
00246     /* does nothing yet!? */
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     /* if light display lists are enabled */
00257     if (clIsEnabled(CL_LIGHT_DISPLAY_LIST))
00258     {
00259         /* get new list id (if necessary) */
00260         if (!light->display_list)
00261             light->display_list = glGenLists(1);
00262         
00263         /* create new list */
00264         glNewList(light->display_list, GL_COMPILE);
00265         clRawLoadLight(light);
00266         glEndList(); /* will overwrite old list */
00267     }
00268     else /* if light display lists are not enabled */
00269     {
00270         /* delete list */
00271         glDeleteLists(light->display_list, 1);
00272         
00273         /* list zero is reserved for no list */
00274         light->display_list = 0;
00275     }
00276 }
00277 
00278 void clUpdateMaterial(CLmaterial* material)
00279 {
00280     /* if light display lists are enabled */
00281     if (clIsEnabled(CL_MATERIAL_DISPLAY_LIST))
00282     {
00283         /* get new list id (if necessary) */
00284         if (!material->display_list)
00285             material->display_list = glGenLists(1);
00286         
00287         /* create new list */
00288         glNewList(material->display_list, GL_COMPILE);
00289         clRawLoadMaterial(material);
00290         glEndList();
00291     }
00292     else /* if material display lists are not enabled */
00293     {
00294         /* delete list */
00295         glDeleteLists(material->display_list, 1);
00296         
00297         /* list zero is reserved for no list */
00298         material->display_list = 0;
00299     }   
00300 }
00301 
00302 void clUpdateTexture(CLtexture* texture)
00303 {
00304     /* if texture objects are enabled */
00305     if (clIsEnabled(CL_TEXTURE_OBJECT))
00306     {
00307         /* get new texture object (if necessary) */
00308         if (texture->texture_object == 0)
00309             glGenTextures(1, &texture->texture_object);
00310         
00311         /* bind and load texture */
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 /* if texture objects are not enabled */
00320     {
00321         /* delete texture object */
00322         glDeleteTextures(1, &texture->texture_object);
00323         
00324         /* texture object zero is reserved for no texture object */
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); /* set client vertex arrays */
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     /* if there is a display list, use it */
00392     if (light->display_list)
00393     {
00394         glCallList(light->display_list);
00395     }
00396     else /* load the light from client memory */
00397     {
00398         clRawLoadLight(light);
00399     }
00400 }
00401 
00402 void clLoadMaterial(const CLmaterial* material)
00403 {
00404   /* if there is a display list, use it */
00405     if (material->display_list)
00406     {
00407         glCallList(material->display_list);
00408     }
00409     else /* load the material from client memory */
00410     {
00411         clRawLoadMaterial(material);
00412     }
00413 }
00414 
00415 void clLoadTexture(const CLtexture* texture)
00416 {
00417     /* if there is a texture object, use it */
00418     if (texture->texture_object)
00419     {
00420         glBindTexture(GL_TEXTURE_2D, texture->texture_object);
00421     }
00422     else /* load the texture from client memory */
00423     {
00424         /* bind and load texture */
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     /* if there is a display list, use it */
00437     if (mesh->display_list)
00438     {   
00439         glCallList(mesh->display_list);
00440     }
00441     else /* else, preserve vertex array setting and render */
00442     {
00443         glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
00444         clRawSetupMesh(mesh);
00445         clRawRenderMesh(mesh);
00446         glPopClientAttrib();
00447     }
00448 }
00449 
00450 /* flags is a pointer to n visibility arrays, where n == mesh->num_primitivesets */
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 /* render all meshes */
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 }

Generated on Thu Dec 27 13:53:41 2007 for CL by  doxygen 1.4.6