Advertisement

Reading BSP map data into DX11 Buffers

Started by February 21, 2020 04:56 PM
50 comments, last by Tom_W 4 years, 10 months ago

JoeJ said:

… looking at your code this layout stuff looks correct to me :(

So filling such a vertex buffer with manual numbers to draw a cube is the only idea i have.

As is mine. Thank so much for you help thus far; I am going to attempt to draw a cube manually within DrawFace() and go from there. When you said you looked at my code, were you looking in my DrawFace() function? Because it draws nothing(I'm working with two projects, one for drawing cubes with color and one with textures).

This makes me think the vertex format is different, for example:

DX9:

pos xyz

uv0 xy

uv1 xy

but DX11 might be set up so it expects:

pos xyzw (w unused)

uv0 xy
uv1 xy

I've altered my stBTPVertex:
struct stBSPVertex

{
 D3DXVECTOR3 p;   // Position Vertice
 float       tu1, tv1; // Texture Coordinates
 D3DXVECTOR3 n;   // Vertice Normal
 DWORD  colour;  // ARGB
 float  lu2, lv2; // Light Tex Coords
};

so that's x, y, z, and tu1 and tv1. The original pictures you saw of the textured, not colored, shape rendered, since my layout is as follows:

D3D11_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },  
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },  
};

So I've tried to conform to the vertex format that the shader expects. But as of right now I'll attempt the cube within the DrawFace() function which is a member of the BSP class from the header.

Do you know anyone, or any community, that is proficient in DirectX? Discord perhaps? Thank you so much for your help, Joe. And everyone else, of course.

Tom_W said:
were you looking in my DrawFace() function?

Doing so i wonder why you have 2 draw commands there, but it worked so before and it won't help if you explain me how your engine works.

Tom_W said:
But as of right now I'll attempt the cube within the DrawFace() function which is a member of the BSP class from the header.

Sounds a good idea, assuming you already were able to draw some triangles outside of engine code limit sources of error.
If you start with very simple single color triangle, you should be able to display the level correctly after some time, then add textures etc, finally make it efficient by avoiding the creation of vertex buffers per frame and face…

Tom_W said:
Do you know anyone, or any community, that is proficient in DirectX? Discord perhaps?

I don't, this is the best place i know (not knowing Discord).

Most of the pros hang out on Twitter and just using the API is rarely a topic for them.

Hobby devs use Unity or UE4 and using API directly is never a topic for them.

The latter point seems to show full impact also on this form since a year or so. Technical questions declined a lot, the whole landscape has changed.
Games are no longer one man projects. Specialization happens, lesser people working on tech but with more expertise, more people working on art and design but with more focus.

So, why do you work on your own engine, if using U would be so much easier?

Advertisement

Why not just download the projects of DX12?

You said DX9 seemed deprecated for you.
Just download the demo projects of DX12 and it already draws a cube for you.

Not to mention DX12 has DXR. Tomorrow you will want to have DXR, and you will call DX11 deprecated too.

Before I started learning for the GPU, i spent a good time googling about which are the latest APIs.

DX12 is super easy. It takes time to adapt to it, but here in the forum i got a lot of help with it. Once you get used, it is super easy, just takes lot of writing. The API is pretty explicit.

Tom_W said:
Do you know anyone, or any community, that is proficient in DirectX?

This is the best community for DX i know of, with lot of experts, but the way you ask is not the correct one.

It is a general rule of forums: “Don't copy paste hundreds of lines from your code and expect people to read it.”

NikiTo said:
It is a general rule of forums: “Don't copy paste hundreds of lines from your code and expect people to read it.”

True.

But i disagree with recommending DX12 to somebody who: 1. Struggles with DX11, 2. Shows old school low poly style game where DX12 will show no benefit, but more likely worse performance.

It's not that i think DX12 is reserved for some kind of elite or requires extraordinary skills, but it is 10 times the code and so work for just the same result. Consequence: Less time to work on the game.

I can write a textured software rasterizer with less code then drawing a simple red triangle with Vulkan.

The only reasons to use a low level API are about performance: Multi threaded command list generation and Async Compute. Raytracing is an additional point now, but as long as you do not need any of this it sounds overkill.

@JoeJ You are correct, but why DX at all then? I am sure, there are many easier APIs than DX out there.

If i had to make a game, i think i would use Unity and avoid coding as much as possible. In order to finish the game sooner(talking about a regular game here). But this is my personal opinion. My time to experiment(to lose) is over.

Tom is giving me the impression(i could be wrong) that he is losing his time. He lacks a clear goal. That's why i assumed, that after time, he will come back here with a similar question about switching from DX11 to DX12. I tried to save him time. But i could be wrong about him.

I spoke with an employee of Microsoft who specializes in DirectX(Jesse Natalie herself) and she assured me, rather reluctantly, that DirectX9.0c is going nowhere as long as Windows exists within this decade, they're making up for graphics driver's dropping support for D3D9 with D3D9On12. I got a very, very, lucky insider's discussion with Microsoft employee's today. Was eye-opening.

Nonetheless, I'm still going at it.
Picture of a cube in GTKRadiant prior to compiling to BSP: https://cdn.discordapp.com/attachments/681620634475954196/681640530710364174/unknown.png

and the rendered result:
https://cdn.discordapp.com/attachments/681620634475954196/681640662378348549/unknown.png

What's different about this? Well, from main.cpp, to draw this, all I did was call bsp.PVS_Render().

Joe, the reason you saw so many Draw calls was due to desperation, not knowing what in the hell the Draw functions even do in DX11 or what the arguments/parameters should be, so I double/tripled up hoping for a full cube. I have yet to get one.

 stBSPVertex pVB[10000];
  /* pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
    m_pFaces[nFace].FirstVert,
    0,
    m_pFaces[nFace].NumVerts,
    m_pFaces[nFace].nFirstMeshVerts,
    (m_pFaces[nFace].NumMeshVerts / 3));*/
  Vertex v2[10000];
  for (int i = 0; i < m_nNumVerts; i++)
  {
   // The put the y ans z the wrong way around!
   pVB[i].p.x = m_pVerts[i].vPoint[0];
   pVB[i].p.y = m_pVerts[i].vPoint[1];
   pVB[i].p.z = m_pVerts[i].vPoint[2];

   // tv is inverted!
   pVB[i].tu1 = m_pVerts[i].Tex[0];
   pVB[i].tv1 = m_pVerts[i].Tex[1];
   pVB[i].lu2 = m_pVerts[i].LightTexCoord[0];
   pVB[i].lv2 = m_pVerts[i].LightTexCoord[1];

   pVB[i].n.x = m_pVerts[i].vNormal[0];
   pVB[i].n.y = m_pVerts[i].vNormal[1];
   pVB[i].n.z = m_pVerts[i].vNormal[2];

   // Alpha hack - so our alpha value isn't 100% anymore
   pVB[i].colour = 0x10ffffff &amp; m_pVerts->RGBA; // ARGB*/

  }
  for (int i = 0; i < m_nNumVerts; i++)
  {
   // The put the y ans z the wrong way around!
   v2[i] = Vertex(pVB[i].p.x, pVB[i].p.y, pVB[i].p.z, pVB[i].tu1, pVB[i].tv1);
  }
  /*Vertex v[] =
  {
  // Front Face
  Vertex(-1.0f, -1.0f, -1.0f, 0.0f, 1.0f),
  Vertex(-1.0f, 1.0f, -1.0f, 0.0f, 0.0f),
  Vertex(1.0f, 1.0f, -1.0f, 1.0f, 0.0f),
  Vertex(1.0f, -1.0f, -1.0f, 1.0f, 1.0f),

  // Back Face
  Vertex(-1.0f, -1.0f, 1.0f, 1.0f, 1.0f),
  Vertex(1.0f, -1.0f, 1.0f, 0.0f, 1.0f),
  Vertex(1.0f, 1.0f, 1.0f, 0.0f, 0.0f),
  Vertex(-1.0f, 1.0f, 1.0f, 1.0f, 0.0f),

  // Top Face
  Vertex(-1.0f, 1.0f, -1.0f, 0.0f, 1.0f),
  Vertex(-1.0f, 1.0f, 1.0f, 0.0f, 0.0f),
  Vertex(1.0f, 1.0f, 1.0f, 1.0f, 0.0f),
  Vertex(1.0f, 1.0f, -1.0f, 1.0f, 1.0f),

  // Bottom Face
  Vertex(-1.0f, -1.0f, -1.0f, 1.0f, 1.0f),
  Vertex(1.0f, -1.0f, -1.0f, 0.0f, 1.0f),
  Vertex(1.0f, -1.0f, 1.0f, 0.0f, 0.0f),
  Vertex(-1.0f, -1.0f, 1.0f, 1.0f, 0.0f),

  // Left Face
  Vertex(-1.0f, -1.0f, 1.0f, 0.0f, 1.0f),
  Vertex(-1.0f, 1.0f, 1.0f, 0.0f, 0.0f),
  Vertex(-1.0f, 1.0f, -1.0f, 1.0f, 0.0f),
  Vertex(-1.0f, -1.0f, -1.0f, 1.0f, 1.0f),

  // Right Face
  Vertex(1.0f, -1.0f, -1.0f, 0.0f, 1.0f),
  Vertex(1.0f, 1.0f, -1.0f, 0.0f, 0.0f),
  Vertex(1.0f, 1.0f, 1.0f, 1.0f, 0.0f),
  Vertex(1.0f, -1.0f, 1.0f, 1.0f, 1.0f),
  };

  DWORD indices[] = {
  // Front Face
  0, 1, 2,
  0, 2, 3,

  // Back Face
  4, 5, 6,
  4, 6, 7,

  // Top Face
  8, 9, 10,
  8, 10, 11,

  // Bottom Face
  12, 13, 14,
  12, 14, 15,

  // Left Face
  16, 17, 18,
  16, 18, 19,

  // Right Face
  20, 21, 22,
  20, 22, 23
  };*/
  DWORD pIB[10000];
  /*m_pIB->Lock(0,
  m_nNumMeshIndices*sizeof(WORD),
  (void**)&amp;pIB,
  0);*/
  for (int i = 0; i < m_nNumMeshIndices; i++)
   pIB[i] = m_pMeshIndices[i];

  D3D11_BUFFER_DESC indexBufferDesc;
  ZeroMemory(&amp;indexBufferDesc, sizeof(indexBufferDesc));

  indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
  indexBufferDesc.ByteWidth = sizeof(DWORD)* m_nNumMeshIndices;
  indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
  indexBufferDesc.CPUAccessFlags = 0;
  indexBufferDesc.MiscFlags = 0;

  D3D11_SUBRESOURCE_DATA iinitData;

  iinitData.pSysMem = pIB;
  pDevice->CreateBuffer(&amp;indexBufferDesc, &amp;iinitData, &amp;squareIndexBuffer);

  pDevCon->IASetIndexBuffer(squareIndexBuffer, DXGI_FORMAT_R32_UINT, 0);


  D3D11_BUFFER_DESC vertexBufferDesc;
  ZeroMemory(&amp;vertexBufferDesc, sizeof(vertexBufferDesc));

  vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
  vertexBufferDesc.ByteWidth = sizeof(Vertex)* m_nNumVerts;
  vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
  vertexBufferDesc.CPUAccessFlags = 0;
  vertexBufferDesc.MiscFlags = 0;
  D3D11_SUBRESOURCE_DATA vertexBufferData;

  ZeroMemory(&amp;vertexBufferData, sizeof(vertexBufferData));
  vertexBufferData.pSysMem = v2;
  pDevice->CreateBuffer(&amp;vertexBufferDesc, &amp;vertexBufferData, &amp;squareVertBuffer);

  //Set the vertex buffer
  UINT stride = sizeof(Vertex);
  UINT offset = 0;
  pDevCon->IASetVertexBuffers(0, 1, &amp;squareVertBuffer, &amp;stride, &amp;offset);
  pDevCon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
  pDevCon->DrawIndexed(m_pFaces[nFace].NumVerts, m_pFaces[nFace].nFirstMeshVerts, m_pFaces[nFace].FirstVert);

  for (int i = 0; i < m_nNumFaces; i++)
  {
   // If its not a tri mesh
   if (m_pFaces[i].nFaceType != 1) continue;

   int nFirstF = m_pFaces[i].nFirstMeshVerts;
   int nNumF = m_pFaces[i].NumMeshVerts;

   int nFirstV = m_pFaces[i].FirstVert;
   int nNumV = m_pFaces[i].NumVerts;

   int nTexIndex = m_pFaces[i].nTexture;
#if(0)
   pDevice->SetTexture(0,
    m_pT[nTexIndex]);
#endif

   int nNumTris = nNumF / 3;

   m_nNumTrisDraw += nNumTris;
  pDevCon->DrawIndexed(nNumTris,nFirstF,nFirstV);
   pDevCon->DrawAuto();
   /*pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,  // Type
    nFirstV,    // BaseVertexIndex
    0,      // MinIndex
    nNumV,     // NumVertices
    nFirstF,    // StartIndex
    nNumTris);    // PrimitiveCount*/
  }
  pDevCon->DrawIndexed(m_nNumMeshIndices, 0, 0);
  pDevCon->Draw(m_nNumTrisDraw, 0);
  pDevCon->Draw(nNumTris, 0);
  pDevCon->DrawIndexed(m_nNumVerts, 0, 0);

 }
}

Again, note the multiple draw calls. It's me randomly choosing what arguments to pass in hopes of rendering what I need.

You'll note the DX9 Draw calls are commented out, I'm simply trying to mimic them. Which ones are correct and which aren't?

You'll also notice that the only thing these cubes are missing are certain tri's – there's a function in the header called RenderAll(). I've noticed it takes note of tri's – something that happens to be missing in these particular cubes.

// Renders ALL the level map

// Currently doesn't check if it renders the same face contents twice, as

// different faces can point to the same data.

void RenderAll(IDirect3DDevice9 * pDevice)
{
#if(1)
 // Used for debugging
 pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
 pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
 pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
 pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
#endif
 pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
 pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
 pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);

// pDevice->SetIndices(m_pIB);

// pDevice->SetStreamSource(0, m_pVB, 0, sizeof(stBSPVertex));

 pDevice->SetFVF(m_FVF_Format);


 for (int i = 0; i<m_nNumFaces; i++)
 {
  // If its not a tri mesh
  if (m_pFaces[i].nFaceType != 1) continue;

  int nFirstF = m_pFaces[i].nFirstMeshVerts;
  int nNumF = m_pFaces[i].NumMeshVerts;

  int nFirstV = m_pFaces[i].FirstVert;
  int nNumV = m_pFaces[i].NumVerts;

  int nTexIndex = m_pFaces[i].nTexture;
#if(0)
  pDevice->SetTexture(0,
   m_pT[nTexIndex]);
#endif

  int nNumTris = nNumF / 3;

  m_nNumTrisDraw += nNumTris;

  pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,  // Type
   nFirstV,    // BaseVertexIndex
   0,      // MinIndex
   nNumV,     // NumVertices
   nFirstF,    // StartIndex
   nNumTris);    // PrimitiveCount
 }
}

I don't really know the exact difference between Draw(), DrawIndexed, DrawAuto(), etc. But I do notice nNumTris--perhaps that's what's missing?

What is the DX11 equivalent of DrawIndexedPrimative with those parameterers, when it only accepts three? This is a big part of my dilemma.

Jesus, I'm so desperate it's a joke. I think I've given out at least five cries for help offering half a grand to someone who is knowledgeable in DirectX just to simply convert one header file, but no takers. Somebody please help me out here! This is torture! NikiTo is correct, I am running out of time. I am 30 years old(I look 18 years old still but whatever), and I've wasted my life on drugs. I started using right when .NET came out, until that point I was up to speed on everything, as good as the next man. I read Andre Lamonthe's Game Programming Book for DirectX 6 when I was young, and I was developing a game engine because I actually wanted to beat SEGA to their next large Sonic release, I had stolen their meshes(I was also coding botnets at the the time, when I saw housegate8.house.gov appear in my list of bots, I jumped with joy that I had unwillingly hacked into Congress). But that's all in the past; My life went downhill and yes, I'm out of time, I am choosing my hobby to be my profession until I am eligible for law school, but I was fired as a paralegal for drug use and a whole lot of life story I'm not going to get into now.

Point is, I refuse to be a drug addict anymore, I'm not going to be one of those pothead people who are content to do nothing, produce nothing. I also refuse to use Unity or any other game engine--if I didn't write it, it's not mine. This is why I'm so devoted to writing my own game engine, and having someone help convert a single header file to DX11 so I can spot all the differences, learn from them, and move on.

I feel every day that I am not successful in parsing and rendering a BSP map in a simple tutorial for DX11 that I'm closer to relapsing because my emotional state is quite low at the moment, when I was writing my game engine in DX9 it was nothing but progress but this decision to jump to DX11 has me at a stop light, and I really need the help of all of you, anyone who is reading this.

Thanks so much for your help so far, especially you Joe, you're a god/genius.

Advertisement

Obviously vertex positions are all correct? 

Obviously triangle → vertex indices must be the problem. Come on, can't be that hard to figure out. Read the specs about various Draw commands to know what they do exactly.

I can confirm life is a downwards spiral and time means running out of it, if that helps. (It doesn't)

Tom_W said:
I also refuse to use Unity or any other game engine--if I didn't write it, it's not mine.

But you use some one elses Quake renderer. What's the difference? The difference is, with U the U people take care if something does not work (sometimes), but in your case only you can care to maintain someone elses code that you might not understand in full detail, which - unfortunately - is necessary.

This brings you into a difficult situation, and by moving to DX11 you make your life only harder. You could do that later. (I told you so before - you did not listen, and now see what you get ;)

Expect more trouble to come. Programming means fixing broken stuff all the time. That's no reason to loose hope or something - it just happens, is unavoidable, is no fun, but you're not alone.

I know dealing with gfx API is a special source of frustration, because there are little options to figure out a reason if stuff does not work.

But it seems you are close. Try to imagine my drawn wireframe, draw just one triangle, add one more until the first is clearly wrong. Shuffle indices, see what happens. Maybe it is that DX9 expected triangle fans, but DX11 might expect triangle strips?

 

 

Tom_W said:
I also refuse to use Unity or any other game engine--if I didn't write it, it's not mine.

Anything you program in any language, makes you use millions of lines of code other people programmed for you. So what you say, is said in a wrong way, or makes no sense at all.

Also you:

Tom_W said:
I had stolen their meshes

Wow Joe, you did that outlining bounding box just for me? Thanks!

I'm simply trying my best to find the DX11 equivalent of:

pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,  // Type
    nFirstV,    // BaseVertexIndex
    0,      // MinIndex
    nNumV,     // NumVertices
    nFirstF,    // StartIndex
    nNumTris);    // PrimitiveCount*/

Both 
			pDevCon->Draw(m_nNumTrisDraw, 0);
			pDevCon->Draw(m_nNumVerts, 0);

Draw the boxes you see. I've tried several methods with DrawIndexed, to no avail. What would be its equivalent? (My browser has me stuck in the code block..)

Given I have nFirstV(the BaseVertexIndex), nNumV(The number of vertices for a particular face), nFirstF(Start Index) and nNumTris(commented as “PrimativeCount"), I'm trying my best to find the DX11 equivalent Draw function. 

Woah! I got close with this one:

pDevCon->Draw(m_nNumTrisDraw, nFirstV);

I got much more cohesive boxes, I just have to find out the right Draw call with the right parameters…

This topic is closed to new replies.

Advertisement