Sign in to follow this  
Hydrael

OpenGL Questions regarding D3DXLoadMeshFromX and LPD3DXMESH

Recommended Posts

Hello everyone, I normally belong the the OpenGL faction (but please don't hunt me out of this forum anyway ;) ), but now certain circumstances require me to parse DirectX .X files. Because I don't really feel like writing a parser myself, I thought of using D3DXLoadMeshFromX to do the dirty work for me. I'm an absolute beginner regarding DX programming, so i looked at some tutorials and tried to help myself using Visual Studio's Intellisense. I've already setup the DirectX programming environment, and I can successfully load .X files using D3DXLoadMeshFromX. I've already found out, how to extract vertices from the loaded mesh, and materials/texture names from the material list What I'm missing now is: - how do I extract texcoords and normals? I just can't find any Methods or Attributes that would return one of the two. And another thing: Is it possible, to use D3DXLoadMeshFromX without creating a D3DDevice (and everything that comes with it, like CreateWindow(), etc)? I only need to get the .X file into memory and then analyze its contents. Thanks for any help in advance Regards Chris

Share this post


Link to post
Share on other sites
The texcoords and normals are a part of the vertex format in DX. Each vertex has it's own set of texcoords and a normal, as well as a position and possibly a color. When you extract the vertices from the vertex buffer, this includes the normal and texcoords in the data structure.

You didn't mention about locking the index buffer, I just want to make sure you're aware you need to get the indices from the index buffer. These let you turn the array of vertices into faces, if you need that info as well.

Lastly, you can't create a ID3DXMESH object without a valid D3D device, simply because the mesh object includes resources on the device itself. Since the code is written to be rendered using DX, the mesh already has it's resources in a ready-to-draw state, as a part of trying to be helpful.

What you can do is create the mesh with the SystemMem flag, which would at least create the resources only in system memory. This would eliminate the need to ever transfer any data to/from the GPU, which would cause quite a slow down. There is still some overhead involved in having a device and loading the .x mesh, but it wouldn't be as painful.

Hope this helps.

Share this post


Link to post
Share on other sites
Thanks a lot sirob, that already made a few things clear.
Since you said, that normals/texcoords come with a vertex, my guess is, that I'm doing vertex extraction the wrong way (storing them in a wrong structure).

Here is my experimental piece of code:

LPDIRECT3DVERTEXBUFFER9 pVB;
mesh->GetVertexBuffer(&pVB);

D3DXVECTOR3* pVertices;
pVB->Lock( 0, 0, (void**)&pVertices, 0 );

float a=pVertices[0].x; //bingo, got the right value

pVB->Unlock();


As you can see, I'm storing vertex data in a structure called D3DVECTOR3. Maybe I'm just missing something, but is this ok?
Because I can't seem to find a way to get normals/texcoords out of that structure.
Edit: I've just seen, that there is a class called D3DVERTEX, which sadly is for DX8.1. Am I right with the guess, that I'd need to use a DX9 equivalent? If yes, what's it called?

Regarding Device creation:
Ok, I guess I will just implement a dummy device from a dummy window and use that with the SystemMem flag

Thanks :D

Share this post


Link to post
Share on other sites
There's no structure or class you need to follow, unfortunatly. What there is is a standard on how the data is held inside the buffer. The bad news is that the size of each vertex depends on this structure, and all the elements are optional, except position.

This all means that extracting the actual data from a mesh is quite difficult if you don't know it's format when you write the application.

If you only need the position, this get's pretty simple since you can easily get the stride size you need to use when going through the buffer from the mesh (using GetNumBytesPerVertex). This is your vertex size, and you can be sure that the first 3 floats are the position. The rest of the current vertex would depend on which of the element it has.
If you then skip the stride size forward, you'll get to the next vertex, and again the first 3 floats are the position.

Like I've mentioned, if you can limit yourself to a certain format, you can save yourself a huge headache. If you can't, you'll have to get the Mesh Vertex Declaration (using GetDeclaration), or the FVF (using GetFVF) and work your way from that. I can assure you it won't be pretty :).

That's all I can think about. Maybe someone else has some nice ideas. I sure don't have any.

Hope this helps :).

Share this post


Link to post
Share on other sites
Allright, thank you.

I guess, I will play around a bit, and see if I get it working the way I'd like it to.
If not, I will go ahead and parse the file myself.

Thanks for your replies sirob, as they helped a lot

Greets
Chris

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Partner Spotlight

  • Forum Statistics

    • Total Topics
      627636
    • Total Posts
      2978319
  • Similar Content

    • By xhcao
      Before using void glBindImageTexture(    GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format), does need to make sure that texture is completeness. 
    • By cebugdev
      hi guys, 
      are there any books, link online or any other resources that discusses on how to build special effects such as magic, lightning, etc. in OpenGL? i mean, yeah most of them are using particles but im looking for resources specifically on how to manipulate the particles to look like an effect that can be use for games,. i did fire particle before, and I want to learn how to do the other 'magic' as well.
      Like are there one book or link(cant find in google) that atleast featured how to make different particle effects in OpenGL (or DirectX)? If there is no one stop shop for it, maybe ill just look for some tips on how to make a particle engine that is flexible enough to enable me to design different effects/magic 
      let me know if you guys have recommendations.
      Thank you in advance!
    • By dud3
      How do we rotate the camera around x axis 360 degrees, without having the strange effect as in my video below? 
      Mine behaves exactly the same way spherical coordinates would, I'm using euler angles.
      Tried googling, but couldn't find a proper answer, guessing I don't know what exactly to google for, googled 'rotate 360 around x axis', got no proper answers.
       
      References:
      Code: https://pastebin.com/Hcshj3FQ
      The video shows the difference between blender and my rotation:
       
    • By Defend
      I've had a Google around for this but haven't yet found some solid advice. There is a lot of "it depends", but I'm not sure on what.
      My question is what's a good rule of thumb to follow when it comes to creating/using VBOs & VAOs? As in, when should I use multiple or when should I not? My understanding so far is that if I need a new VBO, then I need a new VAO. So when it comes to rendering multiple objects I can either:
      * make lots of VAO/VBO pairs and flip through them to render different objects, or
      * make one big VBO and jump around its memory to render different objects. 
      I also understand that if I need to render objects with different vertex attributes, then a new VAO is necessary in this case.
      If that "it depends" really is quite variable, what's best for a beginner with OpenGL, assuming that better approaches can be learnt later with better understanding?
       
    • By test opty
      Hello all,
       
      On my Windows 7 x64 machine I wrote the code below on VS 2017 and ran it.
      #include <glad/glad.h>  #include <GLFW/glfw3.h> #include <std_lib_facilities_4.h> using namespace std; void framebuffer_size_callback(GLFWwindow* window , int width, int height) {     glViewport(0, 0, width, height); } //****************************** void processInput(GLFWwindow* window) {     if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)         glfwSetWindowShouldClose(window, true); } //********************************* int main() {     glfwInit();     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);     //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);     GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", nullptr, nullptr);     if (window == nullptr)     {         cout << "Failed to create GLFW window" << endl;         glfwTerminate();         return -1;     }     glfwMakeContextCurrent(window);     if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))     {         cout << "Failed to initialize GLAD" << endl;         return -1;     }     glViewport(0, 0, 600, 480);     glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);     glClearColor(0.2f, 0.3f, 0.3f, 1.0f);     glClear(GL_COLOR_BUFFER_BIT);     while (!glfwWindowShouldClose(window))     {         processInput(window);         glfwSwapBuffers(window);         glfwPollEvents();     }     glfwTerminate();     return 0; }  
      The result should be a fixed dark green-blueish color as the end of here. But the color of my window turns from black to green-blueish repeatedly in high speed! I thought it might be a problem with my Graphics card driver but I've updated it and it's: NVIDIA GeForce GTX 750 Ti.
      What is the problem and how to solve it please?
  • Popular Now