Code archives/3D Graphics - Mesh/Mesh LoadTerrain
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
This function is exactly like the LoadTerrain command in blitz, except it uses a blitz mesh instead of a blitz terrain. There's no LOD, but it should be alot faster in many circumstances. Same syntax as the Blitz function. Also centres the mesh, unlike the original function. EDIT<<< I have redone this routine, as it had many errors and inaccurate workings: - It will now properly apply the heightmap without a strange seem appearing. - I have added the functionality to adjust the Y scale. - You can load three textures, and state flags, and they will be applied. - The UV mapping has been fixed now. - The function returns the mesh back, which i don't think it did before? Global terrain = load_terrain("heightmap.bmp",0.5); load the terrain half scale (since Red pixel colours highest value is 255, the highest value will now be 128.) To load a texture and apply it to the terrain. Global terrain = load_terrain("heightmap.bmp",0.5,"terrain_texture.bmp",1+16+32); load the terrain, and apply a texture, with the clamping flags and colour flag. Note, you must clamp the texture if it encompasses the whole mesh, or it's edges will bleed to the other side. | |||||
; Y position is calculated by: scale * pixel colour on loaded image. ; PLEASE NOTE: You must clamp the texture your applying if it is spread across the whole mesh. ; If you don't, it will bleed across to the opposite side. Clamp with flags 16 + 32 Function load_terrain(heightmap$,y_scale#=1,texture1$="",t_flag1 = 1,texture2$="",t_flag2 = 1,texture3$="",t_flag3 = 1) temp = LoadImage(heightmap$) If temp = 0 Then Return 0 x = ImageWidth(temp) DebugLog(" image width = "+x) y = ImageHeight(temp) mesh = CreateMesh() surf = CreateSurface(mesh) For ly = 0 To y-1 ; your doing -1 because the image pixels start at 1 and the vertex ; indices start at 0 For lx = 0 To x-1 AddVertex surf,lx , 0, -ly, Float(lx)/(x-1), Float(ly)/(y-1) Next Next RenderWorld AddTriangle surf, 0, 65,64 AddTriangle surf, 0, 1 ,65 For ly = 0 To y-2 For lx = 0 To x-2 ; leave the vertex counting an extra unit short, as the code below reaches ; reaches one unit ahead to create the triangles ; below is to simply explain the creation process and order of the triangles. ; Triangles must be created in clockwise order, facing the camera, to be seen. current_y = ly*y next_y = (ly+1)*y current_x = lx next_x = lx+1 ;create the quad AddTriangle surf, current_y+current_x, next_y+next_x , next_y + current_x AddTriangle surf, current_y+current_x, current_y+next_x , next_y + next_x Next Next PositionMesh mesh, -x/2.0,0,y/2.0 ; centre the mesh on the world axis. SetBuffer ImageBuffer(temp) For ly = 0 To y-1 For lx = 0 To x-1 GetColor lx,ly index = (ly*y) + lx VertexCoords surf, index , VertexX(surf,index), ColorRed()*y_scale, VertexZ(surf,index) Next Next SetBuffer BackBuffer() UpdateNormals mesh If texture1 <> "" Then t1 = LoadTexture(texture1,t_flag1) If t1 = 0 Then RuntimeError(" Error in load_terrain() function: Texture1 not found from filename given") EntityTexture mesh,t1,0,0 End If If texture2 <> "" Then t2 = LoadTexture(texture2,t_flag2) If t2 = 0 Then RuntimeError(" Error in load_terrain() function: Texture2 not found from filename given") EntityTexture mesh,t2,0,1 End If If texture3 <> "" Then t3 = LoadTexture(texture3,t_flag3) If t3 = 0 Then RuntimeError(" Error in load_terrain() function: Texture3 not found from filename given") EntityTexture mesh,t3,0,2 End If Return mesh End Function |
Comments
| ||
Very nice. Very clear. When I have a little time I may extend this further to something like this: Global terrain = load_terrain("heightmap.bmp, texture.bmp,lightmap.bmp") |
| ||
You mean: Global terrain = load_terrain("heightmap.bmp", "texture.bmp", "lightmap.bmp") Function load_terrain(file$, texfile$ = "", lightfile$ = "") ... End Function |
| ||
Yeah, Exactly like that. Your English is fine. Far better than the gibberish that I type most of the time :) Thanks, Allan |
| ||
Well, the texture co-ords are set, so, it should be a doodle to set up :o) |
| ||
Got it working but the texture coords are out of whack. =( |
| ||
It also loads the height map inverted... EDIT: Change this line and it will load the height map correctly. GetColor lx,y-ly Also add this to the end of the function: Return mesh |
| ||
Altered it to:LoadTerrain3( "hmap.bmp","tmap.bmp","lmap.bmp") Now the heightmap is loaded correctly and also the texture coordinates are set. The function automatically scales the texture to fit the terrain. Next on my list for this function is to have it break the terrain up into manageable segments that can be used with PVS and also define the detail level of the terrains so you can cap each segment at say, 500. Function LoadTerrain3(hmap$,tmap$=0,lmap$=0) ; load the heightmap temp = LoadImage(hmap$) If temp = 0 Then RuntimeError "Heightmap image "+hmap$+" does not exist." : Return 0 ; store heightmap dimensions x = ImageWidth(temp) y = ImageHeight(temp) ; load texture and lightmaps tmap = LoadTexture(tmap$) lmap = LoadTexture(lmap$) ; auto scale the textures to the right size If tmap ScaleTexture tmap,x,y If lmap ScaleTexture lmap,x,y ; start building the terrain mesh = CreateMesh() surf = CreateSurface(mesh) ; create some verts for the terrain For ly = 0 To y For lx = 0 To x AddVertex surf,lx,0,ly,1.0/lx,1.0/ly Next Next RenderWorld ; connect the verts with faces For ly = 0 To y-1 For lx = 0 To x-1 AddTriangle surf,lx+((x+1)*ly),lx+((x+1)*ly)+(x+1),(lx+1)+((x+1)*ly) AddTriangle surf,(lx+1)+((x+1)*ly),lx+((x+1)*ly)+(x+1),(lx+1)+((x+1)*ly)+(x+1) Next Next ; position the terrain to center 0,0,0 PositionMesh mesh, -x/2.0,0,-y/2.0 ; alter vertice height to match the heightmap red channel SetBuffer ImageBuffer(temp) For lx = 0 To x For ly = 0 To y GetColor lx,y-ly index = lx + ((x+1)*ly) VertexCoords surf, index , VertexX(surf,index), ColorRed()/20.0,VertexZ(surf,index) ; set the terrain texture coordinates VertexTexCoords surf,index,lx,-ly Next Next SetBuffer BackBuffer() ; update the terrain normals so lighting will look correct UpdateNormals mesh ; apply texture map to index 0 If tmap EntityTexture mesh,tmap,0,0 ; apply lightmap to index 1 with flag 2 If lmap EntityTexture mesh,lmap,0,1 : TextureBlend lmap,2 Return Mesh End Function |
| ||
Hmm...new bug. The far right and bottom vertices aren't effected by the hmap. They stay at 0,0,0 even if the right wall is painted pure white... |
| ||
not sure why but when I try this it crashes on renderworld. |
| ||
Your heightmap is probably too big .. creating too many poly's or verts per surface. I think the limit is 64k verts and 32k polys - higher on some cards. Stevie |
| ||
256 X 256 ? |
| ||
from Chroma: >> The far right and bottom vertices aren't effected by >> the hmap. They stay at 0,0,0 even if the right wall >> is painted pure white... from ckob: >> not sure why but when I try this it crashes on >> renderworld. In an other situation i am haved the same problem. Any vertice from triangle does not exists. Blitz debugger does it nothin register and so it make bugs. You must integrate border-checking. As sample this would be set on a vertice in mesh: ; from: AddTriangle surf,lx+((x+1)*ly),lx+((x+1)*ly)+(x+1),(lx+1)+((x+1)*ly) vertice = lx+((x+1)*ly) So you must test: If lx+((x+1)*ly) > CountVertices(surf) then ... End If ... ... or similarly. On many refers of vertices this would be a long work for(to? sry, my english is bad) testing. |
| ||
128x128, actually... |
| ||
128x128, actually...but the function works AWSOME! thnxs ta big10p 4 finding it 4 me...lol thats how lazy i am p.s. just add ResizeImage temp,128,128 after If temp = 0 Then RuntimeError "Heightmap image "+hmap$+" does not exist." : Return 0 |
| ||
The functions works very good. I wrote a complete tech demo which tiles a given heightmap/colormap into smaller pieces and displays it nearly seamless (there is still a bug with the UV coordinates I couldn't locate). Screenshot Download with Source and Images Source: |
| ||
Moved comments to programming. |
| ||
Need to have another look at this... Thanks for tidying it up though :o) |
| ||
UPDATED! |
| ||
Hey Ross, this is very interesting. I did some stuff a while back (ermm 10 years or so ago) that used Vista and DEM files to create landscapes. It is great to see the type of code necessary to produce such fantastic results, thanks for sharing. |
| ||
Did anyone fix the UV Coordinate glitch yet? I cant seem to find it. |
| ||
? |
| ||
I know u guys proally dont have time to fix it, but here's what i mean by uv coordinate glitch. its some bad geometry. |
| ||
Ok, guys. I have tried & tried to fix ur code, but i still end up where i started. here's my code so far. download the zip provided above to try the code. i added stuff as well. ull need a cloud texture. i will provide it to u. and a sea texture. which i cant provide to you. i say this because my sea texture isnt perfect. |
| ||
Cloud texture: http://www.mediafire.com/download.php?zgmjlieydgl |
| ||
Great demo Drkshadowwing,I'll take a lot at the UV problem but there is a possibility that it might not be fixable since it appears on the limit between two different meshes. As for RossC code, it always gives me a MAV on renderworld()... It's nice to see that B3d can be so great after all these years :) |
| ||
(double post plz delete) |
| ||
[EDITED] Code removed and moved to the appropriate thread there: http://www.blitzbasic.com/Community/posts.php?topic=83668 |
| ||
Remember this isn't a help forum. The code works perfectly fine. If you have trouble with code using my code, please don't post it here :o) |
| ||
Additional here is my own solution, a little bit more code than a single function, its a complete demo (but still based on Ross C's original code). I managed to fix the UV coordinates and use the Terragen File Format as a heightmap base which gives more precision. You can even use Vertex Shadows now because I fixed the chunk normals, too. The Terragen size is irrelevant, the demo will calculate how many tiles are needed and fixes the seams automatically. The colormap texture is stretched across the whole terrain so it should be huge, otherwise you can activate the "vertexcolors" flag but this is not as nice as a colormap. Screenshot: Use Mouse for movement (LMB/RMB = up/down) and these keys: Arrows = Move (5 times fast while holding right SHIFT) C = show/hide chunk seams (otherwise you won't notice any seam) F = fog on/off Q/E = increase/decrease light angle 1...9 = light angle preset between 0° and 180° in 22.5° steps SPACE = wireframe on/off The code is well commented but if you have any questions feel free to ask me. Complete Demo with media (830KB): http://www.christianhart.de/bb/terratiles/terratiles.zip (otherwise you need a custom terragen file, ex. 257x257 size and a matching colormap ex. 1024x1024 pixels) As some of you might have noticed, it is the same island like in this screenshot, yes it could look that nice (i use a quadtree function there but I couldn't manage the Vertex Shadows with it): http://www.blitzbasic.com/gallery/view_pic.php?id=1910 |
| ||
I have a slight fix. Well. I cant get it to work.. But I added it.. Its a few lines that allow for when the sun = 10 degrees (aka 6 am), it adds a day on to the day variable. I know, not useful, but maybe you guys can fix it: |
| ||
Excuse me. NOT a help forum. Stick this somewhere else. Talk about confusing an issue. That's real impressive code, but it's not the right place to post this... I reupdated the code, fixing the UV glitch (which someone isn't seeming to understand...) |
| ||
And I just added my code because it is based and related to Ross' code. The next one will get its own code archive entry. And yes - Darkshadowwing - if you need assistance this is the wrong subforum, post it into "Blitz 3D Programming". This forum here is some kind of showcase where you can improve the code or comment it. |
| ||
Thank you :o) (I really like your extended code btw!) |
| ||
Just wait for the next version. You will LOVE it :-) Here ist a small candy snapshot preview: |
| ||
*Drools* |
Code Archives Forum