📄 surf.java
字号:
if (surf.visframe != r_framecount) continue; if ( (surf.flags & Defines.SURF_PLANEBACK) != sidebit ) continue; // wrong side if ((surf.texinfo.flags & Defines.SURF_SKY) != 0) { // just adds to visible sky bounds R_AddSkySurface(surf); } else if ((surf.texinfo.flags & (Defines.SURF_TRANS33 | Defines.SURF_TRANS66)) != 0) { // add to the translucent chain surf.texturechain = r_alpha_surfaces; r_alpha_surfaces = surf; } else { if ( qglMTexCoord2fSGIS && ( surf.flags & Defines.SURF_DRAWTURB) == 0 ) { GL_RenderLightmappedPoly( surf ); } else { // the polygon is visible, so add it to the texture // sorted chain // FIXME: this is a hack for animation image = R_TextureAnimation(surf.texinfo); surf.texturechain = image.texturechain; image.texturechain = surf; } } } // recurse down the back side R_RecursiveWorldNode(node.children[1 - side]); } /* ============= R_DrawWorld ============= */ void R_DrawWorld() { entity_t ent = new entity_t(); // auto cycle the world frame for texture animation ent.frame = (int)(r_newrefdef.time*2); currententity = ent; if (r_drawworld.value == 0) return; if ( (r_newrefdef.rdflags & Defines.RDF_NOWORLDMODEL) != 0 ) return; currentmodel = r_worldmodel; Math3D.VectorCopy(r_newrefdef.vieworg, modelorg); gl_state.currenttextures[0] = gl_state.currenttextures[1] = -1; gl.glColor3f (1,1,1); // memset (gl_lms.lightmap_surfaces, 0, sizeof(gl_lms.lightmap_surfaces)); gl_lms.clearLightmapSurfaces(); R_ClearSkyBox(); if ( qglMTexCoord2fSGIS ) { GL_EnableMultitexture( true ); GL_SelectTexture( GL_TEXTURE0); GL_TexEnv( GL.GL_REPLACE ); GL_SelectTexture( GL_TEXTURE1); if ( gl_lightmap.value != 0) GL_TexEnv( GL.GL_REPLACE ); else GL_TexEnv( GL.GL_MODULATE ); R_RecursiveWorldNode(r_worldmodel.nodes[0]); // root node GL_EnableMultitexture( false ); } else { R_RecursiveWorldNode(r_worldmodel.nodes[0]); // root node } /* ** theoretically nothing should happen in the next two functions ** if multitexture is enabled */ DrawTextureChains(); R_BlendLightmaps(); R_DrawSkyBox(); R_DrawTriangleOutlines(); } byte[] fatvis = new byte[Defines.MAX_MAP_LEAFS / 8]; /* =============== R_MarkLeaves Mark the leaves and nodes that are in the PVS for the current cluster =============== */ void R_MarkLeaves() { byte[] vis; //byte[] fatvis = new byte[Defines.MAX_MAP_LEAFS / 8]; Arrays.fill(fatvis, (byte)0); mnode_t node; int i, c; mleaf_t leaf; int cluster; if (r_oldviewcluster == r_viewcluster && r_oldviewcluster2 == r_viewcluster2 && r_novis.value == 0 && r_viewcluster != -1) return; // development aid to let you run around and see exactly where // the pvs ends if (gl_lockpvs.value != 0) return; r_visframecount++; r_oldviewcluster = r_viewcluster; r_oldviewcluster2 = r_viewcluster2; if (r_novis.value != 0 || r_viewcluster == -1 || r_worldmodel.vis == null) { // mark everything for (i=0 ; i<r_worldmodel.numleafs ; i++) r_worldmodel.leafs[i].visframe = r_visframecount; for (i=0 ; i<r_worldmodel.numnodes ; i++) r_worldmodel.nodes[i].visframe = r_visframecount; return; } vis = Mod_ClusterPVS(r_viewcluster, r_worldmodel); // may have to combine two clusters because of solid water boundaries if (r_viewcluster2 != r_viewcluster) { // memcpy (fatvis, vis, (r_worldmodel.numleafs+7)/8); System.arraycopy(vis, 0, fatvis, 0, (r_worldmodel.numleafs+7) / 8); vis = Mod_ClusterPVS(r_viewcluster2, r_worldmodel); c = (r_worldmodel.numleafs + 31) / 32; int k = 0; for (i=0 ; i<c ; i++) { fatvis[k] |= vis[k++]; fatvis[k] |= vis[k++]; fatvis[k] |= vis[k++]; fatvis[k] |= vis[k++]; } vis = fatvis; } for ( i=0; i < r_worldmodel.numleafs; i++) { leaf = r_worldmodel.leafs[i]; cluster = leaf.cluster; if (cluster == -1) continue; if (((vis[cluster>>3] & 0xFF) & (1 << (cluster & 7))) != 0) { node = (mnode_t)leaf; do { if (node.visframe == r_visframecount) break; node.visframe = r_visframecount; node = node.parent; } while (node != null); } } } /* ============================================================================= LIGHTMAP ALLOCATION ============================================================================= */ void LM_InitBlock() { Arrays.fill(gl_lms.allocated, 0); } void LM_UploadBlock( boolean dynamic ) { int texture; int height = 0; if ( dynamic ) { texture = 0; } else { texture = gl_lms.current_lightmap_texture; } GL_Bind( gl_state.lightmap_textures + texture ); gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); if ( dynamic ) { int i; for ( i = 0; i < BLOCK_WIDTH; i++ ) { if ( gl_lms.allocated[i] > height ) height = gl_lms.allocated[i]; } gl.glTexSubImage2D( GL.GL_TEXTURE_2D, 0, 0, 0, BLOCK_WIDTH, height, GL_LIGHTMAP_FORMAT, GL.GL_UNSIGNED_BYTE, gl_lms.lightmap_buffer ); } else { gl.glTexImage2D( GL.GL_TEXTURE_2D, 0, gl_lms.internal_format, BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_LIGHTMAP_FORMAT, GL.GL_UNSIGNED_BYTE, gl_lms.lightmap_buffer ); if ( ++gl_lms.current_lightmap_texture == MAX_LIGHTMAPS ) Com.Error( Defines.ERR_DROP, "LM_UploadBlock() - MAX_LIGHTMAPS exceeded\n" ); //debugLightmap(gl_lms.lightmap_buffer, 128, 128, 4); } } // returns a texture number and the position inside it boolean LM_AllocBlock (int w, int h, pos_t pos) { int x = pos.x; int y = pos.y; int i, j; int best, best2; best = BLOCK_HEIGHT; for (i=0 ; i<BLOCK_WIDTH-w ; i++) { best2 = 0; for (j=0 ; j<w ; j++) { if (gl_lms.allocated[i+j] >= best) break; if (gl_lms.allocated[i+j] > best2) best2 = gl_lms.allocated[i+j]; } if (j == w) { // this is a valid spot pos.x = x = i; pos.y = y = best = best2; } } if (best + h > BLOCK_HEIGHT) return false; for (i=0 ; i<w ; i++) gl_lms.allocated[x + i] = best + h; return true; } /* ================ GL_BuildPolygonFromSurface ================ */ void GL_BuildPolygonFromSurface(msurface_t fa) { int i, lindex, lnumverts; medge_t[] pedges; medge_t r_pedge; int vertpage; float[] vec; float s, t; glpoly_t poly; float[] total = {0, 0, 0}; // reconstruct the polygon pedges = currentmodel.edges; lnumverts = fa.numedges; vertpage = 0; Math3D.VectorClear(total); // // draw texture // // poly = Hunk_Alloc (sizeof(glpoly_t) + (lnumverts-4) * VERTEXSIZE*sizeof(float)); poly = Polygon.create(lnumverts); poly.next = fa.polys; poly.flags = fa.flags; fa.polys = poly; for (i=0 ; i<lnumverts ; i++) { lindex = currentmodel.surfedges[fa.firstedge + i]; if (lindex > 0) { r_pedge = pedges[lindex]; vec = currentmodel.vertexes[r_pedge.v[0]].position; } else { r_pedge = pedges[-lindex]; vec = currentmodel.vertexes[r_pedge.v[1]].position; } s = Math3D.DotProduct (vec, fa.texinfo.vecs[0]) + fa.texinfo.vecs[0][3]; s /= fa.texinfo.image.width; t = Math3D.DotProduct (vec, fa.texinfo.vecs[1]) + fa.texinfo.vecs[1][3]; t /= fa.texinfo.image.height; Math3D.VectorAdd (total, vec, total); //Math3D.VectorCopy (vec, poly.verts[i]); poly.x(i, vec[0]); poly.y(i, vec[1]); poly.z(i, vec[2]); //poly.verts[i][3] = s; //poly.verts[i][4] = t; poly.s1(i, s); poly.t1(i, t); // // lightmap texture coordinates // s = Math3D.DotProduct (vec, fa.texinfo.vecs[0]) + fa.texinfo.vecs[0][3]; s -= fa.texturemins[0]; s += fa.light_s*16; s += 8; s /= BLOCK_WIDTH*16; //fa.texinfo.texture.width; t = Math3D.DotProduct (vec, fa.texinfo.vecs[1]) + fa.texinfo.vecs[1][3]; t -= fa.texturemins[1]; t += fa.light_t*16; t += 8; t /= BLOCK_HEIGHT*16; //fa.texinfo.texture.height; //poly.verts[i][5] = s; //poly.verts[i][6] = t; poly.s2(i, s); poly.t2(i, t); } } /* ======================== GL_CreateSurfaceLightmap ======================== */ void GL_CreateSurfaceLightmap(msurface_t surf) { int smax, tmax; IntBuffer base; if ( (surf.flags & (Defines.SURF_DRAWSKY | Defines.SURF_DRAWTURB)) != 0) return; smax = (surf.extents[0]>>4)+1; tmax = (surf.extents[1]>>4)+1; pos_t lightPos = new pos_t(surf.light_s, surf.light_t); if ( !LM_AllocBlock( smax, tmax, lightPos ) ) { LM_UploadBlock( false ); LM_InitBlock(); lightPos = new pos_t(surf.light_s, surf.light_t); if ( !LM_AllocBlock( smax, tmax, lightPos ) ) { Com.Error( Defines.ERR_FATAL, "Consecutive calls to LM_AllocBlock(" + smax +"," + tmax +") failed\n"); } } // kopiere die koordinaten zurueck surf.light_s = lightPos.x; surf.light_t = lightPos.y; surf.lightmaptexturenum = gl_lms.current_lightmap_texture; int basep = (surf.light_t * BLOCK_WIDTH + surf.light_s);// * LIGHTMAP_BYTES; base = gl_lms.lightmap_buffer; base.position(basep); R_SetCacheState( surf ); R_BuildLightMap(surf, base.slice(), BLOCK_WIDTH); } lightstyle_t[] lightstyles; /* ================== GL_BeginBuildingLightmaps ================== */ void GL_BeginBuildingLightmaps(model_t m) { // static lightstyle_t lightstyles[MAX_LIGHTSTYLES]; int i; int[] dummy = new int[128*128]; // init lightstyles if ( lightstyles == null ) { lightstyles = new lightstyle_t[Defines.MAX_LIGHTSTYLES]; for (i = 0; i < lightstyles.length; i++) { lightstyles[i] = new lightstyle_t(); } } // memset( gl_lms.allocated, 0, sizeof(gl_lms.allocated) ); Arrays.fill(gl_lms.allocated, 0); r_framecount = 1; // no dlightcache GL_EnableMultitexture( true ); GL_SelectTexture( GL_TEXTURE1); /* ** setup the base lightstyles so the lightmaps won't have to be regenerated ** the first time they're seen */ for (i=0 ; i < Defines.MAX_LIGHTSTYLES ; i++) { lightstyles[i].rgb[0] = 1; lightstyles[i].rgb[1] = 1; lightstyles[i].rgb[2] = 1; lightstyles[i].white = 3; } r_newrefdef.lightstyles = lightstyles; if (gl_state.lightmap_textures == 0) { gl_state.lightmap_textures = TEXNUM_LIGHTMAPS; } gl_lms.current_lightmap_texture = 1; /* ** if mono lightmaps are enabled and we want to use alpha ** blending (a,1-a) then we're likely running on a 3DLabs ** Permedia2. In a perfect world we'd use a GL_ALPHA lightmap ** in order to conserve space and maximize bandwidth, however ** this isn't a perfect world. ** ** So we have to use alpha lightmaps, but stored in GL_RGBA format, ** which means we only get 1/16th the color resolution we should when ** using alpha lightmaps. If we find another board that supports ** only alpha lightmaps but that can at least support the GL_ALPHA ** format then we should change this code to use real alpha maps. */ char format = gl_monolightmap.string.toUpperCase().charAt(0); if ( format == 'A' ) { gl_lms.internal_format = gl_tex_alpha_format; } /* ** try to do hacked colored lighting with a blended texture */ else if ( format == 'C' ) { gl_lms.internal_format = gl_tex_alpha_format; } else if ( format == 'I' ) { gl_lms.internal_format = GL.GL_INTENSITY8; } else if ( format == 'L' ) { gl_lms.internal_format = GL.GL_LUMINANCE8; } else { gl_lms.internal_format = gl_tex_solid_format; } /* ** initialize the dynamic lightmap texture */ GL_Bind( gl_state.lightmap_textures + 0 ); gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); gl.glTexImage2D( GL.GL_TEXTURE_2D, 0, gl_lms.internal_format, BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_LIGHTMAP_FORMAT, GL.GL_UNSIGNED_BYTE, dummy ); } /* ======================= GL_EndBuildingLightmaps ======================= */ void GL_EndBuildingLightmaps() { LM_UploadBlock( false ); GL_EnableMultitexture( false ); } //ImageFrame frame; // void debugLightmap(byte[] buf, int w, int h, float scale) {// IntBuffer pix = ByteBuffer.wrap(buf).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();// // int[] pixel = new int[w * h];// // pix.get(pixel);// // BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR);// image.setRGB(0, 0, w, h, pixel, 0, w);// AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(scale, scale), AffineTransformOp.TYPE_NEAREST_NEIGHBOR);// BufferedImage tmp = op.filter(image, null);// // if (frame == null) {// frame = new ImageFrame(null);// frame.show();// } // frame.showImage(tmp);// // }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -