how convert a 1D array to 2D and get it's size?

heres the array:
1
2
3
4
5
6
void *BufferMemory;
int BufferSize = ConsoleWidth * ConsoleHeight * sizeof(unsigned int);

    if(BufferMemory) VirtualFree(BufferMemory, 0,MEM_RELEASE);
    BufferMemory = VirtualAlloc(0, BufferSize,MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    unsigned int *PixelColors = (unsigned int) BufferMemory;

can i convert the 'BufferMemory' to 2D array?
for avoid several problems for the X and Y.
Last edited on
Since it seems I didn't make it clear: the solution is to store the dimensions alongside the pixel buffer.
1
2
3
4
5
6
class Bitmap{
    int width;
    int height;
    pixel *data;
    //etc.
};
true.. thank you.
but continue with topic: can i make the array 2D?
There's no way to "make an array 2D" in such a way that the dimensions are stored with the pointer. You could allocate a variable-size struct, but most people prefer not to do that:
1
2
3
4
5
6
7
8
9
10
11
12
13
struct BitmapData{
    int width;
    int height;
    pixel data[1];
};

int width = /*...*/;
int height = /*...*/;
size_t memory_size = width * height * sizeof(pixel) + sizeof(BitmapData);
auto data = (BitmapData *)VirtualAlloc(0, BufferSize,MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
data->width = width;
data->height = height;
memcpy(data->data, some_existing_bitmap, width * height * sizeof(pixel));
It seems pretty pointless to me.
Last edited on
i just need the X and Y.. not the 'Bitmap'.
can i do?:
void BufferMemory[ConsoleHeight][ConsoleWidth];
the 'StretchDIBits()' only accepts 'void*' on tenth parameter:
int StretchDIBits(
[in] HDC hdc,
[in] int xDest,
[in] int yDest,
[in] int DestWidth,
[in] int DestHeight,
[in] int xSrc,
[in] int ySrc,
[in] int SrcWidth,
[in] int SrcHeight,
[in] const VOID *lpBits,
[in] const BITMAPINFO *lpbmi,
[in] UINT iUsage,
[in] DWORD rop
);

Last edited on
seems that i did what i need:
1
2
3
4
5
6
7
8
9
10
11
12
.....
unsigned int PixelColors[ConsoleHeight][ConsoleWidth];
...........
for(int y=0; y<ConsoleHeight; y++)
        {
            for(int x=0, i=0; x<ConsoleWidth; x++)
            {
                PixelColors[y][x] = RGB(0,255,0);
            }
        }
...........
StretchDIBits(HDCConsoleWindow,0,0,ConsoleWidth, ConsoleHeight, 0,0, ConsoleWidth,ConsoleHeight, (void*)PixelColors, &BitInfo,DIB_RGB_COLORS, SRCCOPY );

i convert it: '(void*)PixelColors'.
thank you so much for all
Good luck with the crashes, I guess.
you can convert a 1d to 2d syntax if the 2d has constant dimensions.
if those can vary, you cannot do it, or I don't know any way to make it happen.

You are doing well, you haven't given up and have posted several working chunks that show you are making progress. But you keep circling back to basic concepts in the middle of all the windows code. I advise that it would be a lot easier to have a little test program (console program) that you can study/play with these ideas without the windows mess confusing you. Unravel how it works, then apply it back in the windows stuff you are working on.

Last edited on
like these code:
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#include <iostream>
#include <windows.h>
#include <cmath>
#include <stdlib.h>
#include <vector>
#include <string>

#define M_PI           3.14159265358979323846  /* pi */

struct Position2D
{
    Position2D()
    {
        //Nothing;
    }

    Position2D(float X, float Y)
    {
        PosX = X;
        PosY = Y;
    }
    float PosX = 0;
    float PosY = 0;
};

struct Position3D
{
    float PosX = 0;
    float PosY = 0;
    float PosZ = 0;

    Position3D()
    {
        //Nothing;
    }

    Position3D(float X, float Y, float Z)
    {
        PosX = X;
        PosY = Y;
        PosZ = Z;
    }

    operator Position2D()
    {
        Position2D Pos2D{PosX, PosY};
        Pos2D.PosX = PosX;
        Pos2D.PosY = PosY;
        return Pos2D;
    }

};

std::vector<Position3D> GetLinePoints(Position3D Origin, Position3D Destination)
{
    //Getting the Line Points Count:
    int LineCountPoints = sqrt(abs(Destination.PosX - Origin.PosX) * abs(Destination.PosX - Origin.PosX)
                                  + abs(Destination.PosY - Origin.PosY) * abs(Destination.PosY - Origin.PosY)
                                  + abs(Destination.PosZ - Origin.PosZ) * abs(Destination.PosZ - Origin.PosZ));

    //Get the increment for X, Y and Z:
    Position3D Increment;
    Increment.PosX = (Destination.PosX - Origin.PosX) / LineCountPoints;
    Increment.PosY = (Destination.PosY - Origin.PosY) / LineCountPoints;
    Increment.PosZ = (Destination.PosZ - Origin.PosZ) / LineCountPoints;

    Position3D NextPoint=Origin;

    std::vector<Position3D> GetPoints;
    for(int LinePoint =0 ; LinePoint<LineCountPoints; LinePoint++)
    {
        //Get the next point:
        NextPoint.PosX += Increment.PosX;
        NextPoint.PosY += Increment.PosY;
        NextPoint.PosZ += Increment.PosZ;

        //Round the values:
        Position3D Pos3D;
        Pos3D.PosX = ceil(NextPoint.PosX);
        Pos3D.PosY = ceil(NextPoint.PosY);
        Pos3D.PosZ = ceil(NextPoint.PosZ);
        /*if(Pos3D.PosX <Origin.PosX && Pos3D.PosX > Destination.PosX) break;
        if(Pos3D.PosY <Origin.PosY && Pos3D.PosY > Destination.PosY) break;
        if(Pos3D.PosZ <Origin.PosZ && Pos3D.PosZ > Destination.PosZ) break;*/
        //Add the 3D position on vector:
        GetPoints.push_back(Pos3D);
    }
    return GetPoints;
}



Position3D RotationPoints(Position3D Position, Position3D RotationPosition, Position3D Angle)
{
    //Convert Angles in Radians:
    Angle.PosX *= M_PI / 180 ;
    Angle.PosY *= M_PI / 180 ;
    Angle.PosZ *= M_PI / 180 ;

    Position3D RotatedPoint;

    //for add the Rotation Point
    //we must sub the Rotation point with rotation center:
    Position.PosX -= RotationPosition.PosX;
    Position.PosY -= RotationPosition.PosY;
    Position.PosZ -= RotationPosition.PosZ;


    //First we rotate the Z:
    RotatedPoint.PosX = Position.PosX * cos(Angle.PosZ)-Position.PosY*sin(Angle.PosZ);
    RotatedPoint.PosY = Position.PosX * sin(Angle.PosZ)+Position.PosY*cos(Angle.PosZ);
    RotatedPoint.PosZ = Position.PosZ;

    //Second we rotate the Y:
    RotatedPoint.PosX = RotatedPoint.PosX * cos(Angle.PosY)+RotatedPoint.PosZ*sin(Angle.PosY);
    RotatedPoint.PosY = RotatedPoint.PosY;
    RotatedPoint.PosZ = -RotatedPoint.PosX * sin(Angle.PosY)+RotatedPoint.PosZ*cos(Angle.PosY);

    //Third we rotate the X:
    RotatedPoint.PosX = RotatedPoint.PosX;
    RotatedPoint.PosY = RotatedPoint.PosY * cos(Angle.PosX)-RotatedPoint.PosZ*sin(Angle.PosX);
    RotatedPoint.PosZ = RotatedPoint.PosY * sin(Angle.PosX)+RotatedPoint.PosZ*cos(Angle.PosX);

    //after rotate the point
    //we add the rotation center:
    RotatedPoint.PosX += RotationPosition.PosX;
    RotatedPoint.PosY += RotationPosition.PosY;
    RotatedPoint.PosZ += RotationPosition.PosZ;

    return RotatedPoint;
}


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 + X) =(unsigned int) Color;
    }
}

int main()
{

    BITMAPINFO BitInfo;
    HWND HWNDConsoleWindow = GetConsoleWindow();
    HDC HDCConsoleWindow = GetDC(HWNDConsoleWindow);
    std::vector<Position3D> GetLineDots;
    Position3D Origin ={100,100,0};
    Position3D Destination ={200,200,0};

    Position3D RotOrigin ={0,0,0};
    Position3D RotDestination ={100,100,0};

    GetLineDots = GetLinePoints(Origin,Destination);
    Position3D Angle={0,0,0};
    Position3D RotatePoint={150,150,0};

    RECT rect;
    GetClientRect(HWNDConsoleWindow, &rect);
    int ConsoleWidth = rect.right - rect.left;
    int ConsoleHeight = rect.bottom - rect.top;


    BitInfo.bmiHeader.biSize = sizeof(BitInfo.bmiHeader);
    BitInfo.bmiHeader.biWidth = ConsoleWidth;
    BitInfo.bmiHeader.biHeight = -ConsoleHeight;
    BitInfo.bmiHeader.biPlanes = 1;
    BitInfo.bmiHeader.biBitCount = 32;
    BitInfo.bmiHeader.biCompression = BI_RGB;

    unsigned int PixelColors[ConsoleHeight][ConsoleWidth];

    do
    {
        //draw a background color:
        RotOrigin = RotationPoints(Origin,RotatePoint,Angle);
        RotDestination = RotationPoints(Destination,RotatePoint,Angle);

        for(int y=0; y<ConsoleHeight; y++)
        {
            for(int x=0, i=0; x<ConsoleWidth; x++)
            {
                PixelColors[y][x] = RGB(0,0,255);
            }
        }

        if(GetAsyncKeyState(VK_RIGHT)) Angle.PosZ += 0.2;
        if(GetAsyncKeyState(VK_LEFT)) Angle.PosZ -= 0.2;



        // draw a line:
        DrawLine3D(PixelColors[0],RotOrigin,RotDestination, RGB(0,255,0) );// here theres a different error
        // draw the pixels on console window:
        StretchDIBits(HDCConsoleWindow,0,0,ConsoleWidth, ConsoleHeight, 0,0, ConsoleWidth,ConsoleHeight, (void*)PixelColors, &BitInfo,DIB_RGB_COLORS, SRCCOPY );
    }while(!GetAsyncKeyState(VK_ESCAPE));
   std::cin.get();
    return 0;
}
1
2
3
4
5
6
    RECT rect;
    GetClientRect(HWNDConsoleWindow, &rect);
    int ConsoleWidth = rect.right - rect.left;
    int ConsoleHeight = rect.bottom - rect.top;

    unsigned int PixelColors[ConsoleHeight][ConsoleWidth]; // non-standard: VLA 

The size of C++ array has to be known during compilation. Your program has to run before we know rect.
Besides, that array would be allocated from stack, which tends to be limited in size compared to Free Store.
You need to allocate that memory dynamically.

1
2
DrawLine3D(PixelColors[0],RotOrigin,RotDestination, RGB(0,255,0) );// here theres a different error
StretchDIBits( ..., ConsoleWidth,ConsoleHeight, (void*)PixelColors, ... );

You call StretchDIBits() that apparently takes 1D array and dimensions of "logical 2D array", whose data is in that "1D block".

Why don't you do the same with DrawLine3D()?
 
unsigned int PixelColors[ConsoleHeight][ConsoleWidth];


This is not standard C++. In standard C++ the sizes of the array dimensions have to known at compile time. Some C++ compilers allow this as a C extension - but major compilers such as MS VS do not.

If you use this sort of array definition then the code may not compile with another compiler.
Topic archived. No new replies allowed.