Joaquim Posted August 7, 2022 Posted August 7, 2022 i need 1 correction: the screen only use 2D(X, Y) and not 3D(X, Y, Z)... so how can i create the perspective? is these math correct: PosX2D = PosX3D /(FocalDistance+PosZ3D); PosY2D = PosY3D /(FocalDistance+PosZ3D) ? i have seen several tutorials and seems that they have their own Perspective. understand these, i can create my own polygon and move front-back, and left-right.
jumper Posted August 8, 2022 Posted August 8, 2022 Those are good to start with. Sort your points by depth (z) and draw from back to front. 1
Joaquim Posted August 8, 2022 Author Posted August 8, 2022 (edited) Is always best the window center be the point 0,0? And using float positions? Then i must trunc() or round() to convert to integer? Edited August 8, 2022 by Joaquim
jumper Posted August 9, 2022 Posted August 9, 2022 Experiment. Don't be afraid to try a bunch of variations. It's only software.
Joaquim Posted August 9, 2022 Author Posted August 9, 2022 I'm asking because of results. But i need add a correction for dont draw behind the player.
Joaquim Posted August 10, 2022 Author Posted August 10, 2022 done code: #include <windows.h> #include <iostream> #include <algorithm> #include <vector> #include <math.h> using namespace std; HDC HDCConsole = GetWindowDC(GetConsoleWindow()); struct position { float Pos3DX; float Pos3DY; float Pos3DZ; float PosX; float PosY; POINT Perspective(int FocalDistance, POINT Center={0,0}) { float PosX2D = Pos3DX /(FocalDistance+Pos3DZ)+ Center.x; float PosY2D = Pos3DY /(FocalDistance+Pos3DZ)+Center.y; POINT pos; pos.x=round(PosX2D); pos.y=round(PosY2D); return pos; } }; void DrawPolygon(HDC HDCDestination, vector<position> Points, HPEN &LineColor, HBRUSH &PlaneColor) { HPEN hOldPen = (HPEN)SelectObject(HDCDestination, LineColor); HBRUSH hOldBrush = (HBRUSH)SelectObject(HDCDestination, PlaneColor); POINT pos[Points.size()]; for(unsigned int index=0; index<Points.size(); index++) { pos[index]=Points[index].Perspective(300,{0,0}); } if(Polygon(HDCDestination,pos,4)==FALSE) MessageBox(NULL,"error","error", MB_OK); SelectObject(HDCDestination, hOldPen); SelectObject(HDCDestination, hOldBrush); } int main() { vector<position> Rec; Rec.push_back({0,0,0}); Rec.push_back({10,0,0}); /*Rec.push_back({10,10,0}); Rec.push_back({0,10,0}); Rec.push_back({0,0,0});*/ HPEN hPen1 = CreatePen(PS_SOLID, 1, RGB(0, 255, 0)); HBRUSH hPlane = CreateSolidBrush(RGB(0,255,0)); do { DrawPolygon(HDCConsole,Rec,hPen1,hPlane); }while(!(GetKeyState(VK_ESCAPE) & 0x8000)); DeleteObject(hPen1); DeleteObject(hPlane); return 0; } see the perspetive(): POINT Perspective(int FocalDistance, POINT Center={0,0}) { float PosX2D = Pos3DX /(FocalDistance+Pos3DZ)+ Center.x; float PosY2D = Pos3DY /(FocalDistance+Pos3DZ)+Center.y; POINT pos; pos.x=round(PosX2D); pos.y=round(PosY2D); return pos; } see on the Polygon(): POINT pos[Points.size()]; for(unsigned int index=0; index<Points.size(); index++) { pos[index]=Points[index].Perspective(300,{0,0}); } if(Polygon(HDCDestination,pos,4)==FALSE) MessageBox(NULL,"error","error", MB_OK); if the center is {0,0} the line isn't showed. if the center is {100,100}... the line is showed. The X seems ok... but Y ins't... the line seems drawed much more than window. int main() { vector<position> Rec; Rec.push_back({0,0,0}); Rec.push_back({10,0,0}); /*Rec.push_back({10,10,0}); Rec.push_back({0,10,0}); Rec.push_back({0,0,0});*/ so what is wrong with my perspective code?
Joaquim Posted August 11, 2022 Author Posted August 11, 2022 heres my perspective function: POINT Perspective(int FocalDistance, POINT Center={0,0}) { float PosX2D = Pos3DX /(FocalDistance+Pos3DZ)+ Center.x; float PosY2D = Pos3DY /(FocalDistance+Pos3DZ)+Center.y; POINT pos; pos.x=round(PosX2D); pos.y=round(PosY2D); return pos; } these function is wrong... how the perspective function works: 1 - we must calculate the perspective(please use float or double types on divisions): float Perspective = FocalLenght / (FocalLenght + PolygonPosZ); 2 - using the Perspective, we can change the shape scale or position(scale too): float PosX2D = Pos3DX * Perspective; float PosY2D = Pos3DY * Perspective; 3 - now we can add the center of screen to the position: PosX2D = PosX2D + ViewCenter.x; PosY2D = PosY2D + ViewCenter.y; 4 - the Polygon()(for example) use the POINT pointer.. the POINT structer use LONG type(integers)... so we need use the trunc() function for convert them: POINT pos; pos.x=trunc(PosX2D); pos.y=trunc(PosY2D); now i can draw a polygon: vector<position> Polygon3D={ {30, 145,0}, {85, 165,0}, {105, 110,10}, {65, 125,10}, {30, 105,0} }; vector<POINT> polygon; for(int index=0; index<Polygon3D.size(); index++) { polygon.push_back(Polygon3D[index].Perspective(300,{WindowSize.right/2, WindowSize.bottom/2 })); } //... DrawPolygon(HDCConsole,polygon,hPen1,hPlane); void DrawPolygon(HDC HDCDestination, vector<POINT> points, HPEN LineColor, HBRUSH PlaneColor) { HPEN hOldPen = (HPEN)SelectObject(HDCDestination, LineColor); HBRUSH hOldBrush = (HBRUSH)SelectObject(HDCDestination, PlaneColor); Polygon(HDCDestination,points.data(),points.size()); SelectObject(HDCDestination, hOldPen); SelectObject(HDCDestination, hOldBrush); } yes the 'data()' give us in right vector type type. see the result: https://imgur.com/DcU5Aov thank you so much for all. in time i will create a wall shape for test.
Joaquim Posted August 14, 2022 Author Posted August 14, 2022 'DrawPolygon()' draw a wall... but how can i control the draw position? i can't draw something less than zero Z(behind the player\window\view)... so how can i control it?
jumper Posted August 14, 2022 Posted August 14, 2022 Model in 3D. Use your transforms to convert to a 2D viewport (window). Scale to screen coordinates. If you are already clipping in 2D to the viewport, then you only need to clip the polygons in 3D to the viewplane (plane perpendicular to the direction the viewer is looking). Harder but potentially more efficient is clipping polygons in 3D to the planes from the viewpoint to each of the four viewport sides. Actually, 3D clipping is too advanced for now. Just keep all your models in positive z space until you have everything else working. And use triangles, not polygons, to simplify rendering. Later you can support rectangles and arbitrary polygons by breaking them down into triangles. 1
Joaquim Posted August 15, 2022 Author Posted August 15, 2022 Yes i'm trying clipping the 3D shape. I try avoid the Z negative. But the wrong coordenates continue happen... so what you advice more? Anotherthing is best create my own function for draw a line?
Joaquim Posted August 16, 2022 Author Posted August 16, 2022 (edited) i think i know the problem: the polygon is a serie of lines\dots. but some can be from right to left(normaly the Destination is more far and not more close ). heres the position structure: struct position { float Pos3DX; float Pos3DY; float Pos3DZ; float PosX; float PosY; //Convert 3D to 2D: POINT Perspective(int FocalDistance=300, POINT Center={0,0}) { if(Pos3DZ==0) Pos3DZ=1; float perspect=FocalDistance/(FocalDistance+Pos3DZ); float PosX2D = Pos3DX*perspect + Center.x; float PosY2D = Pos3DY*perspect + Center.y; POINT pos; pos.x=trunc(PosX2D); pos.y=trunc(PosY2D); return pos; } }; and see the GetLineZZero() header: position GetLineZZero(position Origin, position Destination) imagine if the 'Destination' is a Left point and the Origin is the Right point.... how can i compare the values? is just like: if(Destination.Pos3DX < Origin.Pos3DX || Destination.Pos3DY < Origin.Pos3DY || Destination.Pos3DZ < Origin.Pos3DZ) SwapPosition(Origin,Destination);//Swap function not created i'm I right? Edited August 16, 2022 by Joaquim
Joaquim Posted August 16, 2022 Author Posted August 16, 2022 and worst.. i tested just with 1 line, and seems not working lol i must retest the GetLineZZero() and DrawPolygon().
jasonjulius1122 Posted July 7, 2023 Posted July 7, 2023 On 8/7/2022 at 3:45 PM, Joaquim said: i need 1 correction: the screen only use 2D(X, Y) and not 3D(X, Y, Z)... so how can i create the perspective? is these math correct: PosX2D = PosX3D /(FocalDistance+PosZ3D); PosY2D = PosY3D /(FocalDistance+PosZ3D) ? i have seen several tutorials and seems that they have their own Perspective. understand these, i can create my own polygon and move front-back, and left-right. Sure, let's simplify it: Your formulas are a type of 3D to 2D perspective projection. However, it's more common to divide by Z alone, not the sum of focal distance and Z: PosX2D = (FocalDistance * PosX3D) / PosZ3D; PosY2D = (FocalDistance * PosY3D) / PosZ3D; This provides a "camera" view, with objects appearing smaller the further they are. Note, this won't handle viewport transformations, and objects at Z=0 or negative Z may cause issues.
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now