/* virtual */ MStatus pnTriangles::bind(const MDrawRequest& request, M3dView& view) // // Description: // This bind demonstrates the usage of internal material // and texture properties. This shader must be connected // to the "hardwareShader" attribute of a lambert derived // shader. // { // Setup the view view.beginGL(); glPushAttrib( GL_ALL_ATTRIB_BITS ); glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); MColor diffuse(1.0F, 1.0F, 0.0F, 1.0F); MColor specular(1.0F, 1.0F, 1.0F, 1.0F); MColor emission(0.0F, 0.0F, 0.0F, 1.0F); MColor ambient(0.2F, 0.2F, 0.2F, 1.0F); // Get the diffuse and specular colors // float shininess; bool hasTransparency = false; MMaterial material = request.material(); fInTexturedMode = material.materialIsTextured(); // Setting this to true will get the default "green" material back // since it will try and evaluate this shader, which internally // Maya does not understand -> thus giving the "green" material back bool useInternalMaterialSetting = false; if (!useInternalMaterialSetting) { material.getEmission( emission ); material.getSpecular( specular ); shininess = 13.0; } material.getHasTransparency( hasTransparency ); if (!fInTexturedMode) { if (!fTestVertexProgram && !useInternalMaterialSetting) material.getDiffuse( diffuse ); } // In textured mode. Diffuse material is always white // for texture blends else { if (!useInternalMaterialSetting) diffuse.r = diffuse.g = diffuse.b = diffuse.a = 1.0; } // Use a vertex program to set up shading // if (fTestVertexProgram) { bindVertexProgram(diffuse, specular, emission, ambient); } else if (fTestFragmentProgram) { bindFragmentProgram(); } // Don't use a vertex program to set up shading // else { // Set up the material state // glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT); glColor4fv(&ambient.r); if (fInTexturedMode) { glEnable( GL_TEXTURE_2D ); MDrawData drawData = request.drawData(); material.applyTexture( view, drawData ); float scaleS, scaleT, translateS, translateT, rotate; material.getTextureTransformation(scaleS, scaleT, translateS, translateT, rotate); rotate = DEG_TO_RAD(-rotate); float c = cosf(rotate); float s = sinf(rotate); translateS += ((c+s)/2.0F); translateT += ((c-s)/2.0F); glMatrixMode(GL_TEXTURE); glPushMatrix(); glLoadIdentity(); if(scaleS != 1.0f || scaleT != 1.0f) glScalef(1.0f/scaleS, 1.0f/scaleT, 1.0f); if(translateS != 0.0f || translateT != 0.0f) glTranslatef(0.5f-translateS, 0.5f-translateT, 0.0f); else glTranslatef(0.5f, 0.5f, 0.0f); if(rotate != 0.0f) glRotatef(-rotate, 0.0f, 0.0f, 1.0f); glMatrixMode(GL_MODELVIEW); } if (!useInternalMaterialSetting) { glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glColor4fv(&diffuse.r); glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); glColor4fv(&specular.r); glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION); glColor4fv(&emission.r); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess); } else { const MDagPath dagPath = request.multiPath(); material.evaluateMaterial( view, dagPath ); material.setMaterial(dagPath, hasTransparency); } } // Do PN triangles in hardware, or do nothing // if LOD = 0 if (fExtensionSupported[kPNTriangesEXT] || (fSubdivisions == 0)) { if (fSubdivisions != 0) { glEnable( GL_PN_TRIANGLES_ATI ); // Set point mode // if (fPointMode == kPointLinear) glPNTrianglesiATI( GL_PN_TRIANGLES_POINT_MODE_ATI, GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI); else glPNTrianglesiATI( GL_PN_TRIANGLES_POINT_MODE_ATI, GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI); // Set normal mode // if (fNormalMode == kNormalLinear) glPNTrianglesiATI( GL_PN_TRIANGLES_NORMAL_MODE_ATI, GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI); else glPNTrianglesiATI( GL_PN_TRIANGLES_NORMAL_MODE_ATI, GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI); // Set tessellation level // glPNTrianglesiATI( GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI, fSubdivisions ); } } view.endGL(); return MS::kSuccess; }
void R_DrawAliasModel(entity_t *e) { extern void AddFire(vec3_t org, float size); int lnum; vec3_t dist; float add; model_t *clmodel; vec3_t mins, maxs; aliashdr_t *paliashdr; float an; //s, t, int anim; md2_t *pheader; // LH / muff int shell; //QMB :model shells //not implemented yet // byte c, *color; //QMB :color map //does the model need a shell? if (cl.items & IT_QUAD && e == &cl.viewent) shell = true; else shell = false; //set get the model from the e clmodel = e->model; //work out its max and mins VectorAdd(e->origin, clmodel->mins, mins); VectorAdd(e->origin, clmodel->maxs, maxs); //make sure its in screen if (R_CullBox(mins, maxs) && e != &cl.viewent) return; //QMB: FIXME //should use a particle emitter linked to the model for its org //needs to be linked when the model is created and distroyed when //the entity is distroyed //check if its a fire and add the particle effect if (!strcmp(clmodel->name, "progs/flame.mdl")) AddFire(e->origin, 4); if (!strcmp(clmodel->name, "progs/flame2.mdl")) { AddFire(e->origin, 10); return; //do not draw the big fire model, its just a place holder for the particles } // get lighting information //QMB: FIXME //SHOULD CHANGE TO A PASSED VAR //get vertex normals (for lighting and shells) shadedots = r_avertexnormal_dots[((int) (e->angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)]; //make a default lighting direction an = e->angles[1] / 180 * M_PI; shadevector[0] = cos(-an); shadevector[1] = sin(-an); shadevector[2] = 1; //e->angles[0]; VectorNormalize(shadevector); //get the light for the model R_LightPoint(e->origin); // LordHavoc: lightcolor is all that matters from this //work out lighting from the dynamic lights for (lnum = 0; lnum < MAX_DLIGHTS; lnum++) { //if the light is alive if (cl_dlights[lnum].die >= cl.time) { //work out the distance to the light VectorSubtract(e->origin, cl_dlights[lnum].origin, dist); add = cl_dlights[lnum].radius - VectorLength(dist); //if its close enough add light from it if (add > 0) { lightcolor[0] += add * cl_dlights[lnum].colour[0]; lightcolor[1] += add * cl_dlights[lnum].colour[1]; lightcolor[2] += add * cl_dlights[lnum].colour[2]; } } } //scale lighting to floating point VectorScale(lightcolor, 1.0f / 200.0f, lightcolor); // locate the proper data glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); if (gl_n_patches && gl_npatches.getBool()) { glEnable(GL_PN_TRIANGLES_ATI); glPNTrianglesiATI(GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI, gl_npatches.getInt()); if (true) glPNTrianglesiATI(GL_PN_TRIANGLES_POINT_MODE_ATI, GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI); else glPNTrianglesiATI(GL_PN_TRIANGLES_POINT_MODE_ATI, GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI); if (true) glPNTrianglesiATI(GL_PN_TRIANGLES_NORMAL_MODE_ATI, GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI); else glPNTrianglesiATI(GL_PN_TRIANGLES_NORMAL_MODE_ATI, GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI); } if (clmodel->aliastype == MD3IDHEADER) { //do nothing for testing if (!r_modeltexture.getBool()) { GL_DisableTMU(GL_TEXTURE0_ARB); }//disable texture if needed R_DrawQ3Model(e, false, false); if (!r_modeltexture.getBool()) { GL_EnableTMU(GL_TEXTURE0_ARB); }//enable texture if needed if (r_celshading.getBool() || r_outline.getBool()) { glCullFace(GL_BACK); glEnable(GL_BLEND); glPolygonMode(GL_FRONT, GL_LINE); if (e == &cl.viewent) { glLineWidth(1.0f); } else { glLineWidth(5.0f); } glEnable(GL_LINE_SMOOTH); GL_DisableTMU(GL_TEXTURE0_ARB); glColor3f(0.0, 0.0, 0.0); R_DrawQ3Model(e, false, true); glColor3f(1.0, 1.0, 1.0); GL_EnableTMU(GL_TEXTURE0_ARB); glPolygonMode(GL_FRONT, GL_FILL); glDisable(GL_BLEND); glCullFace(GL_FRONT); } if (shell) { glBindTexture(GL_TEXTURE_2D, quadtexture); glColor4f(1.0, 1.0, 1.0, 0.5); glEnable(GL_BLEND); R_DrawQ3Model(e, true, false); glDisable(GL_BLEND); glColor3f(1.0, 1.0, 1.0); } } else if (clmodel->aliastype != ALIASTYPE_MD2) { paliashdr = (aliashdr_t *) Mod_Extradata(e->model); c_alias_polys += paliashdr->numtris; glPushMatrix(); //interpolate unless its the viewmodel if (e != &cl.viewent) R_BlendedRotateForEntity(e); else R_RotateForEntity(e); glTranslatef(paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2]); glScalef(paliashdr->scale[0], paliashdr->scale[1], paliashdr->scale[2]); anim = (int) (cl.time * 10) & 3; glBindTexture(GL_TEXTURE_2D, paliashdr->gl_texturenum[e->skinnum][anim]); // draw all the triangles if (!r_modeltexture.getBool()) { GL_DisableTMU(GL_TEXTURE0_ARB); } else { //highlighting test code if (0 && gl_textureunits > 2) { GL_EnableTMU(GL_TEXTURE1_ARB); glBindTexture(GL_TEXTURE_2D, TextureManager::highlighttexture); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); //need correct mode glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD); glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 1.0); //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD); } } glColor3fv(lightcolor); R_SetupAliasBlendedFrame(e->frame, paliashdr, e, false, false); glDisable(GL_TEXTURE_1D); if (r_celshading.getBool() || r_outline.getBool()) { glColor3f(0.0, 0.0, 0.0); R_SetupAliasBlendedFrame(e->frame, paliashdr, e, false, true); glColor3f(1.0, 1.0, 1.0); } if (!r_modeltexture.getBool()) { GL_EnableTMU(GL_TEXTURE0_ARB); } else { if (0 && gl_textureunits > 2) { //highlighting test code glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); GL_DisableTMU(GL_TEXTURE1_ARB); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } } glActiveTexture(GL_TEXTURE0_ARB); //colour map code... not working yet... /* if (e->colormap != vid.colormap && !gl_nocolors.value) { if (paliashdr->gl_texturenumColorMap&&paliashdr->gl_texturenumColorMap){ glBindTexture(GL_TEXTURE_2D,paliashdr->gl_texturenumColorMap); c = (byte)e->colormap & 0xF0; c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges color = (byte *) (&d_8to24table[c]); //glColor3fv(color); glColor3f(1.0,1.0,1.0); } }*/ if (shell) { glBindTexture(GL_TEXTURE_2D, quadtexture); glColor4f(1.0, 1.0, 1.0, 0.5); glEnable(GL_BLEND); R_SetupAliasBlendedFrame(e->frame, paliashdr, e, true, false); glDisable(GL_BLEND); glColor3f(1.0, 1.0, 1.0); } glPopMatrix(); } else { pheader = (md2_t *) Mod_Extradata(e->model); c_alias_polys += pheader->num_tris; glBindTexture(GL_TEXTURE_2D, pheader->gl_texturenum[e->skinnum]); R_SetupQ2AliasFrame(e, pheader); } if (gl_n_patches && gl_npatches.getBool()) { glDisable(GL_PN_TRIANGLES_ATI); } glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); }