Have display / stop functionality working generally, but textures not appearing properly.

This commit is contained in:
mmcwilliams 2024-05-05 11:28:20 -04:00
parent 62c7181906
commit 566f1ecefd
5 changed files with 147 additions and 71 deletions

BIN
img/4kSnake.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -46,6 +46,7 @@ class State {
void setMode(json& msgData);
void setExposure(json& msgData);
void setPosition(json& msgData);
void setActive () { active = true; }
public :
State();
@ -57,7 +58,7 @@ class State {
vector<uint64_t> getExposure() { return exposure; }
vector<uint64_t> getPosition() { return { x, y, w, h }; }
bool isError () { return ERROR; }
void setActive () { active = true; }
void setInactive () { active = false; }
bool isActive () { return active; }
};

View File

@ -21,9 +21,11 @@
#include <condition_variable>
using namespace std;
using namespace std::chrono;
uint16_t PORT = 8081;
const uint16_t BUFFER_SIZE = 2048;
int clientSocket = 0;
GLuint imageTexture = 0;
GLuint blankTexture = 0;
@ -34,15 +36,68 @@ GLint screenHeight = 0;
Image img;
State state;
void actionDisplay () {
uint64_t exposureTime = 0;
steady_clock::time_point startTime;
bool displaying = false;
bool completed = true;
bool timing = false;
/**
* State Message Variables
**/
bool receivedMessage = false;
string incomingMessage;
string outgoingMessage;
mutex receivedMutex;
condition_variable receivedCondVar;
void actionDisplay () {
vector<uint64_t> exposure = state.getExposure();
if (exposure.size() == 0) {
displaying = true;
completed = true;
timing = false;
} else if (exposure.size() == 1) {
exposureTime = exposure[0];
displaying = true;
completed = false;
timing = true;
startTime = steady_clock::now();
while (!completed) {
//
}
} // multi channel case
}
void actionStop () {
displaying = false;
completed = true;
}
void postAction () {
if (state.isError()) {
outgoingMessage = state.createMessage(false);
} else {
outgoingMessage = state.createMessage(true);
}
const char* msg = outgoingMessage.c_str();
int bytesSent = send(clientSocket, msg, strlen(msg), 0);
if (bytesSent < 0) {
cerr << "Error sending ACK to client" << endl;
} else {
cout << "Sent = " << outgoingMessage << endl;
}
}
void actionLoad () {
auto localStartTime = steady_clock::now();
string imagePath = state.getImage();
vector<uint64_t> position = state.getPosition();
Mat image = img.loadImage(imagePath, position[0], position[1], position[2], position[3]);
glGenTextures(2, &imageTexture);
glGenTextures(1, &imageTexture);
glBindTexture(GL_TEXTURE_2D, imageTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@ -51,19 +106,18 @@ void actionLoad () {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, // Type of texture
glTexSubImage2D(GL_TEXTURE_2D, // Type of texture
0, // Pyramid level (for mip-mapping) - 0 is the top level
GL_RGB, // Internal colour format to convert to
image.cols, // Image width i.e. 640 for Kinect in standard mode
image.rows, // Image height i.e. 480 for Kinect in standard mode
image.cols, // Image width
image.rows, // Image height
0, // Border width in pixels (can either be 1 or 0)
GL_RGB, // Input image format (i.e. GL_RGB, GL_RGBA, GL_BGR etc.)
GL_UNSIGNED_BYTE, // Image data type
image.ptr()); // The actual image data itself
}
void actionStop () {
auto localCurrentTime = steady_clock::now();
auto localElapsedTime = duration_cast<milliseconds>(localCurrentTime - localStartTime).count();
cout << "actionLoad() [" << localElapsedTime << " ms]" << endl;
}
void loadBlank () {
@ -79,22 +133,52 @@ void loadBlank () {
glTexImage2D(GL_TEXTURE_2D, // Type of texture
0, // Pyramid level (for mip-mapping) - 0 is the top level
GL_RGB, // Internal colour format to convert to
blank.cols, // Image width i.e. 640 for Kinect in standard mode
blank.rows, // Image height i.e. 480 for Kinect in standard mode
blank.cols, // Image width
blank.rows, // Image height
0, // Border width in pixels (can either be 1 or 0)
GL_RGB, // Input image format (i.e. GL_RGB, GL_RGBA, GL_BGR etc.)
GL_UNSIGNED_BYTE, // Image data type
blank.ptr()); // The actual image data itself
}
void initImageTexture() {
glGenTextures(1, &imageTexture);
}
void display () {
if (state.isActive()) {
if (state.getAction() == LOAD) {
actionLoad();
} else if (state.getAction() == DISPLAY) {
actionDisplay();
} else if (state.getAction() == STOP) {
actionStop();
}
state.setInactive();
postAction();
}
if (displaying && timing) {
auto currentTime = steady_clock::now();
auto elapsedTime = duration_cast<milliseconds>(currentTime - startTime).count();
if (elapsedTime > exposureTime) {
cout << "Exposure = " << elapsedTime << " ms" << endl;
displaying = false;
completed = true;
}
}
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glViewport(0, 0, screenWidth, screenHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
glBindTexture(GL_TEXTURE_2D, blankTexture);
if (displaying) {
glBindTexture(GL_TEXTURE_2D, imageTexture);
} else {
glBindTexture(GL_TEXTURE_2D, blankTexture);
}
glBegin(GL_QUADS); // front face
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 0.0f); //bottom right
@ -114,47 +198,14 @@ void timer(int value) {
glutTimerFunc(1, timer, 0);
}
/**
* State Message Variables
**/
bool receivedMessage = false;
bool sendMessage = false;
string incomingMessage;
string outgoingMessage;
mutex receivedMutex;
condition_variable receivedCondVar;
mutex sendMutex;
condition_variable sendCondVar;
/**
*
**/
void processMessage () {
if (receivedMessage) {
cout << "RECEIVED" << endl;
state.receiveMessage(incomingMessage);
receivedMessage = false;
while (state.isActive()) {
if (state.getAction() == LOAD) {
actionLoad();
} else if (state.getAction() == DISPLAY) {
actionDisplay();
} else if (state.getAction() == STOP) {
actionStop();
}
}
if (state.isError()) {
outgoingMessage = state.createMessage(false);
} else {
outgoingMessage = state.createMessage(true);
}
sendMessage = true;
}
}
@ -174,32 +225,12 @@ void handleTCPConnection(int clientSocket) {
{
lock_guard<mutex> lock(receivedMutex);
receivedMessage = true;
sendMessage = false;
incomingMessage = localIncomingMessage;
receivedCondVar.notify_all();
}
processMessage();
bool localSendMessage;
string localOutgoingMessage;
{
unique_lock<mutex> lock(sendMutex);
sendCondVar.wait(lock, [&] { return sendMessage; });
localSendMessage = sendMessage;
localOutgoingMessage = outgoingMessage;
}
if (localSendMessage) {
const char* msg = localOutgoingMessage.c_str();
int bytesSent = send(clientSocket, msg, strlen(msg), 0);
if (bytesSent < 0) {
cerr << "Error sending ACK to client" << endl;
break;
}
}
memset(buffer, 0, BUFFER_SIZE);
}
}
@ -209,7 +240,7 @@ void runTCPServer (int serverSocket) {
struct sockaddr_in clientAddr;
socklen_t clientAddrLen = sizeof(clientAddr);
int clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddr, &clientAddrLen);
clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddr, &clientAddrLen);
if (clientSocket < 0) {
cerr << "Error accepting client connection" << endl;
continue;
@ -260,6 +291,7 @@ int main (int argc, char** argv) {
glutDisplayFunc(display);
glutTimerFunc(0, timer, 0);
loadBlank();
initImageTexture();
int serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocket < 0) {

View File

@ -16,7 +16,20 @@ bool State::imageExists (string& image) {
void State::setAction (json& msgData) {
action = static_cast<Action>(msgData["action"]);
cout << "Action = " << action << endl;
switch (action) {
case NONE:
cout << "Action = NONE" << endl;
break;
case LOAD:
cout << "Action = LOAD" << endl;
break;
case DISPLAY:
cout << "Action = DISPLAY" << endl;
break;
case STOP:
cout << "Action = STOP" << endl;
break;
}
}
void State::setImage (json& msgData) {
@ -45,9 +58,11 @@ void State::setPosition (json& msgData) {
void State::setExposure (json& msgData) {
if (msgData["exposure"].size() == 1) {
exposure = { msgData["exposure"][0] };
} else if (msgData["exposure"].size() == 3) {
cout << "Exposure = " << msgData["exposure"][0] << " ms" << endl;
} /*else if (msgData["exposure"].size() == 3) {
exposure = { msgData["exposure"][0], msgData["exposure"][1], msgData["exposure"][2] };
} else {
cout << "Exposure[0] = " << msgData["exposure"][0] << " ms, [1] = " << msgData["exposure"][1] << " ms, [2] = " << msgData["exposure"][2] << " ms" << endl;
}*/ else {
error();
cerr << "Exposure array is incorrect length, " << msgData["exposure"].size() << endl;
return;
@ -81,6 +96,8 @@ void State::receiveMessage (string msgString) {
if (action == DISPLAY && msgData.contains("exposure")) {
setExposure(msgData);
}
setActive();
}
string State::createMessage (bool success) {

View File

@ -1,4 +1,5 @@
const net = require('net');
const { resolve } = require('path');
const serverAddress = 'localhost';
const serverPort = 8081;
@ -16,13 +17,38 @@ async function delay (ms) {
client.connect(serverPort, serverAddress, async () => {
const data = {
action : 1,
image: 'filename.tif',
image: resolve('./img/4kSnake.png'),
position : {
x: 100,
y : 100,
w : 320,
h : 320
}
};
console.log('SENDING');
console.log(data);
client.write(JSON.stringify(data));
await delay(2000);
data.action = 2;
delete data.position
console.log('SENDING');
console.log(data);
client.write(JSON.stringify(data));
await delay(2000);
data.action = 3;
console.log('SENDING');
console.log(data);
client.write(JSON.stringify(data));
await delay(2000);
data.action = 1;
data.position = { x: 50, y : 50, w : 320, h : 320 };
console.log('SENDING');
console.log(data);
client.write(JSON.stringify(data));
await delay(1000);
data.action = 2;
delete data.position;
data.exposure = [ 4000 ];
console.log('SENDING');
console.log(data);
client.write(JSON.stringify(data));