Trying to display oct data using C++,must be compatible with forms

Joined
Jun 10, 2011
Messages
2
Reaction score
0
Hello,

I've spent weeks on something I knew nothing about before, so if someone helps that'd be awesome.

I've written the following program in forms, Visual Studio C++ 2008, that takes in OCT data (16 bit) and display's the result in grayscale on the window. The only problem, is that it runs 7 fps, and I need at least 30. It performs double buffering and all, but it's not even close. (code's at the bottom)

One idea is go straight from an array of data to a bitmap, using Bitmap( width, height, stride, 'PixelFormat16bppGrayScale', *myArray), but this has an error for the pixel format. Also, whenever I use "#include <Gdiplus.h>", I get 106 errors.

I've also looked at using OpenGL to do this. It should be compatible with forms? I've tried lots, but I can't get OpenGL running. What do you download? It's not that straight forward. Is OpenGL just a bunch of libraries that you have to include?

I even wrote simillar code using API (does the same thing), but it is too slow. If anybody knows how to speed it up, that would be helpful.

#pragma once
#using <System.Drawing.dll>
#using <mscorlib.dll>
#include <iostream>
#include <fstream>
#include <cmath>
#include <stdio.h>
#include <cstdio>
#include <stdlib.h>
//#include <Gdipluspixelformats.h>
//#include <Gdiplus.h>
using namespace std;

namespace attemptTwoatDisplay {


using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::IO;
using namespace System::Drawing::Drawing2D;
using namespace System::Threading;
using namespace System::Drawing;

/// <summary>
/// Summary for Form1
///
/// WARNING: If you change the name of this class, you will need to change the
/// 'Resource File Name' property for the managed resource compiler tool
/// associated with all .resx files this class depends on. Otherwise,
/// the designers will not be able to interact properly with localized
/// resources associated with this form.
/// </summary>
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
//dbBitmap = NULL; I guess since I cannot do this: Managed code means that the computer does this for you already.

//dbGraphics = NULL;
result = 0;
yCoordinate = 0;
xCoordinate = 0;
tempThreadOne = 0;
tempThreadTwo = 0;
Width = 1024;
numFrames = 400;
displayFrameThreadOne = 1;
displayFrameThreadTwo = 1;
numPixel = 0;
Height = 512;
Size = Width * Height;
LargestData = 2000;
LowestData = -18000;//NOTE: VERY IMPORTANT: I assumed that Lowest Data is negative for quicker processing. Must change code if positive. (put in absolute values).
//myBrush = gcnew System::Drawing::SolidBrush(System::Drawing::Color::White);
myArray = new Int16[Size*numFrames];
//CustomGrey = new Color;//[Size*numFrames];
//myArrayTwo = new Int16[Size*numFrames*2];
// myArrayThree = new Int16[Size*numFrames];
//myPen = gcnew Pen(Color::White, 1);
myBitmap = gcnew Bitmap(Width, Height );
//format = PixelFormat16bppGrayScale;



instream = fopen("octData", "rb+");
if(instream == NULL)
{

//yikes
cout<<"error";


}
result = fread (myArray,2,Size*numFrames,instream);


//this scales all the values now, so that less calculations need to be done when the display is running.
//for(displayFrameThreadOne = 1; displayFrameThreadOne<numFrames; displayFrameThreadOne++)
//{
//tempThreadOne = displayFrameThreadOne*Width*Height;


// for(int i = 0; i< Size; i++)
//{
// numPixel = i + tempThreadOne;



// if(myArray[numPixel]> LargestData)
// {
// myArray[numPixel] = LargestData;
// }
// if(myArray[numPixel] < LowestData)
// {
// myArray[numPixel] = LowestData;
// }

// myArray[numPixel] = (myArray[numPixel] - LowestData)*255 / (LargestData - LowestData);
// }
//}


//displayFrame = 1;





InitializeComponent();

this->SetStyle(ControlStyles::Opaque, true);
this->SetStyle(ControlStyles::AllPaintingInWmPaint |
ControlStyles::UserPaint |
ControlStyles::DoubleBuffer, true);//this may be all I have to do to perform double buffering.\

th1 = gcnew Thread(gcnew ThreadStart(this, &Form1::th1Method));
// th2 = gcnew Thread(gcnew ThreadStart(this, &Form1::th2Method));//thread two will need to share data from thread one. Must figure this out.
th1->Start();//this calls a thread that does the above code that is commented out.
Thread::Sleep(4000);//main thread is sleeping while other calculates
}

protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}

protected:
private: System::ComponentModel::IContainer^ components;

private: Bitmap ^dbBitmap;
Graphics ^dbGraphics;
UInt32 Width;//Following by example in book, I am making these private. To me public makes more sense, but if it works I won't change it.
UInt32 Height;
UInt32 Size;
Single LargestData;
FILE* instream;
Single LowestData;
int numFrames;
int displayFrameThreadOne;
int displayFrameThreadTwo;
int numPixel;
int tempThreadOne;
int tempThreadTwo;
Int16 test;
//Pen^ myPen;
SolidBrush^ myBrush;
Color CustomGrey;
Int16* myArray;
Int32 result;
int yCoordinate;
int xCoordinate;
Thread ^th1;
Thread ^th2;
PixelFormat format;

Bitmap^ myBitmap;



//Int16* myArrayTwo;
// Int16* myArrayThree;

#pragma region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->SuspendLayout();
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(1016, 478);
this->Name = L"Form1";
this->Text = L"OCT Data";
this->Load += gcnew System::EventHandler(this, &Form1::Form1_Load);
this->Paint += gcnew System::Windows::Forms::PaintEventHandler(this, &Form1::Form1_Paint);
this->Resize += gcnew System::EventHandler(this, &Form1::Form1_Resize);
this->ResumeLayout(false);

}
#pragma endregion

private: System::Void th1Method()
{
for(displayFrameThreadOne = 1; displayFrameThreadOne<numFrames; displayFrameThreadOne++)
{
tempThreadOne = displayFrameThreadOne*Width*Height;


for(int i = 0; i< Size; i++)
{
numPixel = i + tempThreadOne;



if(myArray[numPixel]> LargestData)
{
myArray[numPixel] = LargestData;
}
if(myArray[numPixel] < LowestData)
{
myArray[numPixel] = LowestData;
}

myArray[numPixel] = (myArray[numPixel] - LowestData)*255 / (LargestData - LowestData);
}
//Thread::Sleep(5);
}
}






private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) {


}
private: System::Void Form1_Resize(System::Object^ sender, System::EventArgs^ e) {


dbBitmap = gcnew Bitmap(Width, Height);
//created bitmap

//grab its graphics
dbGraphics = Graphics::FromImage(dbBitmap);


}
private: System::Void Form1_Paint(System::Object^ sender, System::Windows::Forms::PaintEventArgs^ e) {



// Bitmap^ myBitmap = gcnew Bitmap(Width, Height, 1024, //'PixelFormat16bppGrayScale ' ,*myArray );
//here I'm trying the bitmap method
// e->Graphics->DrawImage(myBitmap, 0, 0);
// Invalidate();


//lets just give thread 1 a bit of a head start, so that the data is ready.
Graphics ^g = e->Graphics;
// th2->Start();

//Bitmap^ myBitmap = gcnew Bitmap(Width, Height );


// Draw myBitmap to the screen.
// e->Graphics->DrawImage( myBitmap, 0, 0, myBitmap->Width, myBitmap->Height );


//g->Clear(Color::Black);


tempThreadTwo = displayFrameThreadTwo*Width*Height;


for(int i = 0; i< Size; i++)
{
numPixel = i + tempThreadTwo;



if(i != 0)
{
if(myArray[numPixel]!= myArray[numPixel - Size])
{



// myArray[numPixel] = 0;

//if(myArray[numPixel] > 255 || myArray[numPixel]< 0) this was for if the thread caught up to it.
//Thread::Sleep(500);

CustomGrey= Color::FromArgb(myArray[numPixel], myArray[numPixel],myArray[numPixel] );


// myPen[0] = Pen(CustomGrey);//probably not going to work


yCoordinate = ceil((double)(i/Width));
xCoordinate = i%Width;

myBitmap->SetPixel(xCoordinate, yCoordinate, CustomGrey );

//example myBitmap.SetPixel(row, col, Color(255, 0, 0, 0));
//dbBitmap.SetPixel(xCoordinate, yCoordinate, CustomGrey);


}
}





}
e->Graphics->DrawImage(myBitmap, 0, 0);//( myBitmap, myBitmap->Width, 0, myBitmap->Width, myBitmap->Height );
displayFrameThreadTwo = displayFrameThreadTwo + 1;
Invalidate();

//Update();

//make buffer visible. This is commented out if my other tactic was successful.
// e->Graphics->DrawImageUnscaled(dbBitmap, 0, 0);


}
*/
};
}



THANK YOU
 
It's been a while. I still have problems, but I'll get around to updating them soon, and what I figured out.
 
Back
Top