Jump to content
  • Advertisement
Sign in to follow this  
coderWalker

OpenGL GLSL 3d Tilemap

This topic is 2626 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a block world that is composed of chunks.
Each chunk is 16x16x16 voxels.
I have been drawing in immediate mode, as the code below shows.

However now I am trying to convert to OpenGL 3.1.
I have got alot working and I can draw a chunk on screen without ANY deprecated functions at all.
(Finally, YAY!)

However the problem is now drawing the world.
The world is 25x25x25 Chunks.
Before I would just translate to the chunks position and then draw.

The question is how to do this most effeciently in GLSL?

I have each chunk stored in a VBO.
I mean can I use 3 nested For loops to draw the VBO's somehow?

Right now I'm passing the verticies and tex coords to the Program like normal.

This is just like a tilemap, however it's 3d, and each Position has a unique VBO as opposed to a reference.

Anyone have any ideas?

Thanks in advance, Walker

Old technique:

for (int iChunkY=0+DEPTH;iChunkY<CLIPDIST-DEPTH;iChunkY++)
{
for (int iChunkX=0+DEPTH;iChunkX<CLIPDIST-DEPTH;iChunkX++)
{
for (int iChunkZ=0+DEPTH;iChunkZ<CLIPDIST-DEPTH;iChunkZ++)
{
if (chunkExists[iChunkX][iChunkY][iChunkZ]==true)
{
if (Chunk[iChunkX][iChunkY][iChunkZ]->vertexBuffer.size()!=0)
Chunk[iChunkX][iChunkY][iChunkZ]->renderDraw(iChunkX*16,iChunkY*16,iChunkZ*16);
}
}
}
}
void chunk::renderDraw(float x, float y, float z)
{
if (vertexBuffer.size()!=0)
{
glPushMatrix();
glTranslatef(x,y,z);
glVertexPointer(3, GL_INT, 0, &vertexBuffer[0]);
glTexCoordPointer(2, GL_FLOAT, 0, &textureBuffer[0]);
//Draw
glDrawArrays(GL_QUADS, 0, vertexBuffer.size()*4);
glPopMatrix();
}
}

Share this post


Link to post
Share on other sites
Advertisement
If your chunks all have the same geometry they should all use the same VBO.
You are using vertex arrays.
Switching from vertex arrays to VBO’s is trivial, and any tutorial can guide you.

What exactly is your problem? Nothing is rendering?


L. Spiro

Share this post


Link to post
Share on other sites
Basically I want to be able to draw a 3d Voxel terrain like this:
MinecraftLandscape.png

Which worked perfect before, however I'm now switching to OpenGL 3.1, for the speed so I can increase draw distance.

Proof it worked before:
bug5.png

What I'm getting now:
openGL3_1.PNG

When I rendered before,
The world is divided into Chunks (16x16x16 voxels) and I would render each chunk to a vertexArray. (x,y,z from 0-16)
Then when drawing I would just Translate to that chunks current position and then draw it.

However the problem is with OpenGL 3.1 there is no translate.
Meaning like above when I draw the VBO's they draw on top of each other, which makes sense, considering all their verticies are from 0 to 16.

So now the question is, what is the best way to do this?
Should I continue to make the mesh and somehow translate them?
or
Is there a better way to send the 3d array to the GPU and it compute the mesh and render it?
(the world really is just a 3d array with ID's representing what texture coordinates to apply to the block)

I am using VBO's, the code in the first post is labeled "Old code"
I want to use no deprecated functions (for OpenGL 3.1)

The current code is this:

world.v.cpp
#version 140

uniform float rot;
uniform float aspect;

in vec3 in_vertex;
in vec2 in_coord;

out vec2 out_coord;

void main()
{
float time = rot*3.14/180.0f;

mat3 window = mat3(
vec3(aspect, 0.0, 0.0),
vec3( 0.0, 1.0, 0.0),
vec3( 0.0, 0.0, 1.0)
);
mat3 scale = mat3(
vec3(0.02, 0.0, 0.0),
vec3( 0.0, 0.02, 0.0),
vec3( 0.0, 0.0, 0.02)
);
mat3 yRot= mat3(
vec3( cos(time), 0.0, sin(time) ),
vec3( 0.0, 1.0, 0.0 ),
vec3( -sin(time), 0.0, cos(time) )
);

gl_Position = vec4(in_vertex*yRot*scale*window,1.0);
//gl_Position = vec4(in_vertex,1.0);

out_coord = in_coord;
}

world.f.cpp


#version 140

in vec2 out_coord;
out vec4 MyFragColor;

uniform sampler2D tex[2];

void main()
{
MyFragColor = texture2D(tex[0], out_coord);
}


all the VBO's are just passed to this.

Anyone have any ideas?

Thanks in advance,
CoderWalker

Share this post


Link to post
Share on other sites

However the problem is with OpenGL 3.1 there is no translate.
[/quote]

This seems to be the source of your troubles. In OGL 3 you can still rotate, translate and scale, but you have to do it yourself.

In OGL1 there were a few predefined matrix attributes in the vertex programs like the modelview matrix and the projection matrix alongside whatever custom attributes you chose to add. With OGL3 these predefined attributes were removed, so there are only the custom ones left. What you have to do in OGL3 is add your own custom modelview projection matrix as an attribute to the shader which you set up and bind yourself.

Share this post


Link to post
Share on other sites
all that the later gl versions did was off-load the responsibility for matrix manipulations onto the user. Somebody still has to do it. you could try looking at third source libraries like GLM or CML to do some of that for you.

Look at glUniformMatrix

Share this post


Link to post
Share on other sites
Are you saying there is no GLSL way to do this?

I mean if I'm going to use functions that do the same thing as the deprecated ones, I mind as well use the deprecated ones.

I just wanted to make a really fast way to draw this.

Should I make uniforms for the positions and change them when drawing?

There has to be a way to do this without using deprecated or like deprecated funcions.

Thanks again,

any Ideas welcome!

Walker

Share this post


Link to post
Share on other sites
The way to set a transform matrix in non-deprecated GL is through the use of glUniformMatrix, as an earlier poster indicated. And yes, your functions to construct the transform matrices are probably going to look a lot like the deprecated ones. No, switching to non-deprecated doesn't automagically make your drawing super fast.. If it wasn't fast in deprecated GL, it probably won't be fast in non-deprecated GL.

Deprecated doesn't necessarily mean everything that old GL was doing is obsolete. In regards to matrix manipulations and transforms, it just means that someone else (you) has the responsibility of performing those manipulations. GL just changed the way things were done internally, that's all. The "old" way of having a projection, a modelview, and a texture matrix "slot" was clunky and not reflective of real-world usage once shaders came onto the scene. So now, a matrix is just another parameter passed to a shader via uniform, and to simplify the API, GL will no longer provide utility functions to assist in constructing the matrix.

So, yes, you can make uniforms of the positions and change them while drawing. If your chunks don't rotate or scale, then passing a full 4x4 matrix is not necessary. Passing only the X, Y and Z translations is perfectly viable. For each chunk drawn, set the positions as uniforms, and in the vertex shader add those translations to the vertex being processed.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!