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:
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
Best regards,
Yours3!f
Cancel
Save
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.
Cancel
Save
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.
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:
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;
}
I guess this doesn't change much right?
Cancel
Save
I simplified the whole app to 317 lines, here's the 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;
};
}
Cancel
Save
Dont use mat_world in the combined matrix u pass to the shader constant... use mat_w that u created, hehe
Cancel
Save
In C++, friends have access to your privates.
In ObjAsm, your members are exposed!
Oh dx9 my bad - same deal...
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
Cancel
Save
In C++, friends have access to your privates.
In ObjAsm, your members are exposed!
Oh dx9 my bad - same deal...
dx_dev->SetTransform(D3DTS_WORLD, &mat_world);
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...
Cancel
Save
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):
#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;
};
}
Cancel
Save