• Advertisement
Sign in to follow this  

glNormal3f conversion to direct3d

This topic is 2774 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

[Source] glBegin(GL_TRIANGLES);
glNormal3f(ROOT2D2, -ROOT2D2, 0);
glNormal3f(-ROOT2D2, ROOT2D2, 0);
glVertex3f(x, y, z-height);
glVertex3f(x-width, y-width, z);
glVertex3f(x-width, y+width, z);

glNormal3f(0, ROOT2D2, ROOT2D2);
glVertex3f(x, y, z-height);
glVertex3f(x-width, y+width, z);
glVertex3f(x+width, y+width, z);

glNormal3f(ROOT2D2, ROOT2D2, 0);
glVertex3f(x, y, z-height);
glVertex3f(x+width, y+width, z);
glVertex3f(x+width, y-width, z);

glNormal3f(0, ROOT2D2, -ROOT2D2);
glVertex3f(x, y, z-height);
glVertex3f(x+width, y-width, z);
glVertex3f(x-width, y-width, z);
glEnd();
[/Source]

What is the equvalence coding for Direct3D, please?
AFAIK, glNormal3f "places" a unit vector at that coordinate, but can't find
similar stuff in direct3d...
Thanks
Jack

Share this post


Link to post
Share on other sites
Advertisement
I don't believe D3D has anything equivalent to OpenGL immediate mode. (Although, I think I've seen some wrappers that people have put together to emulate the behavior, more or less.)

Note that even in OpenGL, immediate mode is now deprecated. In any case, your best bet is probably to adjust your code to render using more typical methods (e.g. vertex buffers, etc.).

Share this post


Link to post
Share on other sites
Thanks jyk for your response.
I'd like to know what that whole lot of code does functionally.
All I know that is doing a DrawPyramid, and as I want to convert it into Direct3D
coding. Could you give me any pointers of what the code does step-by-step?
Thanks
Jack

Share this post


Link to post
Share on other sites
Every 3 glVertex calls are generating a triangle, and the glNormal call is providing a normal for each of the vertices of the triangle, altogether they generate some shape.

Share this post


Link to post
Share on other sites
Quote:
Original post by NumberXaero
Every 3 glVertex calls are generating a triangle, and the glNormal call is providing a normal for each of the vertices of the triangle, altogether they generate some shape.


Hello NumverXaero,
still can't figure out how to code this stuff in direct3d....
Any sample code? just anything that can get me started..
especially on how to go about attaching a vector in space.
Thanks
Jack

Share this post


Link to post
Share on other sites
As mentioned above, DX doesn't have an "immediate" mode. You would have to create a vertexbuffer, load in the triangle data and (later) render the vertexbuffer.

Pseudo-code

determine number of vertices
create a vertexbuffer of that size
from glBegin(GL_TRIANGLES) to glEnd()
get a normal or vertex
write it to the vertexbuffer
//...
render the vertexbuffer

If you're not familiar with DirectX, I'd suggest writing and understanding a simplified version of that process. I.e., create a vertexbuffer, load it with "fixed" data, render it. When you see how that works, change the loading routine to use OGL data.

Share this post


Link to post
Share on other sites
Quote:
Original post by Buckeye
As mentioned above, DX doesn't have an "immediate" mode. You would have to create a vertexbuffer, load in the triangle data and (later) render the vertexbuffer.

Pseudo-code

determine number of vertices
create a vertexbuffer of that size
from glBegin(GL_TRIANGLES) to glEnd()
get a normal or vertex
write it to the vertexbuffer
//...
render the vertexbuffer

If you're not familiar with DirectX, I'd suggest writing and understanding a simplified version of that process. I.e., create a vertexbuffer, load it with "fixed" data, render it. When you see how that works, change the loading routine to use OGL data.


Thanks, I'll have to have a bit of thinking. Let me come back if I have problems.
Jack

Share this post


Link to post
Share on other sites
If you're familiar with the STL, you could (eventually) read in the data into vectors of vertices, normals, etc. Then vector::size() would tell you how big the vertex buffer needs to be. Be careful, though, OGL allows you to set a normal that applies until it changes. In DX, you'll have to apply a normal to every vertex.

Share this post


Link to post
Share on other sites
Look at the tutorials in the DirectX SDK, particularly D3D9 Tutorial 2 - Rendering Vertices. This should tell you almost everything you need to know.

The one thing it won't tell you is about DrawPrimitiveUP, which lets you use arrays of structs in system memory as a source for rendering from. It's use is generally discouraged as it's slower than using a vertex buffer, but for simple beginning code it's quite fine, and will save you the complication of having to do everything the right way from the outset (especially if you're porting code from OpenGL) (although VBs in D3D are not really that difficult).

Share this post


Link to post
Share on other sites
Quote:
Original post by mhagain
Look at the tutorials in the DirectX SDK, particularly D3D9 Tutorial 2 - Rendering Vertices. This should tell you almost everything you need to know.

The one thing it won't tell you is about DrawPrimitiveUP, which lets you use arrays of structs in system memory as a source for rendering from. It's use is generally discouraged as it's slower than using a vertex buffer, but for simple beginning code it's quite fine, and will save you the complication of having to do everything the right way from the outset (especially if you're porting code from OpenGL) (although VBs in D3D are not really that difficult).


Hello mhagain,
I wonder the normal of (ROOT2D2, -ROOT2D2,0) is a vertex normal or surface normal.
I ask because if it is a vertex normal, i have to duplicate it 3 times in the vertex buffer, seems redundant. It looks like a surface normal, but I am not sure how to add it to the vertex buffer?


#define JVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1)


class CJVertex
{
public:
CJVertex();
CJVertex( float x, float y, float z,
float nx, float ny, float nz,
D3DXCOLOR DiffuseColor,
D3DXCOLOR SpecularColor,
float tu, float tv);
~CJVertex();

// Functions
public:
void Set( float x, float y, float z,
float nx, float ny, float nz,
D3DXCOLOR DiffuseColor,
D3DXCOLOR SpecularColor,
float tu, float tv);

protected:

// Variables
public:
D3DXVECTOR3 m_Position;
D3DXVECTOR3 m_Normal;
D3DXCOLOR m_DiffuseColor;
D3DXCOLOR m_SpecularColor;
float m_tu, m_tv;

protected:

};


// Untested Jacky Luk 21/7/2010
void drawPyramid(LPDIRECT3DDEVICE9 pDevice,DXfloat x, DXfloat y, DXfloat z, DXfloat height, DXfloat width)
{
std::vector<CJVertex> v_vertex;
CJVertex jv;
D3DXVECTOR3 vertex1(x,y,z-height);
D3DXVECTOR3 vertex2(x-width, y-width, z);
D3DXVECTOR3 vertex3(x-width, y+width, z);

D3DXVECTOR3 edge1 = vertex2 - vertex1;
D3DXVECTOR3 edge2 = vertex3 - vertex2;

D3DXVECTOR3 vec3;
D3DXVECTOR3 nVec;
D3DXVec3Cross(&vec3, &edge1, &edge2);
D3DXVec3Normalize(&nVec, &vec3);



jv.Set(x,y,z-height,-ROOT2D2, ROOT2D2,0, D3DXCOLOR(255,255,255,255), D3DXCOLOR(127,127,127,255), 1.0f, 1.0f);
v_vertex.push_back(jv);

jv.Set(x-width, y-width, z, -ROOT2D2, ROOT2D2, 0, D3DXCOLOR(255,255,255,255), D3DXCOLOR(127,127,127,255), 1.0f, 1.0f);
v_vertex.push_back(jv);

jv.Set(x-width, y+width, z, -ROOT2D2, ROOT2D2, 0, D3DXCOLOR(255,255,255,255), D3DXCOLOR(127,127,127,255), 1.0f, 1.0f);
v_vertex.push_back(jv);

////..... add the rest of them


HRESULT r = 0;

// New vertex buffer
LPDIRECT3DVERTEXBUFFER9 pVB = 0;

r = pDevice->CreateVertexBuffer( sizeof( CJVertex ), D3DUSAGE_WRITEONLY, JVERTEX, D3DPOOL_DEFAULT, &pVB , NULL);
if( FAILED( r ) )
return;// E_FAIL;

// Pointer to vertex buffer data
void* pData = 0;

// Lock the vertex buffer
r = pVB->Lock( 0, 0, /*(BYTE**)*/&pData, 0 );
if( FAILED( r ) )
{
pVB->Release();
return;
}

for (int i = 0; i < v_vertex.size(); i++)
{
// Copy the vertex for the point into the vertex buffer
CopyMemory( (PBYTE)pData+i*sizeof(CJVertex), (PBYTE)&v_vertex, sizeof( CJVertex ) );
}

// Unlock the vertex buffer
pVB->Unlock();

// Attach the vertex buffer to a rendering stream
pDevice->SetStreamSource( 0, pVB, 0, sizeof( CJVertex ) );

// Draw the point
pDevice->DrawPrimitive( D3DPT_POINTLIST, 0, 1 );

// Release the vertex buffer
pVB->Release();








Thanks in advance
Jack

Share this post


Link to post
Share on other sites
If it's a surface normal it still needs to be added to each individual vertex in the buffer. VertexBuffers in D3D are the same as VBOs or vertex arrays in OpenGL in this respect; you can't specify a "current normal" or "current color" that every vertex issued automatically picks up until you change it.

If you're honestly having trouble with this, I'd recommend that you step back and consider a much simpler application until you're feeling more comfortable with the way D3D works. Work from the tutorials in the SDK, they're great learning resources. No criticism intended, just honest helpful advice: I think you're trying to take on too much too soon, and that's not a good way to learn.

[Edited by - mhagain on July 21, 2010 7:27:40 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by mhagain
If it's a surface normal it still needs to be added to each individual vertex in the buffer. VertexBuffers in D3D are the same as VBOs or vertex arrays in OpenGL in this respect; you can't specify a "current normal" or "current color" that every vertex issued automatically picks up until you change it.

If you're honestly having trouble with this, I'd recommend that you step back and consider a much simpler application until you're feeling more comfortable with the way D3D works. Work from the tutorials in the SDK, they're great learning resources. No criticism intended, just honest helpful advice: I think you're trying to take on too much too soon, and that's not a good way to learn.


[link]http://img811.imageshack.us/img811/1741/normal2s.jpg[/link]

I think it's talking about the normals circled above.
If I had a vertex buffer that I must pass to it a normal for every vertex
Wouldn't that be too redundant? (See format of CJVertex)
And which normals (face or vertex) I produced should be used in this case?
And thanks for your advice, I am also reading back some of my old references
which I have long forgotten. :)
Thanks
Jack

Share this post


Link to post
Share on other sites
Quote:
Original post by lucky6969b
If I had a vertex buffer that I must pass to it a normal for every vertex
Wouldn't that be too redundant? (See format of CJVertex)


It's the same as what OpenGL does anyway, but it's just hidden behind the API there. You set a "current normal" via glNormal3f, and then every time you call glVertex3f the "current normal" is associated with the vertex and transferred to the command buffer. So even if you only use glNormal3f once, you'll still get n normal transfers if you call glVertex3f n times.

So the GL immediate mode API is just a convenience feature rather than anything more optimal. And don't worry, using a proper vertex buffer, or even a software array via DrawPrimitiveUP, will greatly outperform OpenGL immediate mode every time, even with the (apparent) extra data.

This is actually a perfectly understandable pitfall that can happen to anyone who has an OpenGL background and are moving to D3D. They see more code (though that's not always the case) and more data and think it must be redundant and suboptimal, whereas it's actually not (the same applies to the pseudo-OO-ness of COM vs OpenGL procedural calls).

So run with the recommended way of doing it in D3D, don't worry that it might contradict what you already know to be true when you think in OpenGL terms, and all will be well. The worst thing you can actually do is try to brutalize D3D code to look the same as the equivalent OpenGL code. It won't work right, you'll make a mess, and performance will suffer.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement