how send a function array parameter?

heres how i call the function:
1
2
3
 unsigned int PixelColors[ConsoleHeight][ConsoleWidth];
// draw a line:
        DrawLine3D(PixelColors,RotOrigin,RotDestination, RGB(0,255,0) );

the function:
1
2
3
4
5
6
7
8
9
10
11
void DrawLine3D(unsigned int *&Pixels, Position3D Origin, Position3D Destination, COLORREF Color)
{
    std::vector<Position3D> GetLineDots = GetLinePoints(Origin, Destination);
    for(int x=0; x<GetLineDots.size()-1; x++)
    {
        unsigned int X = GetLineDots[x].PosX;
        unsigned int Y = GetLineDots[x].PosY;

        Pixels[X] [Y] = Color;
    }
}

i get an error on 'Pixels[X] [Y] = Color;': "invalid types 'unsigned int[unsigned int]' for array subscript".
how can i fix the code?
'PosX' and 'PosY' are float types
Last edited on
Pixels is a pointer to unsigned int, but you're trying to dereference it twice. If you need to flatten a 2D coordinate for rectangular data, you'd do something like:
1
2
size_t index = width * y + x;
Pixels[index] = value;


PS: Passing Pixels as a reference is unnecessary since you never overwrite the value of Pixels itself.
Last edited on
'DrawLine3D()' don't recive size parameters.
if i do 'void DrawLine3D(unsigned int Pixels[],'.. works but the array have only 1 dimension... but how i change for 2 dimensions?
"unsigned int Pixels[]" and "unsigned int* Pixels" as function parameters mean the same exact thing, it's just syntax sugar to use the [].

As seen in your other thread, the Win32 call StretchDIBits inevitably expects the lpBits data to be representable as one contiguous 1D array. So you can cast the 2D array to fake it as a 1D pointer, or you could just have a 1D array to begin with.(*) The latter seems simpler to me, but I guess either way works.

You own the DrawLine3D function. Add a parameter that tells the function what the width is. Pass in ConsoleWidth tp DrawLines3D, then you can do
pixels[y * ConsoleWidth + x] = Color;

Also,
1
2
3
4
5
6
7
    operator Position2D()
    {
        Position2D Pos2D{PosX, PosY};
        Pos2D.PosX = PosX;
        Pos2D.PosY = PosY;
        return Pos2D;
    }

This is redundant. You could just do
1
2
3
4
    operator Position2D()
    {
        return Pos2D{PosX, PosY};
    }



(*)This is what I mean here. Again, it appears to not be necessary, but would prevent unnecessary weird casts.
1
2
3
4
5
6
7
8
9
10
11
unsigned int PixelColors[ConsoleHeight * ConsoleWidth];

// ...

for(int y=0; y<ConsoleHeight; y++)
{
    for(int x=0; x<ConsoleWidth; x++)
    {
        PixelColors[y * ConsoleWidth + x] = RGB(0,0,255);
    }
}
Last edited on
i'm so sorry, but can i pass a 2D array or vector for a parameter function?
As long as ConsoleWidth is a global constant, you can do this:

 
void DrawLine3D(unsigned Pixels[][ConsoleWidth], etc...)


can i do it without the 'ConsoleWidth' on parameter declaration?
With array, no. You need the non-inner dimension so the compiler knows the pointer offsets.

With vector, yes. You can pass a vector of vectors as a parameter, and then query the .size() of each inner vector to know the width. But this is (1) less efficient since each vector is a separate allocation, and (2) not compatible with what StretchDIBits requires, since it requires one contiguous array.

What is so bad about adding a parameter to DrawLine3D, since you are able to change the function signature?
Last edited on
Are you saying that ConsoleHeight and ConsoleWidth are not constant?
That is a non-standard extension to C++ from C99.

Anyway, you could flatten the array and do the 2D calculation in the function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void DrawLine3D(unsigned *pixels, unsigned height, unsigned width)
{
    for (unsigned h = 0; h < height; h++)
    {
        for (unsigned w = 0; w < width; w++)
        {
            unsigned i = h * width + w;
            cout << pixels[i] << ' ';
        }
        cout << '\n';
    }
}

// call it like this:
    DrawLine3D((unsigned*)pixels, height, width);
You can use standard C++ with a 1D vector that you treat as 2D.
This is efficient since all data is in one block.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <vector>
using namespace std;

void Print2D(const vector<unsigned>& pixels, unsigned width)
{
    unsigned height = pixels.size() / width;
    for (unsigned h = 0; h < height; h++)
    {
        unsigned rowstart = h * width;
        for (unsigned w = 0; w < width; w++)
        {
            unsigned i = rowstart + w;
            cout << pixels[i] << ' ';
        }
        cout << '\n';
    }
}

int main()
{
    unsigned height, width;
    cin >> height >> width;

    vector<unsigned> pixels(height * width);

    for (unsigned h = 0; h < height; h++)
        for (unsigned w = 0; w < width; w++)
            pixels[h * width + w] = 0;

    Print2D(pixels, width);
}

All good suggestions. Only thing that remains is figuring out why Cambalinho doesn't want to pass the width as a parameter, solving all his problems.
Ganado: "All good suggestions. Only thing that remains is figuring out why Cambalinho doesn't want to pass the width as a parameter, solving all his problems."
i'm sorry... but why not be more automatic and simple? is what i think... i can add more parameters on function... but i need be more simple ;)
thanks to all.. but i'm trying using:
std::vector<std::vector<unsigned >> PixelColors{{ConsoleWidth},{ConsoleHeight}};
but when i do:
1
2
3
4
5
6
7
for(int y=0; y<ConsoleHeight; y++)
        {
            for(int x=0; x<ConsoleWidth; x++)
            {
                PixelColors[y][x] = RGB(0,0,255);
            }
        }

i get these error when the program terminates\frezes:
"Process returned -1073740940 (0xC0000374) execution time : 0.025 s
Press any key to continue."
i'm doing wrong with 'PixelColors[y][x]' or with 'PixelColors{{ConsoleWidth},{ConsoleHeight}}'?
i did wrong the 2D vector creation:
std::vector<std::vector<unsigned int>> PixelColors( ConsoleHeight , std::vector<unsigned int> (ConsoleWidth, 0));
even on value i must use the 'vector'.
now i did another topic for convert 2D vector to void*.
thank you so much for all
i'm sorry... but why not be more automatic and simple? is what i think... i can add more parameters on function... but i need be more simple ;)

1D array is "simpler" than 2D array.

You lament that creating and filling 1D is "too complex". Yet, isn't the ultimate goal to call a function that expects 1D (void *) array?

If the data will be consumed as 1D array in a function that you can't modify, then isn't 1D array exactly what should offer it?
i'm learning and understand on hard way... but now i know the void* is 1D array pointer.
thank you so much for all
The Microsoft documentation of the function says:
[in] lpBits

const void*
A pointer to the image bits, which are stored as an array of bytes.

Now you know that "array" means "array" -- at least in this context.
thanks for the correction to all.. thank you
Topic archived. No new replies allowed.