Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Poki027

Pages: [1]
1
Graphics / How to DRAW custom shapes?
« on: January 15, 2022, 01:32:45 pm »
Hi! I'm trying to make a 3D engine with SFML, and for now it's going quite well.
I'm using a single "cube" to test out different things, which was just a sf::VertexArray.
The problem appears once I want to use multiple cubes since I have to use nested for loops (one for the number of cubes, one for the 8 vertices of the cubes) or just one for loop, but either way, I want to avoid doing it like that since it doesn't feel expandable and easy to use. I would like to be able to instantiate the cubes like this for example:
sf::VertexArray cubes(sf::Cubes, 10); // create 10 cubes
 
and then draw them like so:
window.draw(cubes);
 
I can't understand how to set up custom shapes tho and https://www.sfml-dev.org/tutorials/2.0/graphics-shape.php doesn't really help me.

This is the current cube code:
struct Cube
{
        float scale;
        Vector3 pos;
        Vector3 vertexLocal[8] =
        {
                // Front face
                Vector3(-1.0, -1.0,  1.0),
                Vector3(1.0, -1.0,  1.0),
                Vector3(1.0,  1.0,  1.0),
                Vector3(-1.0,  1.0,  1.0),

                // Back face
                Vector3(-1.0, -1.0, -1.0),
                Vector3(1.0,  -1.0, -1.0),
                Vector3(1.0,  1.0, -1.0),
                Vector3(-1.0, 1.0, -1.0)                         
        };             
        Vector3 vertexGlobal[8];
        float vertexDistances[8];
       
        Cube(const float _scale)
        {
                scale = _scale;
                for(int v = 0; v < 8; v++)
                {
                        vertexGlobal[v] = Vector3(vertexLocal[v].x + pos.x, vertexLocal[v].y + pos.y, vertexLocal[v].z + pos.z);                               
                        vertexDistances[v] = sqrt((vertexLocal[v].x - pos.x)*(vertexLocal[v].x - pos.x) + (vertexLocal[v].y - pos.y)*(vertexLocal[v].y - pos.y) + (vertexLocal[v].z - pos.z)*(vertexLocal[v].z - pos.z));
                        vertexGlobal[v] *= scale;
                        vertexDistances[v] *= scale;
                        //vertexGlobal[i] = Vector3(vertexGlobal[i].x / 2, vertexGlobal[i].y / 2, vertexGlobal[i].z / 2);
                        vertexGlobal[v].UpdateVector();
                }              
        }
       
        void UpdateCube()
        {
                for(int i = 0; i < 8; i++)
                {
                        vertexGlobal[i] = Vector3(vertexLocal[i].x + pos.x, vertexLocal[i].y + pos.y, vertexLocal[i].z + pos.z);
                        vertexGlobal[i] *= scale;
                        vertexGlobal[i].UpdateVector();
                        vertexLocal[i].UpdateVector();
                }              
        }
};

And this is how I'm showing the vertices on the screen:
class Camera
{
        public:
                float nearClippingPlane, farClippingPlane, fieldOfView, focalLength;
                Vector3 position, rotation, resolution;
                vector<Vector3> verticesOnScreen, verticesOffScreen;
               
                Camera(float _nearClippingPlane, float _farClippingPlane, float focal, Vector3 res)
                {
                        nearClippingPlane = _nearClippingPlane;
                        farClippingPlane = _farClippingPlane;
                        focalLength = focal;
                        fieldOfView = 2 * atan(res.x / (2 * focal));
                        resolution = res;
                       
                        if(!verticesOnScreen.empty())
                                verticesOnScreen.clear();
                        if(!verticesOffScreen.empty())
                                verticesOffScreen.clear();     
                }
               
                Camera()
                {
                        nearClippingPlane = 1.0f;
                        farClippingPlane = 100.0f;
                        fieldOfView = 60.0f;
                        resolution = Vector3(W_SCREEN, H_SCREEN, 0);
                }
               
                Vector3 WorldToCamera(Vector3 vertex)
                {
                        //cout << "WorldToCamera: " << vertex.x << " : " << scaleFactor << endl;
                        vertex += position;
                        vertex.UpdateVector();
                        vertex.z *= -1; //invert the camera's view (or else it would appear we are looking "through" a mirror)
                        if(vertex.z < nearClippingPlane + position.z) //if the vertex's z coordinate is smaller than the near clipping plane's
                                vertex.z = nearClippingPlane;                           // distance from the camera, clip the vertex's z to the value of near clipping plane's distance
                        //treat camera's position as 0, 0, 0 if using verToCam variable
                        vertex.x *= (focalLength / vertex.z);
                        vertex.y *= (focalLength / vertex.z);
                        //cout << "wtc" << endl;
                        //cout << "WorldToCamera: " << output.x << " : " << scaleFactor << endl;
                        return vertex;
                }      
               
                sf::Vector2f CameraToScreen(Vector3 vertex)
                {
                        Vector3 cam = WorldToCamera(vertex);
                        cam.UpdateVector();
                        //cout << "CameraToScreen: " << cam.x << endl;
                        return sf::Vector2f(-cam.x + W_SCREEN/2, -cam.y + H_SCREEN/2); //center the coords to the screen and return them
                }
};
 
I'm still a bit new to posting on forums, so if you need more information, just ask and I'll provide.

Pages: [1]