Mercavity's picture

Indexed Arrays

I am in the middle of designing a Terrain Editor. I am using indexed vertex arrays. I am havign trouble drawing the 4 X 4 terrain to the screen. Does any one have any suggestions?

// THIS IS THE TERRAIN CLASS. I MAKE AN INSTANCE OF THIS CLASS IN THE MAIN FORM, AND CALL THE RENDER FUNCTION INSIDE THE GL_CONTROL RENDER.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Input;
 
 
namespace RHS_TerrainEditor
{
    public class TerrainData
    {
        /// <summary>
        /// Vertex Coords Array.
        /// </summary>
        private OpenTK.Vector3d[] m_Vertices;
 
        /// <summary>
        /// Normal Array.
        /// </summary>
        private OpenTK.Vector3d[] m_Normals;
 
        /// <summary>
        /// Vertex Color Array.
        /// </summary>
        private OpenTK.Graphics.Color4[] m_Colors;
 
        /// <summary>
        /// Index array of vertex array.
        /// </summary>
        private double[] m_Indices;
 
        /// <summary>
        /// Texture UVs.
        /// </summary>
        private OpenTK.Vector2d m_UVs;
 
        /// <summary>
        /// The total number of triangles used to create the terrain.
        /// </summary>
        private int m_nNumber_O_Triangles;
 
        /// <summary>
        /// The total number of vertices in the terrain.
        /// </summary>
        private int m_nNumber_O_Verts;
 
 
        /// <summary>
        /// TerrainData Constructor
        /// </summary>
        public TerrainData(int _terrainWidth, int _terrainHeight)
        {
            //  Initialize the number of trinagles that is needed to create the terrain.
            m_nNumber_O_Triangles = _terrainWidth * 2 * _terrainHeight;
 
            //  Initialize the number of Verts needed to make the terrain.
            m_nNumber_O_Verts = (_terrainWidth + 1) * (_terrainHeight + 1);
            m_Vertices = new OpenTK.Vector3d[m_nNumber_O_Verts];
            m_Normals = new OpenTK.Vector3d[m_nNumber_O_Verts];
 
            //  Initialize the number of indices we are going to have.
            m_Indices = new double[m_nNumber_O_Triangles * 3];
 
            OpenTK.Vector3d minBounds = new OpenTK.Vector3d(0, 0, 0);
            OpenTK.Vector3d maxBounds = new OpenTK.Vector3d(0, 0, 0);
            OpenTK.Vector3d Position = new OpenTK.Vector3d(minBounds.X, 0, minBounds.Y);   // Set the start position.
            maxBounds.X = _terrainWidth;
            maxBounds.Z = _terrainHeight;
            int Count = 0;
            int numVertsX = _terrainWidth + 1;
            int numVertsZ = _terrainHeight + 1;
            double StepX = (maxBounds.X - minBounds.X) / _terrainWidth;
            double StepZ = (maxBounds.Z - minBounds.Z) / _terrainHeight;
 
            //  Calculate each vertex position.
            for (int z = 0; z < numVertsZ; z++)
            {
                Position.X = minBounds.X;       //  Reset our 'X' position.
                for (int x = 0; x < numVertsX; x++)
                {
                    m_Vertices[Count].X = Position.X;
                    m_Vertices[Count].Z = Position.Z;
                    Position.X += StepX;        //  Increment X across.
                    Count++;
                }
                Position.Z += StepZ;            //  Increment Z across.
            }
 
            //  Initialize each noraml to (0,1,0)
            for (int n = 0; n < m_nNumber_O_Verts; n++)
            {
                m_Normals[n].X = 0;
                m_Normals[n].Y = 1;
                m_Normals[n].Z = 0;
            }
 
            //  Define the indices that make up each triangle.
            Count = 0;
            int vIndex = 0;
            for (int z = 0; z < _terrainHeight; z++)
            {
                for (int x = 0; x < _terrainWidth; x++)
                {
                    // First Triangle
                    m_Indices[Count++] = vIndex + numVertsX + 1;
                    m_Indices[Count++] = vIndex + numVertsX;
                    m_Indices[Count++] = vIndex;
 
                    // Second Triangle
                    m_Indices[Count++] = vIndex + 1;
                    m_Indices[Count++] = vIndex + numVertsX + 1;
                    m_Indices[Count++] = vIndex;
 
                    vIndex++;
                }
                vIndex++;
            }
        }
 
 
        /// <summary>
        /// Draw the terrain the the screen in the OpenTK control panel.
        /// </summary>
       public void RenderTerrain()
        {
            //  Set the terrains color to black.
            OpenTK.Graphics.OpenGL.GL.ClearColor(Color.Black);            //  The background color.
            OpenTK.Graphics.OpenGL.GL.Clear(OpenTK.Graphics.OpenGL.ClearBufferMask.ColorBufferBit | OpenTK.Graphics.OpenGL.ClearBufferMask.DepthBufferBit);
 
            Matrix4 modelview = Matrix4.LookAt(Vector3.UnitZ, Vector3.Zero, Vector3.UnitY);
            OpenTK.Graphics.OpenGL.GL.MatrixMode(OpenTK.Graphics.OpenGL.MatrixMode.Modelview);
            OpenTK.Graphics.OpenGL.GL.LoadMatrix(ref modelview);
 
            // Enble and specify pointers to vertex arrays.
            OpenTK.Graphics.OpenGL.GL.EnableClientState(OpenTK.Graphics.OpenGL.EnableCap.NormalArray);
            OpenTK.Graphics.OpenGL.GL.EnableClientState(OpenTK.Graphics.OpenGL.EnableCap.ColorArray);
            OpenTK.Graphics.OpenGL.GL.EnableClientState(OpenTK.Graphics.OpenGL.EnableCap.VertexArray);
 
            OpenTK.Graphics.OpenGL.GL.NormalPointer(OpenTK.Graphics.OpenGL.NormalPointerType.Double, 3, m_Normals);
 
            OpenTK.Graphics.OpenGL.GL.ColorPointer(4, OpenTK.Graphics.OpenGL.ColorPointerType.Float, 4, m_Colors);
 
            OpenTK.Graphics.OpenGL.GL.VertexPointer(3, OpenTK.Graphics.OpenGL.VertexPointerType.Double, 3, m_Vertices);
 
            OpenTK.Graphics.OpenGL.GL.PushMatrix();
 
            OpenTK.Graphics.OpenGL.GL.DrawArrays(OpenTK.Graphics.OpenGL.BeginMode.Triangles, 0, m_nNumber_O_Triangles);
 
            OpenTK.Graphics.OpenGL.GL.PopMatrix();
 
            // Disable vertex arrays.
            OpenTK.Graphics.OpenGL.GL.DisableClientState(OpenTK.Graphics.OpenGL.EnableCap.VertexArray);
            OpenTK.Graphics.OpenGL.GL.DisableClientState(OpenTK.Graphics.OpenGL.EnableCap.ColorArray);
            OpenTK.Graphics.OpenGL.GL.DisableClientState(OpenTK.Graphics.OpenGL.EnableCap.NormalArray);
        }
 
 
 
    }
}

[edit (by kanato): inserted code tags]


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
kanato's picture

A couple of suggestions:
Don't use black as a clear color. If there is a problem with lighting or something, and your objects are being drawn black, you can't tell. For similar reasons, don't use white either.
Are you using lighting? Turn it off and disable your normal array if so.
It looks like you haven't set anything for the color array?
Have you set a projection matrix?

Also, your pushmatrix and popmatrix calls are superfluous. If you want to do that, you should call pushmatrix before calling loadmatrix.

zahirtezcan's picture

Your stride parameters are given wrong. `Stride` is byte distance between two reads from the buffer such that, lets say you have a vertex structure of position and color:

struct Vertex
{
    public Vector3 Position;
    public Vector4 color;
    public static readonly int SizeInBytes = Vector3.SizeInBytes /*position*/ + Vector4.SizeInBytes /*color*/
}

Moreover, lets assume you want to set pointers with an array of this structure:
Vertex[] buffer

Then you should give stride for position: Vertex.SizeInBytes.

For your case, all of your stride parameters should be zero