Setting and connecting pixels - mfc

I want to set pixels where the mouse click is made and connect those pixels. My code is as follows.
void CChildView::OnLButtonDown(UINT nFlags,CPoint point)
{
CDC* pDC= GetDC();
int x[100],y[100];
POINT Pt[4];
for(int i=0;i<4;i++)
{
SetPixel(NULL,Pt[i].x,Pt[i].y,RGB(0,0,0));
pDC->MoveTo(Pt[i].x,Pt[i].y);
pDC->LineTo(Pt[i+1].x,Pt[i+1].y);
}
}
But I am not getting anything in the output other than a blank screen. Pls help.

create the variables you need
in the CChildView class add a variable that stores the last point, and a variable that stores the amount of points you currently have
CPoint m_lastPoint;
int m_iPointAmount;
in the CChildView constructor initialize the variables
m_lastPoint.x = -1;
m_lastPoint.y = -1;
m_iPointAmount = 1;
in the OnLButtonDown method
check if it is the first point, and update the member variable
if it is not the first point and you have less than 4 points, connect the new point with the last one
if (m_lastPoint.x != -1 && m_iPointAmount <5)
{
CDC* pDC= GetDC();
pDC->MoveTo(m_lastPoint.x,m_lastPoint.y);
pDC->LineTo(point.x,point.y);
}
m_lastPoint = point;
m_iPointAmount++

Related

Are they actually garbage values or just the default values of enumeration if I don't initialize them?

I have branch positions that are not initialized to any value of side enumeration. However, when I try to draw them to the screen, they're actually on the same side, on the left side of the tree. I think those uninitialized branch positions are garbage values, a remnant from the memory that the PC has been used or hasn't been used. I'm not quite sure every time I run the program, they're always on the left side, which seems consistent, which is the first value in the side enumeration, which I assumed to be 0. Are they actually garbage values or just the default values of enumeration if I don't initialize them?
// Include important libraries here
#include <SFML/Graphics.hpp>
// Make code easier to type with "using namespace"
using namespace sf;
// Function declaration
void updateBranches(int seed);
const int NUM_BRANCHES = 6;
Sprite branches[NUM_BRANCHES];
// Where is the player/branch?
// Left or Right
enum class side { LEFT, RIGHT, NONE };
side branchPositions[NUM_BRANCHES];
// This is where our game start from
int main()
{
// Create a video mode object
VideoMode vm(1920, 1080);
// Create and open a window for the game
RenderWindow window(vm, "Timber!!!", Style::Fullscreen);
// Track whether the game is running
bool paused = true;
while (window.isOpen())
{
/*
****************************************
Handle the player's input
****************************************
*/
if (Keyboard::isKeyPressed(Keyboard::Escape))
{
window.close();
}
// Start the game
if (Keyboard::isKeyPressed(Keyboard::Enter))
{
paused = false;
// Reset the time and the score
score = 0;
timeRemaining = 6;
}
/*
****************************************
Update the scene
****************************************
*/
if (!paused)
{
// update the branch sprites
for (int i = 0; i < NUM_BRANCHES; i++)
{
float height = i * 150;
if (branchPositions[i] == side::LEFT)
{
// Move the sprite to the left side
branches[i].setPosition(610, height);
// Flip the sprite round the other way
branches[i].setRotation(180);
}
else if (branchPositions[i] == side::RIGHT)
{
// Move the sprite to the right side
branches[i].setPosition(1330, height);
// Set the sprite rotation to normal
branches[i].setRotation(0);
}
else
{
// hide the branch
branches[i].setPosition(3000, height);
}
}
} // End if(!paused)
/*
****************************************
Draw the scene
****************************************
*/
// Clear everything from the last frame
window.clear();
// Draw the branches
for (int i = 0; i < NUM_BRANCHES; i++)
{
window.draw(branches[i]);
}
// Show everything we just drew
window.display();
}
return 0;
}
Uninitialized (non-static) local variables are not initialized.
Uninitialized variables in namespace scope (including the global namespace, like your branchPositions array) are actually "zero" initialized.
So all elements of the branchPositions array should be zero, which is equal to LEFT.
Turn all warnings on and check what the compiler says. If your compiler complains then your code is very likely wrong.
It seems you are relying on the fact that static variables are initialised to zeroes. And by chance zero corresponds to one enumeration value. You are living very dangerous. You should usually be able to change the order of enumeration, but you can’t. Change the enum to LEFT = 1 and everything will break down.
In C++ it is defined that enum values start with 0 unless you define it otherwise, and each one is 1 more than the previous one unless you state otherwise. That’s something you can rely on. But you are relying on how variables are initialised and that is very, very dangerous.

opengl update model position while camera position not updated in time causes blinking (model fly out of view)

I rendered a scene having earth and a satellite. The position of the satellite is collected and updated by a thread. The position data is provided by an background calculation program.
// main.cpp
void CollectCraft(void)
{
SetupChannel();
int iFlag = 1;
while(iFlag > 0)
{
iFlag = CollectData();
Sleep(10);
}
CloseChannel();
}
int main(void)
{
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)CollectCraft, 0, NULL, NULL); // in collect.cpp
RenderMainWindow(); // in render.cpp
return 1;
}
The CollectCraft function receives data from a background program. Once it receives any data, it stores in a double
// collect.cpp
double Craft_R[3] = {0.0};
...
int CollectData(void)
{
char chrMessage[255] = {0};
int iFlag = CollectSocket(&sListen, &sServer, chrMessage);
if (iFlag <= 0) return iFlag;
else
{
unsigned char i = 0, j = 0;
unsigned short usLength = 0;
for ( i = 0; i < dimCraft; i++)
{
for (j=0; j<3; j++)
{
memcpy(&Craft_R[j], &chrMessage[usLength], 8);
usLength += 8;
}
}
}
return iFlag;
}
I fixed my camera on one of the satellite (following it and staring at it). It updates its position and the view matrix according to the position of the satellite.
The satellite updated it's position according to the latest received data (I simply get it through a extern double Craft_R).
// render.cpp
extern double Craft_R[3]; // directly get latest satellite position data
...
RenderMainWindow()
{
...
while (!glfwWindowShouldClose(MainWindow))
{
glm::dmat4 view = camera.GetViewMatrix();
...
Sate1Pos = glm::dvec3(Craft_R[0], Craft_R[1], Craft_R[2]); // update satellite position
glm::dmat4 model_sate1(1.0);
model_sate1 = glm::translate(model_sate1, Sate1Pos);
...
switch (CameraPosID)
{
case 0:
camera.Focus(EarthPos);
break;
case 1:
camera.Focus(Sate1Pos); // update camera position
}
glfwSwapBuffers(MainWindow);
glfwPollEvents();
}
}
The problem is, the collection of the latest satellite position data always happens BETWEEN the update of the camera position and the update of the satellite position. It means my satellite flies to the latest position but my camera still stays at the last position. After glfwSwapBuffers(), the next while (!glfwWindowShouldClose(MainWindow)) will render the satellite far away out of the field of view of the camera. And it will last until the next while for the camera to update its position and get the satellite back to its field of view.
If the background program keeps sending the satellite position, the scene will render as if the satellite is blinking. And if the background program stops sending the satellite position, everything is ok and stable. If I control the background program to send the satellite position once, the satellite in the scene will blink one time and then remains stable.
My question is if there is a way to simultaneously update position of the camera and the satellite? Many thanks and sorry for my poor English since it is not my mother tongue.

Waveform Widget Touchgfx

I’m creating a waveform widget in TouchGFX, but unsure how best to loop the waveform back to zero at the end because there are three frame buffers so you have to invalidate over an area three times or you get flickering . How would you handle looping the array back to start (x=0).
The main issue is my code originally assumed there was only one frame buffer. I think my code needs to be refactored for three framebuffers or add the ability to write directly to the frame buffer. Any hints would be greatly appreciated.
bool Graph::drawCanvasWidget(const Rect& invalidatedArea) const
{
if (numPoints < 3)
{
// A graph line with a single (or not even a single) point is invisible
return true;
}
else{
Canvas canvas(this, invalidatedArea);
for (int index = 0; index < (numPoints-1); index++)
{
canvas.moveTo(points[index].x,points[index].y);
canvas.lineTo(points[index].x,points[index+1].y);
canvas.lineTo(points[index+1].x,points[index+1].y);
canvas.lineTo(points[index+1].x,points[index].y);
}
return canvas.render(); // Shape above automatically closed
}
return true;
}
void Graph::newPoint(int y)
{
if(numPoints==501){
numPoints=0;
}else if ((maxPoints-numPoints)<=20){
points[numPoints].x = numPoints;
points[numPoints].y = y;
Rect minimalRect(480,0,20,100);
invalidateRect(minimalRect);
numPoints++;
}else{
points[numPoints].x = numPoints;
points[numPoints].y = y;
Rect minimalRect(numPoints-3,0,20,100);
invalidateRect(minimalRect);
numPoints++;
}
}
With TouchGFX 4.15.0 (just out) the TouchGFX Designer now supports a Graph widget (previously only found in source code in demos) which can be used to produce your waveforms. It has some more elegant ways of inserting points which may suit your needs.

Drawing Bitmap on to screen using CRenderTarget::DrawBitmap and Byte Array (instead of file) in VC++

I am working with COSMCtrl in order to display maps on to the viewing window.
In the COSMCtrl, a file name is passed on to the CD2DBitmap constructor along with CRenderTarget object. But my application doesnt have image file. It will receive image data (in the form of byte array) from a database.
Could any one please help me in finding out the solution ?
The sample code is below:
BOOL COSMCtrl::DrawTile(CRenderTarget* pRenderTarget, const CD2DRectF& rTile, int nTileX, int nTileY)
{
//What will be the return value from this function (assume the worst)
BOOL bSuccess = FALSE;
//Form the path to the cache file which we want to draw
int nZoom = static_cast<int>(m_fZoom);
CString sFile(GetTileCachePath(m_sCacheDirectory, nZoom, nTileX, nTileY, FALSE));
//Get the fractional value of the zoom
double fInt = 0;
double fFractionalZoom = modf(m_fZoom, &fInt);
//Try to obtain the standard tile
CD2DBitmap bitmap(pRenderTarget, sFile);
// I have a Byte Array. I should pass the byte array instead of file
//Determine how the tile should be draw
BOOL bStandardTile = FALSE;
if (fFractionalZoom == 0 && SUCCEEDED(bitmap.Create(pRenderTarget)))
bStandardTile = TRUE;
//Load up the image from disk and display it if we can
if (bStandardTile)
{
//Draw the image to the screen at the specified position
pRenderTarget->DrawBitmap(&bitmap, rTile, 1.0);
bSuccess = TRUE;
}
return bSuccess;
}
I am not allowed to save the byte array to disk (as image).
I have tried using the other constructor of CD2DBitmap which accepts CRenderTarget and HBITMAP. but of no use

How do I set up an if statement to animate a sprite?

How can I set up an if statement so after every frame the sprite shows the next frame and then the next and then once it goes through all the frames it is over?
I tried using if statements and it has never worked for me, could anyone give an example?
Edit:
After demand for code I have decided to add a sample.
int frame4 = 1;
if(frame4 = 1)
{
WalkDownFrame1(); //Renders frame 4
}
else if(frame4 = 2)
{
WalkDownFrame2(); //Renders frame 2
}
else if(frame4 = 3)
{
WalkDownFrame3(); //Renders frame 3
}
else if(frame4 = 4)
{
WalkDownFrame4(); //Renders frame 4
}
else if(frame4 = 5)
{
frame4 = 1;
}
frame4++;
no matter what modifications I apply it stays stuck on one frame.
I'm assuming you mean if the conditions are true the animation occurs and if the conditions are false it stops, in which case it would look like
/*Rest of your model transformation code*/
if(shouldbeanimating){
/*animation code*/
}else{
/*default state or nothing if you want the model to
freeze at that point in the animation*/
}
Then whenever the program should stop the animation you just set shouldbeanimating to false
Well, you need to know how many frames your animation has. Then you proceed to draw frame after frame. If you hit the last frame you go back to the first or you stop.
Here's a link that will help you. It's doesnt matter if its SDL or any other lib, the approach is always the same.
http://lazyfoo.net/SDL_tutorials/lesson20/index.php
As an example
while(isAnimating)
{
framecounter++;
isAnimating = (framecounter < MAX_FRAMES);
}
They're many solutions. You can do a Sprite Class and add an attribute _tick, store your Texture into a container, like a std::vector. I'll give you a short hint. You put a method tick() to increment your tick number. You put an attribute nbFrames, that contains the number of frames for the current sprite.
int tick;
int nbFrames; //equivalent of textures.size()
std::vector<SDL_Texture*> textures;
SDL_Texture *idle_frame;
bool moving;
int x;
int y;
Sprite::Sprite()
{
_tick = 0;
//init your textures
moving = false;
x = 0;
y = 0;
}
int _tick;
void Sprite::tick(void)
{
// Consider that _tick can reach the Max Value of int32
_tick++;
}
void Sprite::render(void)
{
SDL_Texture *texture;
if(moving)
{
int fr_index = _tick % nbFrames;
texture = textures[fr_index];
}
else
{
texture = idle_frame;
}
//then you do your render code with SDL_RenderCopy, or OpenGL code
//.
//..
}
Still missing some other thing to handle, but that an hint for your solution.
Is it possible that you are just assigning in the if statement and not testing? Or did you just miss typed it here?
Because if your code is if(frame = 0) it should be (frame == 0).