привет, решил переписать пример с gameDev.net и вроде все окей, переписал, сетка создалась верная, НО при движении камеры, Лоды не ходят за камерой, а остаются от центра, то есть в центре максимальный ЛОД ну и дальше от центра идет хуже и хуже, не зависимо от того где камера !!!
в коде карта высот не используется на данный момент, то есть сетка генерируеться с высотой в любом месте = 0, для того что бы разобраться в проблеме !
собственно вот код
-(void)Init
{
glActiveTexture(GL_TEXTURE0);
unsigned char HeightMap[m_iSize*m_iSize];
float fHeightMap[m_iSize*m_iSize];
[self LoadTerrain:"/WorkSource/cocoaWork/3dEngine Quat+pos/Models/Terrain.raw" nSize:(m_iSize * m_iSize) pHeightMap:&HeightMap];
//7 Then i have to convert it to float to be able to send it to the vertex shader
int size = m_iSize;
int z,x;
for ( z = 0; z < size; z++)
{
for (x = 0; x < size; x++)
{
fHeightMap[x+z*(int)size] = (float)(HeightMap[(x+z*(int)m_iSize)]/100000.0f);
}
}
// Bind the texture
[self RGBA_BindFPTexture:fHeightMap size:size level:&TextureMap];
// Set the block size
DefaultSize = 63;
// ________________
// _RING FIX______R|
// |MB|MB|H|MB|MB|I|
// |__|__|B|__|__|N|
// |MB| |MB|G|
// |__| |__|F|
// |VB| |VB|I|
// |MB| |MB|X|
// |__| |__| |
// |MB|MB|H|MB|MB| |
// |__|__|B|__|__| |
//MB = MainBlock
//VB/HB = BlockFix
// Init blocks
glGenBuffers(1, &vTerrain);
glBindBuffer(GL_ARRAY_BUFFER, vTerrain);
glBufferData(GL_ARRAY_BUFFER, 4000000, 0, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glGenBuffers(1, &iTerrain);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iTerrain);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4000000, 0, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
oTerrainV = 0; oTerrainI = 0;
[self InitBlock:&MainBlock width:DefaultSize heigth:DefaultSize];
[self InitBlock:&HorizontalBlockFix width:DefaultSize heigth:2.0f];
[self InitBlock:&VerticalBlockFix width:2.0f heigth:DefaultSize];
[self InitBlock:&HorizontalFix width:2*DefaultSize+1.0f heigth:1.0f];
[self InitBlock:&VerticalFix width:1.0f heigth:2*DefaultSize+1.0f];
[self InitBlock:&HorizontalRingFix width:DefaultSize*2+1.0f heigth:1.0f];
[self InitBlock:&VerticalRingFix width:1.0f heigth:DefaultSize*2+2.0f];
// Degenerates
Degenerate.Height = DefaultSize*4+2.0f;
Degenerate.Width = DefaultSize*4+2.0f;
[self CreateDegenerateBlockDL];
TerrainS = [Load createShaders:"/downloads/anim/Models/Monsters/Stalker/GTerrain.fs"
vertexPath:"/downloads/anim/Models/Monsters/Stalker/GTerrain.vs"];
/*
uniform vec4 ScaleFactor;
uniform vec4 FineBlockOrig;
uniform vec2 ViewerPos;
uniform vec2 AlphaOffset;
uniform vec2 Width;
uniform sampler2D heightmap;
*/
GT_ScaleFactor = glGetUniformLocation( TerrainS, "ScaleFactor" );
GT_FineBlockOrig = glGetUniformLocation( TerrainS, "FineBlockOrig" );
GT_ViewerPos = glGetUniformLocation( TerrainS, "ViewerPos" );
GT_AlphaOffset = glGetUniformLocation( TerrainS, "AlphaOffset" );
GT_Width = glGetUniformLocation( TerrainS, "Width" );
GT_heightmap = glGetUniformLocation( TerrainS, "heightmap" );
GT_a_position = glGetAttribLocation ( TerrainS, "a_position");
GT_mvpMatrix = glGetUniformLocation( TerrainS, "mvpMatrix" );
}
// Binds float texture with FLOAT32 so taht the texture shader can access it
-(void)RGBA_BindFPTexture:(float*)Data size:(int)size level:(unsigned int*)level
{
glGenTextures(1, level);
glBindTexture(GL_TEXTURE_2D, *level);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA_FLOAT32_ATI, size, size, 0, GL_ALPHA, GL_FLOAT, Data );
}
// Loads terrain from 16bit raw file
-(void)LoadTerrain:(char *)strName nSize:(int)nSize pHeightMap:(Byte *)pHeightMap
{
FILE *pFile = NULL;
pFile = fopen( strName, "rb" );
if ( pFile == NULL )
{
return;
}
fread( pHeightMap, 1, nSize, pFile );
fclose(pFile);
}
-(int)max:(float)a b:(float)b
{
return a < b ? b : a;
}
-(int)min:(float)a b:(float)b
{
return a < b ? a : b;
}
-(void)Render
{
//camera->testing
cx = Camera_m_Position.x;
cz = Camera_m_Position.z;
// Sets the detai lelvel based on height a level is only rendered if its size is larger than 2.5 the cameras height over a vertexs height in the ring
if( DefaultSize*4*pow(2,HeightScale-1.0f) < (Camera_m_Position.y-0*0.005f)*2.5f)
{
HeightScale =[self min:7.0f b:HeightScale+1.0f];
}
else if( DefaultSize*4*pow(2,HeightScale-2.0f) > (Camera_m_Position.y-0*0.005f)*2.5f)
{
HeightScale = [self max:1.0f b:HeightScale-1.0f];
}
glUseProgram(TerrainS);
glBindTexture ( GL_TEXTURE_2D, TextureMap );
// Renders the inner default
[self RenderDefault:cx z:cz];
// Renders ring around default
int n;
for (n = 0; n < 6 - HeightScale+1.0f; n++)
{
[self RenderLevel:cx z:cz level:n];
}
glUseProgram(0);
}
// Renders a level
-(void)RenderLevel:(float)x z:(float)z level:(float)Level
{
float scale = pow(2, Level)*pow(2,HeightScale-1.0f);
int blocksize = (MainBlock.Width-1.0f)*scale;
float x3 = (x/(scale*2.0f))*scale*2.0f;
float z3 = (z/(scale*2.0f))*scale*2.0f;
float x1 = x3-2*blocksize;
float z1 = z3-2*blocksize;
float sx3 = (x/(scale))*scale;
float sz3 = (z/(scale))*scale;
//-(void)RenderBlock:(float)x z:(float)z scale:(float)scale CurBlock:(Block*)CurBlock
if(Level != 0)
{
if (x3 == sx3 && z3 != sz3 )
{
[self RenderBlock:(x1+blocksize) z:(z1+blocksize) scale:scale CurBlock:&HorizontalRingFix];
[self RenderBlock:(x1+3*blocksize+scale) z:(z1+blocksize) scale:scale CurBlock:&VerticalRingFix];
}
else if (x3 != sx3 && z3 != sz3 )
{
[self RenderBlock:(x1+blocksize+scale) z:(z1+blocksize) scale:scale CurBlock:&HorizontalRingFix];
[self RenderBlock:(x1+blocksize) z:(z1+blocksize) scale:scale CurBlock:&VerticalRingFix];
}
else if (x3 != sx3 && z3 == sz3 )
{
[self RenderBlock:(x1+blocksize+scale) z:(z1+3*blocksize+scale) scale:scale CurBlock:&HorizontalRingFix];
[self RenderBlock:(x1+blocksize) z:(z1+blocksize) scale:scale CurBlock:&VerticalRingFix];
}
else if (x3 == sx3 && z3 == sz3 )
{
[self RenderBlock:(x1+blocksize) z:(z1+3*blocksize+scale) scale:scale CurBlock:&HorizontalRingFix];
[self RenderBlock:(x1+3*blocksize+scale) z:(z1+blocksize) scale:scale CurBlock:&VerticalRingFix];
}
}
[self RenderBlock:(x1-scale) z:(z1) scale:scale CurBlock:&Degenerate];
float x2, z2;
[self RenderBlock:(x1+2*blocksize) z:(z1) scale:scale CurBlock:&VerticalBlockFix];
[self RenderBlock:(x1) z:(z1+2*blocksize) scale:scale CurBlock:&HorizontalBlockFix];
[self RenderBlock:(x1+2*blocksize) z:(z1+3*blocksize+2*scale) scale:scale CurBlock:&VerticalBlockFix];
[self RenderBlock:(x1+3*blocksize+2*scale) z:(z1+2*blocksize) scale:scale CurBlock:&HorizontalBlockFix];
x2 = x1;
z2 = z1;
[self RenderMainBlock:(x2) z:(z2) scale:scale CurBlock:&MainBlock];
[self RenderMainBlock:(x2+blocksize) z:(z2) scale:scale CurBlock:&MainBlock];
[self RenderMainBlock:(x2) z:(z2+blocksize) scale:scale CurBlock:&MainBlock];
x2 = x1+2*blocksize+2*scale;
z2 = z1;
[self RenderMainBlock:(x2) z:(z2) scale:scale CurBlock:&MainBlock];
[self RenderMainBlock:(x2+blocksize) z:(z2) scale:scale CurBlock:&MainBlock];
[self RenderMainBlock:(x2+blocksize) z:(z2+blocksize) scale:scale CurBlock:&MainBlock];
x2 = x1+2*blocksize+2*scale;
z2 = z1+2*blocksize+2*scale;
[self RenderMainBlock:(x2+blocksize) z:(z2) scale:scale CurBlock:&MainBlock];
[self RenderMainBlock:(x2+blocksize) z:(z2+blocksize) scale:scale CurBlock:&MainBlock];
[self RenderMainBlock:(x2) z:(z2+blocksize) scale:scale CurBlock:&MainBlock];
x2 = x1;
z2 = z1+2*blocksize+2*scale;
[self RenderMainBlock:(x2) z:(z2) scale:scale CurBlock:&MainBlock];
[self RenderMainBlock:(x2) z:(z2+blocksize) scale:scale CurBlock:&MainBlock];
[self RenderMainBlock:(x2+blocksize) z:(z2+blocksize) scale:scale CurBlock:&MainBlock];
}вторая часть
-(void)RenderBlock:(float)x z:(float)z scale:(float)scale CurBlock:(Block*)CurBlock
{
/*
uniform vec4 ScaleFactor;
uniform vec4 FineBlockOrig;
uniform vec2 ViewerPos;
uniform vec2 AlphaOffset;
uniform vec2 Width;
uniform sampler2D heightmap;
*/
glUniform2f(GT_ViewerPos, Camera_m_Position.x, Camera_m_Position.z);
glUniform2f(GT_Width, CurBlock->Width*scale*4.0f+2.0f*scale, CurBlock->Height*scale*4.0f+2.0f*scale);
glUniform4f(GT_ScaleFactor, scale, scale, x, z);
glUniform1f(GT_heightmap,0);
glUniform4f(GT_FineBlockOrig, 1.0f/m_iSize, 1.0f/m_iSize, (x-100000.0f+m_iSize/2)/m_iSize, (z-100000.0f+m_iSize/2)/m_iSize);
glUniformMatrix4fv(GT_mvpMatrix, 1, FALSE, &mvpMatrix.m[0][0]);
glBindBuffer(GL_ARRAY_BUFFER, vTerrain);
glVertexAttribPointer(GT_a_position,2,GL_FLOAT,GL_FALSE, sizeof (STVertex), offsetof (STVertex, pos)+CurBlock->oVert);
glEnableVertexAttribArray ( GT_a_position );
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iTerrain);
glDrawElements(GL_LINES, CurBlock->nindc, GL_UNSIGNED_SHORT, CurBlock->oIndc);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
-(void)RenderMainBlock:(float)x z:(float)z scale:(float)scale CurBlock:(Block*)CurBlock
{
if([iFrustrum SphereInFrustum:x+CurBlock->Width*scale*0.5 y:0 z:z+CurBlock->Width*scale*0.5 radius:CurBlock->Width*scale*0.5*1.4])
{
glUniform2f(GT_ViewerPos, Camera_m_Position.x, Camera_m_Position.z);
glUniform4f(GT_ScaleFactor, scale, scale, x, z);
glUniform1f(GT_heightmap,0);
glUniform4f(GT_FineBlockOrig, 1.0f/m_iSize, 1.0f/m_iSize, (x+m_iSize/2)/m_iSize, (z+m_iSize/2)/m_iSize);
glUniformMatrix4fv(GT_mvpMatrix, 1, FALSE, &mvpMatrix.m[0][0]);
glBindBuffer(GL_ARRAY_BUFFER, vTerrain);
glVertexAttribPointer(GT_a_position,2,GL_FLOAT,GL_FALSE, sizeof (STVertex), offsetof (STVertex, pos)+CurBlock->oVert);
glEnableVertexAttribArray ( GT_a_position );
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iTerrain);
glDrawElements(GL_LINES, CurBlock->nindc, GL_UNSIGNED_SHORT, CurBlock->oIndc);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
}
-(void)RenderDefault:(float)x z:(float)z
{
float scale = pow(2,HeightScale-1.0f);
int blocksize = (MainBlock.Width-1.0f)*scale;
x = (x/(scale*2.0f))*2.0f*scale+scale;
z = (z/(scale*2.0f))*2.0f*scale+scale;
[self RenderBlock:(x) z: (z) scale:scale CurBlock:&MainBlock];
[self RenderBlock:(x-blocksize) z:(z) scale:scale CurBlock:&MainBlock];
[self RenderBlock:(x-blocksize) z:(z-blocksize) scale:scale CurBlock:&MainBlock];
[self RenderBlock:(x) z:(z-blocksize) scale:scale CurBlock:&MainBlock];
[self RenderBlock:(x-blocksize-scale) z:(z-blocksize-scale) scale:scale CurBlock:&HorizontalFix];
[self RenderBlock:(x-blocksize) z:(z+blocksize) scale:scale CurBlock:&HorizontalFix];
[self RenderBlock:(x-blocksize-scale) z:(z-blocksize) scale:scale CurBlock:&VerticalFix];
[self RenderBlock:(x+blocksize) z:(z-blocksize-scale) scale:scale CurBlock:&VerticalFix];
}
-(void)InitBlock:(Block*)CurBlock width:(float)width heigth:(float)heigth
{
CurBlock->Height = heigth+1.0f;
CurBlock->Width = width+1.0f;
[self CreateBlockDL:CurBlock];
}
// Im using Displaylists but vertex buffers works fine
-(void)CreateBlockDL:(Block*)CurBlock
{
//GL_TRIANGLE_STRIP
int x,z,i;
Vertex = (STVertex*)malloc(sizeof(STVertex));
Triangl = (STTriangl*)malloc(sizeof(STTriangl));
nV = 0;
for ( z = 0; z < CurBlock->Height-1; z++)
{
for ( x = 0; x < CurBlock->Width; x++)
{
if (x == 0 && z != 0)
{
[self RenderVertex3s:x z:z];
}
[self RenderVertex3s:x z:z];
[self RenderVertex3s:x z:z+1];
if (x == CurBlock->Width-1 && z != CurBlock->Height-2)
{
[self RenderVertex3s:x z:z+1];
}
}
}
Triangl = realloc(Triangl, nV*sizeof(STTriangl));
for (i=0;i<nV;i++){
Triangl[i].i = i;
}
glBindBuffer(GL_ARRAY_BUFFER, vTerrain);
glBufferSubData(GL_ARRAY_BUFFER, oTerrainV, nV*sizeof(STVertex), Vertex);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iTerrain);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, oTerrainI, nV*sizeof(STTriangl), Triangl);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
CurBlock->oVert = oTerrainV;
CurBlock->oIndc = oTerrainI;
CurBlock->nindc = nV;
oTerrainV+=nV*sizeof(STVertex);
oTerrainI+=nV*sizeof(STTriangl);
free(Vertex);
Vertex = NULL;
free(Triangl);
Triangl = NULL;
nV = 0;
}
-(void)RenderVertex3s:(int)x z:(int)z
{
Vertex[nV].pos.x = x;Vertex[nV].pos.z = z;
Vertex = realloc(Vertex, (nV+2)*sizeof(STVertex));
nV++;
}
-(void)CreateDegenerateBlockDL
{
float size = DefaultSize*4+1.0f;
nV = 0;
int x,z;
//(GL_TRIANGLES);
Vertex = (STVertex*)malloc(sizeof(STVertex));
Triangl = (STTriangl*)malloc(sizeof(STTriangl));
nV = 0;
x = 1;
for (z = 0; z < size; z+=2)
{
[self RenderVertex3s:x z:z];
[self RenderVertex3s:x z:z+2];
[self RenderVertex3s:x z:z];
[self RenderVertex3s:x z:z];
[self RenderVertex3s:x z:z+2];
[self RenderVertex3s:x z:z+1];
[self RenderVertex3s:x z:z+1];
[self RenderVertex3s:x z:z+2];
[self RenderVertex3s:x z:z+2];
}
x = size+2;
for (z = 0; z < size; z+=2)
{
[self RenderVertex3s:x z:z];
[self RenderVertex3s:x z:z+2];
[self RenderVertex3s:x z:z];
[self RenderVertex3s:x z:z+1];;
[self RenderVertex3s:x z:z+2];
[self RenderVertex3s:x z:z];
[self RenderVertex3s:x z:z+2];
[self RenderVertex3s:x z:z+2];
[self RenderVertex3s:x z:z+1];
}
z = 0;
for (x = 1; x < size+1; x+=2)
{
[self RenderVertex3s:x z:z];
[self RenderVertex3s:x+2 z:z];
[self RenderVertex3s:x z:z];
[self RenderVertex3s:x z:z];
[self RenderVertex3s:x+1 z:z];
[self RenderVertex3s:x+2 z:z];
[self RenderVertex3s:x+1 z:z];
[self RenderVertex3s:x+2 z:z];
[self RenderVertex3s:x+2 z:z];
}
z = size+1;
for (x = 1; x < size+1; x+=2)
{
[self RenderVertex3s:x z:z];
[self RenderVertex3s:x z:z];
[self RenderVertex3s:x+2 z:z];
[self RenderVertex3s:x z:z];
[self RenderVertex3s:x+2 z:z];
[self RenderVertex3s:x+1 z:z];
[self RenderVertex3s:x+1 z:z];
[self RenderVertex3s:x+2 z:z];
[self RenderVertex3s:x+2 z:z];
}
glBindBuffer(GL_ARRAY_BUFFER, vTerrain);
glBufferSubData(GL_ARRAY_BUFFER, oTerrainV, nV*sizeof(STVertex), Vertex);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iTerrain);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, oTerrainI, nV*sizeof(STTriangl), Triangl);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
Degenerate.oVert = oTerrainV;
Degenerate.oIndc = oTerrainI;
Degenerate.nindc = nV;
oTerrainV+=nV*sizeof(STVertex);
oTerrainI+=nV*sizeof(STTriangl);
free(Vertex);
Vertex = NULL;
free(Triangl);
Triangl = NULL;
nV = 0;
}шейдер
uniform vec4 ScaleFactor;
uniform vec4 FineBlockOrig;
uniform vec2 ViewerPos;
uniform mat4 mvpMatrix;
uniform vec2 AlphaOffset;
uniform vec2 Width;
uniform sampler2D heightmap;
attribute vec2 a_position;
varying vec2 uv;
varying vec2 alpha;
void main()
{
vec2 Gridpos = a_position;
vec2 WorldPos = Gridpos * ScaleFactor.xy + ScaleFactor.zw;
vec4 newVertexPos = vec4(WorldPos.x, 0, WorldPos.y, 1.0);
gl_Position = mvpMatrix * newVertexPos ;
}Жесть. И ты думаешь, что кто-то будет твой код в таких количествах разбирать?

да на самом деле код дикий знаю ! просто расчитываю на
а ) кто то хорошо знаком с GCM и одним взглядом на рендер может что то посоветовать
б ) просто кто то кинет свою реализацию на GLSL и я у себя найду ошибку !
на самом деле нужный код не много места занимает ... я просто привел весь чтоб если что была полная инфа ))))))
PS блин, на месяц свалил ,уже наверно давно бы сделал (((((, ат черт щас наверняка придет slava и побашке мне даст ^^ ну не так хорошо я знаю енгл, чтоб по пайперу написать нормальный GCM ((((
все работает это у меня руки кривые сорри !
криво работает но суть есть дальше уже думаю сам разберусь !
I
Зато самое главное дал другим готовую реализацию, которую надо допилит или не надо :)
ты знаешь, посмотрел тока на твой шейдер.... вижу что передаешь карту высот (uniform sampler2D heightmap;), но не вижу где ты выборку делаешь из нее... ???
должно быть ченить типо того:
vec4 newVertexPos = vec4(WorldPos.x, texture2D( heightmap, vtexCoords ).x , WorldPos.z, 1.0); // если ты текстуры как флоат создавал то во всех компонентах (x или y или z) одно и тоже значение будет
gl_Position = mvpMatrix * newVertexPos ;
вообще я не видел че за клипмап тут на форуме, но тру клипмап описан в гпу-гем 2, http://research.microsoft.com/en-us/um/people/hoppe/gpugcm.pdf
Тема в архиве.