LDraw.org Discussion Forums

Full Version: Simple renderer in .net with SharpGL (openGL)
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3 4 5 6
I like to have for my several apps a slim renderer.
It should be done in pur net language
I have already set up a little bit, but run into problems that I am too stupid for to solve.
Is there anybody out there that can help on this?
Although I don't use .net specifically in my programs, maybe I can help on the general stuff. Any LDraw renderer uses the same principles anyway.

What problems are you having?
At present it is just that I have a flipped picture in my renderer. I'll send a screenshot by PM to you this evening along with the source code in .net vb.
I hope you help a little bit.
Are you compensating for DirectX being left handed while LDraw (and OpenGL) use right handed coordinates.
That might be the problem.
Please note that all lines with ' are comments
and sorry for my german comments:

This is to set the renderscene:
Code:
Public Sub InitSettings()
        ' Das hier sollte Sie erst einmal auch nicht kümmern.
        ' Hier wird mit Hilfe einer Matrix festgelegt, wie
        ' die einzelnen Objekte zu rendern sind.

        Dim Lookat As New Vector3
        Dim CameraPosition As New Vector3
        Dim UpDown As New Vector3
        Dim Factor As Integer = 3

        With Lookat
            .X = gLookAt.X
            .Y = gLookAt.Y
            .Z = gLookAt.Z
        End With

        With CameraPosition
            .X = 123.182831 / Factor '-70
            .Y = -100.578362 / Factor '-50
            .Z = -125.182831 / Factor '-100
        End With

        With UpDown
            .X = 0 '-0.35
            .Y = -1 '-0.866
            .Z = 0 '0.35
        End With

        'declare the World as identity matrix
        matWorld = Matrix.Identity

        'D3DDevice.SetTransform(TransformType.World1, matWorld)
        D3DDevice.SetTransform(TransformType.View, matWorld)
        'd3ddevice.SetTransform(

        ' Diese Matrix kann man als Kamera betrachten, mit
        ' der sich das Sichtfeld modifizieren lässt.
        ' Der erste MakeVector ist der Standort der Camera 100, -100, 100
        ' Der zweite MakeVector ist der Lookat Punkt 0, 0, 0
        ' Der dritte MakeVector bestimmt oben und unten 0, -1 , 0
        matView = Matrix.LookAtLH(CameraPosition, Lookat, UpDown)


        D3DDevice.SetTransform(TransformType.View, matView)


        ' Mit der Projektion-Matrix legen wir Sichtweite und
        ' Sichtwinkel fest.
        'Die beiden letzten Werte legen fest was man sieht, bei 1 ,1000 ist alles ok
        'bei 0.001 , 1000 sieht man hindurch
        'matProj = Matrix.PerspectiveFovLH((Pi / 4), 4 / 3, 10, 1000)
        matProj = Matrix.PerspectiveFovLH((Pi / 4), frmLDParts.Panel1.Width / frmLDParts.Panel1.Height, 10, 1000)
        D3DDevice.SetTransform(TransformType.Projection, matProj)

        ' Jetzt teilen wir dem Device noch mit, welches
        ' Art Vertex wir haben
        D3DDevice.VertexFormat = CType(D3DFVF_COLORVERTEX, VertexFormats)


        'With vbLightAmbient
        '  .a = 255
        '  .b = 125
        '  .g = 125
        '  .r = 125
        'End With
        'vbLight.Ambient = vbLightAmbient

        Dim vbTestBench As New VertexBuffer(D3DDevice, 400, Usage.Points, CType(D3DFVF_COLORVERTEX, VertexFormats), Pool.Default)
        'MsgBox("Vertexbuffer.SizeInBytes: " & test.SizeInBytes)
        Dim descr As VertexBufferDescription = vbTestBench.Description
        'MsgBox("VertexbufferDecsription.VertexFormat: " & descr.VertexFormat)
        'Dim descr As VertexBufferDescription
        'descr.Format = Format.VertexData
        'descr.VertexFormat = D3DFVF_COLORVERTEX
        'descr.Usage = Usage.Points
        'descr.Type = ResourceType.VertexBuffer



        ' Und noch ein paar Einstellungen

        'D3DDevice.SetRenderState(RenderStates.ZEnable, True)
        D3DDevice.RenderState.ZBufferWriteEnable = True
        'D3DDevice.SetRenderState(RenderStates.Lighting, False)
        D3DDevice.RenderState.Lighting = False
        'D3DDevice.SetRenderState(RenderStates.FillMode, FillMode.Solid)
        D3DDevice.RenderState.FillMode = FillMode.Solid
        'D3DDevice.SetRenderState(RenderStates.CullMode, Cull.CounterClockwise)
        D3DDevice.RenderState.CullMode = Cull.None
        D3DDevice.RenderState.AntiAliasedLineEnable = True
        D3DDevice.RenderState.LocalViewer = True

        'D3DDevice.SetRenderState D3DRS_CULLMODE, D3DCULL_CCW
    End Sub


The main loop:
Code:
Public Sub Mainloop()
        ' Der MainLoop läuft solange wie wir die
        ' bRunning-Variable auf 'true' lassen

        Do While bRunning

            ' Das vorher Gezeichnete löschen, indem wir es mit
            ' grauer Farbe übermalen
            D3DDevice.Clear((Direct3D.ClearFlags.Target Or Direct3D.ClearFlags.ZBuffer), Color.WhiteSmoke, 1.0F, 0)
            'D3DDevice.Clear 0, ByVal 0, D3DCLEAR_TARGET Or D3DCLEAR_ZBUFFER, &HC0C0C0, 1.0#, 0
            '&HFF& = Blau
            '&HAA& =

            ' Dem Device sagen, dass das "rendern gleich
            ' beginnt"
            D3DDevice.BeginScene()

            ' Und nun lassen wir das Ganze noch rotieren
            Rotation = Rotation + 0.01

            matWorld = Matrix.Identity
            matRotation = Matrix.RotationY(CSng(Rotation * 1 * Pi / 180))
            matWorld = Matrix.Multiply(matWorld, matRotation)

            'D3DDevice.SetTransform(TransformType.World, matWorld)

            ' Hier "rendern" wir unsere Szene
            'Debug.Print("Start Rendern")
            If UBound(gLines) > 0 Then
                D3DDevice.DrawUserPrimitives(PrimitiveType.LineList, CInt(CLng(UBound(gLines) / 2)), gLines)
            End If

            'Dim a As New Line(D3DDevice)
            'a.Begin()
            'a.DrawTransform(gLines, matWorld, gLines(1).Color)
            'a.End()

            If UBound(gTriangles) > 0 Then
                D3DDevice.DrawUserPrimitives(PrimitiveType.TriangleList, CInt(CLng(UBound(gTriangles) / 3)), gTriangles)
            End If
            'MsgBox(UBound(Quads))
            If UBound(gQuads) > 0 Then
                D3DDevice.DrawUserPrimitives(PrimitiveType.TriangleList, CInt(CLng(UBound(gQuads) / 3)), gQuads)
            End If
            'D3DDevice.SetTexture(0, Textur)
            'D3DDevice.VertexFormat = CustomVertex.PositionTextured.Format

            'Debug.Print("End Rendern")

            ' Rendern beendet
            D3DDevice.EndScene()

            ' Und das Ganze "präsentieren"
            D3DDevice.Present()


            ' Jeder, der schon mal einen Loop ohne Beendigungs-
            ' Bedingung gebastelt hat, weiß, dass man ein
            ' Doevents braucht, um noch Eingaben in seinen
            ' PC machen zu können
            My.Application.DoEvents()
            'bRunning = False
        Loop
    End Sub

Maybe you can see in the code above why my picture with this renderer is mirrored.
You seem to correct for the neg y-axis in the viewmatrix, but I don't think you correct for the left/right stuff. I believe you need to scale all ldraw matrices with the inverse of 1, 1, -1 for that.
Yes, that sounds reasonable. I'll try that soon and let you know.
I dug up some very old LD4DModeler code, which used DirectX

In it I do correction during the type 1 line loading.

Code:
//x y z
  matrix.m[3, 0]:=getvalue(line);
  matrix.m[3, 1]:=getvalue(line);
  matrix.m[3, 2]:=getvalue(line);
  matrix.m[3, 3]:=1;

  //a b c
  matrix.m[0, 0]:=getvalue(line);
  matrix.m[1, 0]:=getvalue(line);
  matrix.m[2, 0]:=getvalue(line);

  //d e f
  matrix.m[0, 1]:=getvalue(line);
  matrix.m[1, 1]:=getvalue(line);
  matrix.m[2, 1]:=getvalue(line);

  //g h i
  matrix.m[0, 2]:=getvalue(line);
  matrix.m[1, 2]:=getvalue(line);
  matrix.m[2, 2]:=getvalue(line);

  matrix.m[0, 3]:=0;
  matrix.m[1, 3]:=0;
  matrix.m[2, 3]:=0;        

  //rechthandig matrix -> linkshandige matrix
  //(T^-1)ST      waar s bron is en T rh2lhflip is

  //mat:=rh2lhflip^-1
  D3DXMatrixInverse(mat, @dummy, rh2lhflip);
  //mat:=(rh2lhflip^-1)*s
  D3DXMatrixMultiply(mat, mat, matrix);
  //s:=(rh2lhflip^-1)*s*rh2lhflip
  D3DXMatrixMultiply(matrix, mat, rh2lhflip);


rh2lhflip is inited elsewhere as D3DXMatrixScaling(rh2lhflip, 1, -1, 1);

Do note this is very (11 years!) old code, and I wasn't exactly an expert myself at that time Smile


edit: above code is less then correct and unnecessary overcomplicated. It's better to convert to lefthand/neg y axis at the model level.
Thanks for sharing that code.
At present I am looking for the right matrix to use:
1 0 0 0
0 1 0 0
0 0 -1 0
0 0 0 1

Do you think this is the correct matrix to use?
If yes, I set up a manual matrix and multiply just before the output with this.
Pages: 1 2 3 4 5 6