1

I have created an interesting "list" of structures. Those structures contain some arrays (dynamic) and I want to ReDim them. But I get an error :
    "A first chance exception of type 'System.NullReferenceException' occurred in 3D Cube.exe" and
    "Object reference not set to an instance of an object.".

This is how the code looks like (you can see that it looks like opengl):

THE MODULE:

Public Module _3DDefinitions
    Public Pen1 As New System.Drawing.Pen(Color.White, 2)


    Public Structure VertexesObjects
        Dim Face() As Faces
        Dim FaceCount As Double
        Dim Position As DPoint  ''Translated Position
        Dim NPPF As Integer     ''NumberofPointsPerFace
    End Structure
    Public Structure Faces
        Dim PointVertexes() As _3DDefinitions.DPoint
        Dim PointCount As Double
        Dim FaceColor As Color
    End Structure
    Public Structure DPoint
        Dim X As Single
        Dim Y As Single
        Dim Z As Single
    End Structure

    Enum GL_LoadAction As Byte
        GL_Start = 1   ''Start- equivalent of GlBegin
        GL_End = 2     ''End-equivalent of GlEnd 
    End Enum

    Enum GL_EnableAction As Byte
        GL_UseDefaultUnit = 1
        GL_UseOwnUnit = 2
        GL_Translation = 4
    End Enum
End Module

THE CLASS(I didn't include the first part of the class and many subs and functions):

Private Objects() As _3DDefinitions.VertexesObjects,
    ObjectsIndex As Double, FacesIndex As Double, PointsIndex As Double,
    GL_NPPF As Integer = 4, GL_COLOR As Color = Color.Brown,
    GL_Status As _3DDefinitions.GL_LoadAction = GL_LoadAction.GL_Start, GL_TranslatePosition As _3DDefinitions.DPoint,
    GL_Settings As _3DDefinitions.GL_EnableAction = GL_EnableAction.GL_UseDefaultUnit,
    GL_DrawingInitialized As Boolean = False, GL_GraphicsInitialized As Boolean = False,
    GL_Unit As Double = 300


Public Sub GL_LoadVertexes(ByVal Operation As _3DDefinitions.GL_LoadAction)
    GL_Status = Operation
    If Operation = _3DDefinitions.GL_LoadAction.GL_Start And Not GL_DrawingInitialized Then
        GL_DrawingInitialized = True
        GL_GraphicsInitialized = False

        ReDim Preserve Objects(ObjectsIndex)

        FacesIndex = 0
        PointsIndex = 0

    ElseIf Operation = GL_LoadAction.GL_End And GL_GraphicsInitialized And GL_DrawingInitialized Then
        GL_DrawingInitialized = False
        ObjectsIndex = ObjectsIndex + 1

        Draw()

    End If
End Sub

Public Sub LoadVertex3D(ByVal X As Single, ByVal Y As Single, ByVal Z As Single)

    If GL_Status = GL_LoadAction.GL_Start Then
        GL_GraphicsInitialized = True

        ReDim Preserve Objects(ObjectsIndex).Face(FacesIndex).PointVertexes(PointsIndex)''<--Here is the error

        If FindBit(GL_Settings, GL_EnableAction.GL_UseOwnUnit) Then
            With Objects(ObjectsIndex).Face(FacesIndex).PointVertexes(PointsIndex)
                .X = X
                .Y = Y
                .Z = Z
            End With

        ElseIf FindBit(GL_Settings, GL_EnableAction.GL_UseDefaultUnit) Then
            With Objects(ObjectsIndex).Face(FacesIndex).PointVertexes(PointsIndex)
                .X = X * GL_Unit / 10
                .Y = Y * GL_Unit / 10
                .Z = Z * GL_Unit / 10
            End With

        End If

        If PointsIndex = GL_NPPF - 1 Then
            FacesIndex = FacesIndex + 1
            PointsIndex = 0
        Else

            PointsIndex = PointsIndex + 1

        End If

    End If
End Sub


      The sub LoadVertex3D just loads some points (coordinates) in memory (using the structures) and the sub GL_LoadVertexes tells the class that the user wants to load the points of an 3d object. I really need those structures because for example I will want to create a new "object" so I'll have to use the "Objects" special variable again. But when I do that the FacesIndex and PointsIndex (those are just counters) will be reset .
      The only var that will remain untouched will be ObjectsIndex. And that's why I need the structures because in those I can save the number of created faces and points (in the FaceCount and PointCount variables).
       What's the problem? Or if you know a better solution for my needs can you tell me please?

sergiu reznicencu
  • 1,039
  • 1
  • 11
  • 31
  • 1
    Avoid `ReDim` (a holdover from VB6 days), consider using `List` instead. – Dai Dec 29 '15 at 19:13
  • Consider not using standard NET Type names for your variables too. Basically `Private Objects() As ...` simply declares the array. I cant see where you create and instance in that wall of code. See http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it/26761773#26761773 – Ňɏssa Pøngjǣrdenlarp Dec 29 '15 at 19:15
  • @Plutonix I'm kinda new to vb.net. What did you mean by "NET Type"? I know from vb6 that Type was used for structures.. – sergiu reznicencu Dec 29 '15 at 19:16
  • @Plutonix I didn't know I have to use the new keyword when creating an variable. There's a module in which I have a few structures. Then in the class I create a variable like this : Private Objects() as . . I've done exactly what you said. And creating a new instance of what? – sergiu reznicencu Dec 29 '15 at 19:24
  • New is not for "creating variables" it creates an instance of an object. `I create a variable like this...`. As before, `Private | Dim` simply **declares** a variable; your array is declared but **not** instanced. Use a List instead and save yourself some grief. – Ňɏssa Pøngjǣrdenlarp Dec 29 '15 at 21:41

1 Answers1

0

Your issue is really here:

FacesIndex = FacesIndex + 1

You increase the index without doing a redim on the array it references. Then when you go to redim your PointVertexes array, you get the null reference because the index does not exist within the Face array. To resolve, you should do something like this:

    If PointsIndex = GL_NPPF - 1 Then
        FacesIndex = FacesIndex + 1
        ReDim Preserve Objects(ObjectsIndex).Face(FacesIndex)
        PointsIndex = 0
        ... and then create the inner array, etc...
Steve
  • 5,585
  • 2
  • 18
  • 32