Sign in to follow this  

rotating cube in orthographic mode

This topic is 2324 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

Hi,

I want to rotate a cube in orthographic mode. I can set up the orthographic mod using D3DXMatrixOrthoLH(...), and I can drag a full-screen quad on screen, however when I try to rotate nothing shows up on screen.
Here's the code:
[code]
D3DXMatrixOrthoLH(&mat_proj, (FLOAT)screen_width, (FLOAT)screen_height, 0.0f, 1.0f);

D3DXMATRIX mat_w;
float rotation = -45.0f;
D3DXMatrixRotationY(&mat_w, D3DXToRadian(rotation));
dx_dev->SetTransform(D3DTS_WORLD, &mat_w);

D3DXMatrixLookAtLH( &mat_view, &D3DXVECTOR3( 0.0f, 0.0f, 0.0f ),
&D3DXVECTOR3( 0.0f, 0.0f, -1.0f ),
&D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );

D3DXMATRIXA16 mat_mvp = mat_world * mat_view * mat_proj;
constant_table->SetMatrix(dx_dev, "mvp", &mat_mvp);

//render full-screen quad
[/code]

Best regards,
Yours3!f

Share this post


Link to post
Share on other sites
Try rotating 0 degrees and increase until you can't see it.

Try printing out the object to world matrix.

Make sure that you are rotating around the object space Y axis and not the world space Y axis.

Remember that the matrix in HLSL is the transpose of the matrix in DirectX.

Share this post


Link to post
Share on other sites
I tried what you said at 1 (or -1) I can see only a little bit of it, so I tried to increase the z-max value when I set the orthogonal projection matrix to 1000.0 and now I can see half of the full-screen quad, I guess the rest is behind the near plane, so it gets cut out.

[quote]Try printing out the object to world matrix.
[/quote]

What do you mean by that? Do you want me to post the world matrix?

Since I don't do any translation I guess I spin the quad aroung its object space y axis.

In HLSL I just do the following:
[code]
struct VS_INPUT
{
float4 position : POSITION;
float2 tex_coord : TEXCOORD0;
};

struct VS_OUTPUT
{
float4 position : POSITION;
float2 tex_coord : TEXCOORD0;
};

float4x4 mvp;

VS_OUTPUT main( in VS_INPUT input )
{
VS_OUTPUT output;

output.position = mul(input.position, mvp);
output.tex_coord = input.tex_coord;

return output;
}
[/code]

I guess this doesn't change much right?

Share this post


Link to post
Share on other sites
I simplified the whole app to 317 lines, here's the code:

[code]
#define WIN32_LEAN_AND_MEAN

#include <Windows.h>
#include <d3d9.h>
#include <d3dx9.h>

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <tchar.h>
#include <sstream>
#include <stdexcept>

LPDIRECT3D9 dx;
LPDIRECT3DDEVICE9 dx_dev;
D3DPRESENT_PARAMETERS dx_pp = {0};

HWND the_hwnd;
HINSTANCE the_instance;
WNDCLASSEX wc;

int screen_width = 0;
int screen_height = 0;

#define CFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE)
struct CV
{
CV(FLOAT xx, FLOAT yy, FLOAT zz, DWORD cc)
{
x = xx;
y = yy;
z = zz;
color = cc;
}
FLOAT x, y, z;
DWORD color;
};

LPDIRECT3DVERTEXBUFFER9 vbo = NULL;

DWORD global_time = GetTickCount();

LRESULT CALLBACK window_process(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
HRESULT init_top_tasks(int w, int h);
void shutdown_top_tasks();
void enter_main_loop();
HRESULT init_dx();
HRESULT init_vbo();
void render();
void clean_up();
BOOL build_present_parameters();
void handle_keypress(WPARAM wparam);

//enables key press handling
#ifndef D3BUG
#define D3BUG
#endif

int WINAPI _tWinMain(HINSTANCE instance, HINSTANCE, LPTSTR, int nCmdShow)
{
the_instance = instance;

HRESULT result = init_top_tasks(1024, 576);

enter_main_loop();

shutdown_top_tasks();

return result;
}

HRESULT init_top_tasks(int w, int h)
{
screen_width = w;
screen_height = h;

ZeroMemory(&wc, sizeof(WNDCLASSEX));

wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = window_process;
wc.hInstance = the_instance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = L"WindowClass";

RegisterClassEx(&wc);

the_hwnd = CreateWindowEx(NULL,
L"WindowClass",
L"DX",
WS_OVERLAPPEDWINDOW,
20,
20,
screen_width,
screen_height,
NULL,
NULL,
the_instance,
NULL);

ShowWindow(the_hwnd, SW_SHOW);

return init_dx();
}

HRESULT init_dx()
{
HRESULT result;

dx = Direct3DCreate9(D3D_SDK_VERSION);

//build pp
if(!build_present_parameters())
{
return -1;
}

result = dx->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
the_hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&dx_pp,
&dx_dev);
if(FAILED(result))
{
return result;
}

result = dx_dev->SetRenderState(D3DRS_LIGHTING, FALSE);
if(FAILED(result))
{
return result;
}
result = dx_dev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
if(FAILED(result))
{
return result;
}
result = dx_dev->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
if(FAILED(result))
{
return result;
}
result = dx_dev->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
if(FAILED(result))
{
return result;
}
result = dx_dev->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
if(FAILED(result))
{
return result;
}

result = init_vbo();
if(FAILED(result))
{
return result;
}

return result;
}

BOOL build_present_parameters()
{
ZeroMemory(&dx_pp, sizeof(dx_pp));
dx_pp.Windowed = TRUE;
dx_pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
dx_pp.hDeviceWindow = the_hwnd;
dx_pp.BackBufferFormat = D3DFMT_X8R8G8B8;
dx_pp.BackBufferWidth = screen_width;
dx_pp.BackBufferHeight = screen_height;
dx_pp.EnableAutoDepthStencil = TRUE;
dx_pp.AutoDepthStencilFormat = D3DFMT_D16;

return TRUE;
}

HRESULT init_vbo()
{
HRESULT result;

CV vertices[] =
{
CV((FLOAT)screen_width / -2.0f, (FLOAT)screen_height / -2.0f, 0.0f, D3DCOLOR_XRGB(255, 255, 255)),
CV((FLOAT)screen_width / 2.0f, (FLOAT)screen_height / -2.0f, 0.0f, D3DCOLOR_XRGB(0, 255, 255)),
CV((FLOAT)screen_width / 2.0f, (FLOAT)screen_height / 2.0f, 0.0f, D3DCOLOR_XRGB(0, 0, 255)),
CV((FLOAT)screen_width / -2.0f, (FLOAT)screen_height / -2.0f, 0.0f, D3DCOLOR_XRGB(255, 255, 255)),
CV((FLOAT)screen_width / 2.0f, (FLOAT)screen_height / 2.0f, 0.0f, D3DCOLOR_XRGB(0, 255, 255)),
CV((FLOAT)screen_width / -2.0f, (FLOAT)screen_height / 2.0f, 0.0f, D3DCOLOR_XRGB(0, 0, 255))
};

result = dx_dev->CreateVertexBuffer(6 * sizeof(CV), 0, CFVF, D3DPOOL_MANAGED, &vbo, NULL);
if(FAILED(result))
{
return result;
}

VOID* v;

vbo->Lock(0, 0, (void**)&v, 0);
memcpy(v, vertices, sizeof(vertices));
vbo->Unlock();
return result;
}

void render()
{
D3DXMATRIX mat_world, mat_view, mat_proj;

dx_dev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);

dx_dev->BeginScene();

dx_dev->SetFVF(CFVF);

D3DXMatrixOrthoLH(&mat_proj, screen_width, screen_height, -1.0f, 1.0f);
dx_dev->SetTransform(D3DTS_PROJECTION, &mat_proj);

D3DXMatrixLookAtLH( &mat_view, &D3DXVECTOR3( 0.0f, 0.0f, 0.0f ),
&D3DXVECTOR3( 0.0f, 0.0f, -1.0f ),
&D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );
dx_dev->SetTransform( D3DTS_VIEW, &mat_view );

D3DXMatrixRotationY(&mat_world, D3DXToRadian(1.0f));
dx_dev->SetTransform(D3DTS_WORLD, &mat_world);

dx_dev->SetStreamSource(0, vbo, 0, sizeof(CV));
dx_dev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);

dx_dev->EndScene();
dx_dev->Present(NULL, NULL, NULL, NULL);
}

void shutdown_top_tasks()
{
clean_up();
}

void clean_up()
{
vbo->Release();
dx_dev->Release();
dx->Release();
SendMessage(the_hwnd, WM_DESTROY, NULL, NULL);
}

void enter_main_loop()
{
MSG msg;
int return_value;

if(dx_dev)
{
render();
}

//the main message pump
while((return_value = GetMessage(&msg, NULL, 0, 0)) != 0)
{
if(return_value == -1)
{
//error
break;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}

LRESULT CALLBACK window_process(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch(msg)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
break;
}
#ifdef D3BUG
case WM_KEYDOWN:
{
handle_keypress(wparam);
break;
}
#endif
default:
{
if(dx_dev)
{
int current_time = GetTickCount() - global_time;
if(current_time > 33)
{
render();
global_time = GetTickCount();
}
}
break;
}
}

return DefWindowProc(hwnd, msg, wparam, lparam);
}

void handle_keypress(WPARAM wparam)
{
switch(LOWORD(wparam))
{
default:
break;
};
}
[/code]

Share this post


Link to post
Share on other sites
Oh dx9 my bad - same deal...

[quote]dx_dev->SetTransform(D3DTS_WORLD, &mat_world);[/quote]
Wrong.

The world transform is your imaginary 3d pen...
Set the world transform to the one you created, just before u draw, to rotate and translate the thing you will render.
And if you need to move somewhere else in the world, set it again, then render.
Try that :)

Share this post


Link to post
Share on other sites
[quote name='__Homer__' timestamp='1312543031' post='4844950']
Oh dx9 my bad - same deal...

[quote]dx_dev->SetTransform(D3DTS_WORLD, &mat_world);[/quote]
Wrong.

The world transform is your imaginary 3d pen...
Set the world transform to the one you created, just before u draw, to rotate and translate the thing you will render.
And if you need to move somewhere else in the world, set it again, then render.
Try that :)


[/quote]

I did exactly that...check out the example that I posted, you can see that half of the full-screen quad is getting cut out...

Share this post


Link to post
Share on other sites
[quote name='__Homer__' timestamp='1312542719' post='4844949']
Dont use mat_world in the combined matrix u pass to the shader constant... use mat_w that u created, hehe :)
[/quote]

umm I use what I created, mat_w is in the first example, I posted the whole source where it is called mat_world

Share this post


Link to post
Share on other sites
ok, I finally got it, I just had to think about the orthographic projection frustum as a cuboid which is screen_width wide, screen_height tall, and has near z plane at screen_width / -2 and a far plane at screen_width / 2. so I had to set up the projection matrix like this:

D3DXMatrixOrthoLH(&mat_proj, screen_width, screen_height, (float)screen_width / -2.0f, (float)screen_width / 2.0f);

here's the full code (rotate it with space):
[code]
#define WIN32_LEAN_AND_MEAN

#include <Windows.h>
#include <d3d9.h>
#include <d3dx9.h>

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <tchar.h>
#include <sstream>
#include <stdexcept>

LPDIRECT3D9 dx;
LPDIRECT3DDEVICE9 dx_dev;
D3DPRESENT_PARAMETERS dx_pp = {0};

HWND the_hwnd;
HINSTANCE the_instance;
WNDCLASSEX wc;

int screen_width = 0;
int screen_height = 0;

#define CFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE)
struct CV
{
CV(FLOAT xx, FLOAT yy, FLOAT zz, DWORD cc)
{
x = xx;
y = yy;
z = zz;
color = cc;
}
FLOAT x, y, z;
DWORD color;
};

LPDIRECT3DVERTEXBUFFER9 vbo = NULL;

DWORD global_time = GetTickCount();

float rotation = 0.0f;

LRESULT CALLBACK window_process(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
HRESULT init_top_tasks(int w, int h);
void shutdown_top_tasks();
void enter_main_loop();
HRESULT init_dx();
HRESULT init_vbo();
void render();
void clean_up();
BOOL build_present_parameters();
void handle_keypress(WPARAM wparam);

//enables key press handling
#ifndef D3BUG
#define D3BUG
#endif

int WINAPI _tWinMain(HINSTANCE instance, HINSTANCE, LPTSTR, int nCmdShow)
{
the_instance = instance;

HRESULT result = init_top_tasks(1024, 576);

enter_main_loop();

shutdown_top_tasks();

return result;
}

HRESULT init_top_tasks(int w, int h)
{
screen_width = w;
screen_height = h;

ZeroMemory(&wc, sizeof(WNDCLASSEX));

wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = window_process;
wc.hInstance = the_instance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = L"WindowClass";

RegisterClassEx(&wc);

the_hwnd = CreateWindowEx(NULL,
L"WindowClass",
L"DX",
WS_OVERLAPPEDWINDOW,
20,
20,
screen_width,
screen_height,
NULL,
NULL,
the_instance,
NULL);

ShowWindow(the_hwnd, SW_SHOW);

return init_dx();
}

HRESULT init_dx()
{
HRESULT result;

dx = Direct3DCreate9(D3D_SDK_VERSION);

//build pp
if(!build_present_parameters())
{
return -1;
}

result = dx->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
the_hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&dx_pp,
&dx_dev);
if(FAILED(result))
{
return result;
}

result = dx_dev->SetRenderState(D3DRS_LIGHTING, FALSE);
if(FAILED(result))
{
return result;
}
result = dx_dev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
if(FAILED(result))
{
return result;
}
result = dx_dev->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
if(FAILED(result))
{
return result;
}
result = dx_dev->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
if(FAILED(result))
{
return result;
}
result = dx_dev->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
if(FAILED(result))
{
return result;
}

result = init_vbo();
if(FAILED(result))
{
return result;
}

return result;
}

BOOL build_present_parameters()
{
ZeroMemory(&dx_pp, sizeof(dx_pp));
dx_pp.Windowed = TRUE;
dx_pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
dx_pp.hDeviceWindow = the_hwnd;
dx_pp.BackBufferFormat = D3DFMT_X8R8G8B8;
dx_pp.BackBufferWidth = screen_width;
dx_pp.BackBufferHeight = screen_height;
dx_pp.EnableAutoDepthStencil = TRUE;
dx_pp.AutoDepthStencilFormat = D3DFMT_D16;

return TRUE;
}

HRESULT init_vbo()
{
HRESULT result;

CV vertices[] =
{
CV((FLOAT)screen_width / -2.0f, (FLOAT)screen_height / -2.0f, 0.0f, D3DCOLOR_XRGB(255, 255, 255)),
CV((FLOAT)screen_width / 2.0f, (FLOAT)screen_height / -2.0f, 0.0f, D3DCOLOR_XRGB(0, 255, 255)),
CV((FLOAT)screen_width / 2.0f, (FLOAT)screen_height / 2.0f, 0.0f, D3DCOLOR_XRGB(0, 0, 255)),
CV((FLOAT)screen_width / -2.0f, (FLOAT)screen_height / -2.0f, 0.0f, D3DCOLOR_XRGB(255, 255, 255)),
CV((FLOAT)screen_width / 2.0f, (FLOAT)screen_height / 2.0f, 0.0f, D3DCOLOR_XRGB(0, 255, 255)),
CV((FLOAT)screen_width / -2.0f, (FLOAT)screen_height / 2.0f, 0.0f, D3DCOLOR_XRGB(0, 0, 255))
};

result = dx_dev->CreateVertexBuffer(6 * sizeof(CV), 0, CFVF, D3DPOOL_MANAGED, &vbo, NULL);
if(FAILED(result))
{
return result;
}

VOID* v;

vbo->Lock(0, 0, (void**)&v, 0);
memcpy(v, vertices, sizeof(vertices));
vbo->Unlock();
return result;
}

void render()
{
D3DXMATRIX mat_world, mat_view, mat_proj;

dx_dev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);

dx_dev->BeginScene();

dx_dev->SetFVF(CFVF);

D3DXMatrixOrthoLH(&mat_proj, screen_width, screen_height, (float)screen_width / -2.0f, (float)screen_width / 2.0f);
dx_dev->SetTransform(D3DTS_PROJECTION, &mat_proj);

D3DXMatrixLookAtLH( &mat_view, &D3DXVECTOR3( 0.0f, 0.0f, 0.0f ),
&D3DXVECTOR3( 0.0f, 0.0f, -1.0f ),
&D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );
dx_dev->SetTransform( D3DTS_VIEW, &mat_view );

D3DXMatrixRotationY(&mat_world, D3DXToRadian(rotation));
dx_dev->SetTransform(D3DTS_WORLD, &mat_world);

dx_dev->SetStreamSource(0, vbo, 0, sizeof(CV));
dx_dev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);

dx_dev->EndScene();
dx_dev->Present(NULL, NULL, NULL, NULL);
}

void shutdown_top_tasks()
{
clean_up();
}

void clean_up()
{
vbo->Release();
dx_dev->Release();
dx->Release();
SendMessage(the_hwnd, WM_DESTROY, NULL, NULL);
}

void enter_main_loop()
{
MSG msg;
int return_value;

if(dx_dev)
{
render();
}

//the main message pump
while((return_value = GetMessage(&msg, NULL, 0, 0)) != 0)
{
if(return_value == -1)
{
//error
break;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}

LRESULT CALLBACK window_process(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch(msg)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
break;
}
#ifdef D3BUG
case WM_KEYDOWN:
{
handle_keypress(wparam);
break;
}
#endif
default:
{
if(dx_dev)
{
int current_time = GetTickCount() - global_time;
if(current_time > 33)
{
render();
global_time = GetTickCount();
}
}
break;
}
}

return DefWindowProc(hwnd, msg, wparam, lparam);
}

void handle_keypress(WPARAM wparam)
{
switch(LOWORD(wparam))
{
case 0x20:
{
rotation += 1.0f;
}
default:
break;
};
}
[/code]

Share this post


Link to post
Share on other sites

This topic is 2324 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.

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