παπι Δημοσ. 27 Φεβρουαρίου 2013 Δημοσ. 27 Φεβρουαρίου 2013 Απλα λεω να μοιρασω αυτο το περιεργο πραγμα που εφτιαξα. //papi #define USEWIN 0 #define NOMINMAX #include <Windows.h> #include <algorithm> #include <iterator> #include <string> #include <vector> #include <iostream> class Console2D { int height,width; char background; struct {float x,y;} cursor; std::vector<char> buffer; std::vector<char> backbuffer; public: Console2D(int height, int width,char background = ' ') : height(height), width(width), background(background) , buffer(height*width) { cursor.x = 0.0f; cursor.y = 0.0f; std::fill(buffer.begin(),buffer.end(),background); } void Clear() { std::fill(buffer.begin(),buffer.end(),background); system("cls"); } void Present() { PresentEx(); return; int pad = 1; for(auto it = buffer.begin(); it != buffer.end(); it++,pad++) { std::cout<<*it; if(!(pad % width)) std::cout<<std::endl; } } void PresentEx() { //h console pio argh kai apo to 8anato.... int pad = 1; std::string tmp; for(auto it = buffer.begin(); it != buffer.end(); it++,pad++) { tmp.push_back(*it); if(!(pad % width)) { std::string tmp1; std::reverse(tmp.begin(),tmp.end()); for(auto t = tmp.begin(); t!= tmp.end(); ++t) { if(*t == ' ') continue; tmp1.assign(t,tmp.end()); break; } std::reverse(tmp1.begin(),tmp1.end()); std::cout<<tmp1<<std::endl; tmp.clear(); } } } void Plot(int x, int y) { int p = y * width + x ; if(x < 0 || x > width ||y < 0 || y > height) return; buffer[p] = '*'; } void LineTo(float x,float y) { Line(cursor.x,cursor.y,x,y); SetCursor(x,y); } void SetCursor(float x,float y) { cursor.x = x; cursor.y = y; } void Line(float x0,float y0,float x1,float y1) { float x = x1-x0; float y = y1-y0; float len = std::sqrt(x*x+y*y); x /= len; y /= len; for(float i = 0.f -len; i < 0.f; i+= 1.f) Plot((x0 + x * (len + i)) , (y0 + y * ( len +i )) ); } int Height(){return this->height;} int Width(){return this->width;} }; struct Vector3 { float x,y,z; Vector3()(0.f),y(0.f),z(0.f) { } Vector3(float x, float y, float z) : x(x),y(y),z(z) { } Vector3 operator/ (float n) { if(n) return Vector3(x/n,y/n,z/n); return Vector3(); } Vector3 operator- (const Vector3& r) const { return Vector3(x-r.x,y-r.y,z-r.z); } Vector3& operator/= (float n) { *this = *this / n; return *this; } Vector3& Normalize() { *this /= this->Len(); return *this; } Vector3 Cross(const Vector3& r) const { return Vector3( y * r.z - z * r.y, z * r.x - x * r.z, x * r.y - y * r.x); } float Dot(const Vector3& r) const { return x * r.x + y * r.y + z * r.z; } float Len() const { return std::sqrt(x*x + y*y + z*z); } }; struct Matrix4 { float m[4][4]; Matrix4() { for(int i = 0; i < 4;i++) for(int j = 0; j < 4; j++) m[i][j] = 0.0f; } void Identity() { /* identity matrix [ 1 0 0 0 ] [ 0 1 0 0 ] [ 0 0 1 0 ] [ 0 0 0 1 ] */ for(int i = 0; i < 4;i++) for(int j = 0; j < 4; j++) { if(j == i) //diagwnios m[i][j] = 1.0f; else m[i][j] = 0.0f; } } Vector3 TransformVec3(const Vector3& v) const { Vector3 res; float n = m[0][3]*v.x + m[1][3] * v.y + m[2][3] * v.z + m[3][3]; if(n) { res.x = (m[0][0]*v.x + m[1][0]*v.y + m[2][0]*v.z + m[3][0]) / n; res.y = (m[0][1]*v.x + m[1][1]*v.y + m[2][1]*v.z + m[3][1]) / n; res.z = (m[0][2]*v.x + m[1][2]*v.y + m[2][2]*v.z + m[3][2]) / n; } else res.x = res.y = res.z = 0.0f; return res; } //3d left handed!!!!!! void RotateX(float r) { /* [ 1, 0, 0, 0] Rx = [ 0, cos(r),sin(r), 0] [ 0,-sin(r),cos(r), 0] [ 0, 0, 0, 1] */ this->Identity(); m[1][1] = std::cos(r); m[1][2] = std::sin(r); m[2][1] = -std::sin(r); m[2][2] = std::cos(r); } void RotateY(float r) { /* [cos(r), 0,-sin(r), 0] Ry = [ 0, 1, 0, 0] [sin(r), 0, cos(r), 0] [ 0, 0, 0, 1] */ this->Identity(); m[0][0] = std::cos(r); m[0][2] = -std::sin(r); m[2][0] = std::sin(r); m[2][2] = std::cos(r); } void RotateZ(float r) { /* [ cos(r),sin(r), 0, 0] Rz = [-sin(r),cos(r), 0, 0] [ 0, 0, 1, 0] [ 0, 0, 0, 1] */ this->Identity(); m[0][0] = std::cos(r); m[0][1] = std::sin(r); m[1][0] = -std::sin(r); m[1][1] = std::cos(r); } void Scaling(float x,float y,float z) { this->Identity(); m[0][0] = x; m[1][1] = y; m[2][2] = z; } void Translation(float x, float y, float z) { this->Identity(); m[0][3] = x; m[1][3] = y; m[2][3] = z; } void ProjectionPerspectiveLH(float nearp, float farp, float aspect,float fovy) { /*http://msdn.microsoft.com/en-us/library/bb205350(VS.85).aspx xScale 0 0 0 0 yScale 0 0 0 0 zf/(zf-zn) 1 0 0 -zn*zf/(zf-zn) 0 where: yScale = cot(fovY/2) xScale = yScale / aspect ratio */ float yScale = 1.0f / std::tan(fovy / 2.0f); float xScale = yScale / aspect; m[0][0] = xScale; m[1][1] = yScale; m[2][2] = farp / (farp-nearp); m[2][3] = 1.0f; m[3][2] = -(nearp*farp)/(farp-nearp); } void LookAtLH(const Vector3& eye,const Vector3& at, const Vector3& up) { /*http://msdn.microsoft.com/en-us/library/windows/desktop/bb205342(v=vs.85).aspx zaxis = normal(At - Eye) xaxis = normal(cross(Up, zaxis)) yaxis = cross(zaxis, xaxis) xaxis.x yaxis.x zaxis.x 0 xaxis.y yaxis.y zaxis.y 0 xaxis.z yaxis.z zaxis.z 0 -dot(xaxis, eye) -dot(yaxis, eye) -dot(zaxis, eye) 1 */ this->Identity(); Vector3 z = at-eye; Vector3 x = up.Cross(z.Normalize()); Vector3 y = z.Cross(x); m[0][0] = x.x; m[0][1] = y.x; m[0][2] = z.x; m[1][0] = x.y; m[1][1] = y.y; m[1][2] = z.y; m[2][0] = x.z; m[2][1] = y.z; m[2][2] = z.z; m[3][0] = -x.Dot(eye); m[3][1] = -y.Dot(eye); m[3][2] = -z.Dot(eye); } void Viewport(int height, int widht) { /* http://msdn.microsoft.com/en-us/library/windows/desktop/bb206341(v=vs.85).aspx [ x 0 0 0] [ 0 y 0 0] [ 0 0 z 0] [ i j m 1] x = widht / 2 y = -(height / 2) z = maxDepth - minDepth (z) i = X + widht / 2 (X = viewport corners) j = Y + height / 2 (Y = --//--) m = minZ */ this->Identity(); m[0][0] = float(widht) / 2.0f; m[1][1] = -float(height) / 2.0f; m[2][2] = 1.0f; // max 1 min 0 m[3][0] = float(widht) / 2.0f; m[3][1] = float(height) / 2.0f; m[3][2] = 0.0f; } //operators float& operator() (int i,int j) { return m[i][j]; } float operator() (int i,int j) const { return m[i][j]; } Matrix4 operator* (const Matrix4& r) { /* matrix mul [a b] [1 2] = [ a1 + b3 a2 + b4 ] [c d] * [3 4] [ c1 + d3 d2 + d4 ] */ Matrix4 res; for(int i = 0; i < 4; i++)//row for(int j = 0; j < 4; j++)//col for(int c = 0; c < 4; c++)//cross res(i,j) += m[i][c] * r(c,j); return res; } Matrix4& operator*= (const Matrix4& r) { *this = *this * r; return *this; } }; #if USEWIN //win interface LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wParam, LPARAM lParam); void RenderTriangleTopology(HDC hdc, const std::vector<Vector3>& vertices,const std::vector<unsigned>& indices, const Matrix4& wvp); #endif void RenderTriangleTopology(Console2D& console,const std::vector<Vector3>& vertices,const std::vector<unsigned>& indices, const Matrix4& wvp); void InitBuffers(); std::vector<Vector3> g_verticesBuffer; std::vector<unsigned> g_indicesBuffer; int height = 600; int width = 600; int main(int argc, char **argv) { Console2D console(50,70,' '); InitBuffers(); #if USEWIN HWND hWnd; MSG msg; WNDCLASSEX cl = { 0 }; cl.cbSize = sizeof(cl); cl.hCursor = LoadCursor(0,IDC_ARROW); cl.lpszClassName = L"OutputWindow"; cl.lpfnWndProc = WndProc; RegisterClassEx(&cl); hWnd = CreateWindow(L"OutputWindow",L"Output",WS_VISIBLE,CW_USEDEFAULT,0,width,height,0,0,0,&console); ShowWindow(hWnd, SW_SHOW); while(GetMessage(&msg,0,0,0) > 0) DispatchMessage(&msg); #else Matrix4 view,viewport,projecting,rotation,wvp; view.LookAtLH(Vector3(0.0f,0.0f,-4.0f),Vector3(0.0f,0.0f,0.0f),Vector3(0.0f,1.0f,0.0f)); projecting.ProjectionPerspectiveLH(1.0f,1000.0f,console.Width()/console.Height(),3.14f/4.0f); viewport.Viewport(console.Height(),console.Width()); for(float pi = 0.0f; pi <3.14f * 10; pi+= 0.1f) { rotation.RotateY(pi); wvp = rotation * view * projecting * viewport; RenderTriangleTopology(console,g_verticesBuffer,g_indicesBuffer,wvp); Sleep(100); } #endif return 0; } void RenderTriangleTopology(Console2D& console,const std::vector<Vector3>& vertices,const std::vector<unsigned>& indices, const Matrix4& wvp) { if(indices.size() % 3) throw std::exception("Mono set twn triwn"); console.Clear(); for(std::vector<unsigned>::const_iterator idx = indices.begin(); idx != indices.end(); ++idx) { Vector3 p1,p2,p3; p1 = wvp.TransformVec3(vertices[ *idx ]); idx++; p2 = wvp.TransformVec3(vertices[ *idx ]); idx++; p3 = wvp.TransformVec3(vertices[ *idx ]); console.Line(p1.x,p1.y,p2.x,p2.y); console.Line(p1.x,p1.y,p3.x,p3.y); console.Line(p3.x,p3.y,p2.x,p2.y); } console.Present(); } void InitBuffers() { //enas kybos //6 shmeia g_verticesBuffer.push_back(Vector3(-1.0f,-1.0f,-1.0f)); g_verticesBuffer.push_back(Vector3(-1.0f,+1.0f,-1.0f)); g_verticesBuffer.push_back(Vector3(+1.0f,+1.0f,-1.0f)); g_verticesBuffer.push_back(Vector3(+1.0f,-1.0f,-1.0f)); g_verticesBuffer.push_back(Vector3(-1.0f,-1.0f,+1.0f)); g_verticesBuffer.push_back(Vector3(-1.0f,+1.0f,+1.0f)); g_verticesBuffer.push_back(Vector3(+1.0f,+1.0f,+1.0f)); g_verticesBuffer.push_back(Vector3(+1.0f,-1.0f,+1.0f)); //syndesh shmeiwn //mpros g_indicesBuffer.push_back(0); g_indicesBuffer.push_back(1); g_indicesBuffer.push_back(2); g_indicesBuffer.push_back(0); g_indicesBuffer.push_back(2); g_indicesBuffer.push_back(3); //kwlos g_indicesBuffer.push_back(4); g_indicesBuffer.push_back(6); g_indicesBuffer.push_back(5); g_indicesBuffer.push_back(4); g_indicesBuffer.push_back(7); g_indicesBuffer.push_back(6); //Tsipras g_indicesBuffer.push_back(4); g_indicesBuffer.push_back(5); g_indicesBuffer.push_back(1); g_indicesBuffer.push_back(4); g_indicesBuffer.push_back(1); g_indicesBuffer.push_back(0); //kasidiaris g_indicesBuffer.push_back(3); g_indicesBuffer.push_back(2); g_indicesBuffer.push_back(6); g_indicesBuffer.push_back(3); g_indicesBuffer.push_back(6); g_indicesBuffer.push_back(7); //patos g_indicesBuffer.push_back(4); g_indicesBuffer.push_back(0); g_indicesBuffer.push_back(3); g_indicesBuffer.push_back(4); g_indicesBuffer.push_back(3); g_indicesBuffer.push_back(7); } #if USEWIN void RenderTriangleTopology(HDC hdc, const std::vector<Vector3>& vertices,const std::vector<unsigned>& indices, const Matrix4& wvp) { if(indices.size() % 3) throw std::exception("Mono set twn triwn"); for(std::vector<unsigned>::const_iterator idx = indices.begin(); idx != indices.end(); ++idx) { Vector3 p1,p2,p3; p1 = wvp.TransformVec3(vertices[ *idx ]); idx++; p2 = wvp.TransformVec3(vertices[ *idx ]); idx++; p3 = wvp.TransformVec3(vertices[ *idx ]); MoveToEx(hdc,p1.x,p1.y,0); LineTo(hdc,p1.x,p1.y); LineTo(hdc,p2.x,p2.y); LineTo(hdc,p3.x,p3.y); LineTo(hdc,p1.x,p1.y); } } LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HGDIOBJ hOld,hPen; static Console2D *console; Matrix4 view,proj,projConsole,rot,scaling,viewport,viewportConsole,worldTransformationViewProjection,wvpConsole; static float pi = 0.0f; switch(msg) { case WM_TIMER: if(pi > 3.14f) pi = 0.0f; pi+= 0.01f; InvalidateRect(hWnd,0,1); break; case WM_CREATE: console = (Console2D*)((CREATESTRUCT*)lParam)->lpCreateParams; SetTimer(hWnd,0,300,0); break; case WM_PAINT: BeginPaint(hWnd,&ps); //clear bk FillRect(ps.hdc,& ps.rcPaint,(HBRUSH) (COLOR_WINDOW + 1)); hPen = CreatePen(PS_SOLID,1,RGB(0,200,0)); hOld = SelectObject(ps.hdc,hPen); // //camera view.LookAtLH( Vector3(0.0f,0.0f,-3.0f),// thesh Vector3(0.0f,0.0f,0.0f),// stoxos Vector3(0.0f,1.0f,0.0f)// y einai to panw ); // perspective: dinei thn esthish toy xwroy (meros tis cameras kai ayto) // projection: provaloyme to 3d kosmo se ena "toixo" na to pw... proj.ProjectionPerspectiveLH(1.0f,1000.0f,width/height,3.14f/4.0f); //gia thn console projConsole.ProjectionPerspectiveLH(1.0f,1000.0f,console->Width()/console->Height(),3.14f/4.0f); //viewport to teleiko soloupoma gia na xwresei sto output tou window viewport.Viewport(height,width); //allh mia gia thn console viewportConsole.Viewport(console->Height(),console->Width()); //rotation rot.RotateY(pi); //scaling scaling.Scaling(0.7f,0.7f,0.7f); //gia to window worldTransformationViewProjection = rot * scaling * view * proj * viewport; //gia th console wvpConsole = rot * scaling * view * projConsole * viewportConsole; RenderTriangleTopology(ps.hdc,g_verticesBuffer,g_indicesBuffer,worldTransformationViewProjection); RenderTriangleTopology(*console,g_verticesBuffer,g_indicesBuffer,wvpConsole); // DeleteObject(SelectObject(ps.hdc,hOld)); EndPaint(hWnd,&ps); break; default: return DefWindowProc(hWnd,msg,wParam,lParam); } return 0; } #endif 4
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα