// // Emscripten/SDL2/OpenGLES2 sample that demonstrates simple geometry and shaders, mouse and touch input, and window resizing // // Setup: // Install emscripten: http://kripken.github.io/emscripten-site/docs/getting_started/downloads.html // // Build: // emcc -std=c++11 hello_triangle.cpp events.cpp camera.cpp -s USE_SDL=2 -s FULL_ES2=1 -s WASM=0 -o hello_triangle.html // // Run: // emrun hello_triangle.html // // Result: // A colorful triangle. Left mouse pans, mouse wheel zooms in/out. Window is resizable. // #ifdef __EMSCRIPTEN__ #include #endif #include #include //#include //#include #include #include "dcmtk/config/osconfig.h" #include "dcmtk/dcmdata/dcfilefo.h" #include "dcmtk/dcmdata/dcdeftag.h" #include "dcmtk/dcmdata/dcuid.h" #include "dcmtk/dcmdata/dcmetinf.h" #include "dcmtk/dcmdata/dcdict.h" #include "dcmtk/dcmdata/dcdicent.h" #include "dcmtk/dcmdata/dcxfer.h" #include "dcmtk/dcmjpeg/djdecode.h" /* for JPEG decoders */ #include "dcmtk/dcmjpeg/djencode.h" /* for JPEG encoders */ #include "dcmtk/dcmjpls/djdecode.h" /* for JPEG-LS decoders */ #include "dcmtk/dcmjpls/djencode.h" /* for JPEG-LS encoders */ #include "dcmtk/dcmdata/dcrledrg.h" /* for RLE decoder */ #include "dcmtk/dcmdata/dcrleerg.h" /* for RLE encoder */ #include "dcmtk/dcmjpeg/dipijpeg.h" /* for dcmimage JPEG plugin */ #include "dcmtk/dcmjpeg/djrplol.h" #include "dcmtk/dcmimage/diregist.h" #include "dcmtk/dcmdata/dcpixseq.h" #include "dcmtk/dcmjpeg/djcparam.h" #include "dcmtk/dcmjpeg/djeijg8.h" #include "dcmtk/dcmjpeg/djcodece.h" #include "dcmtk/dcmdata/dcchrstr.h" #include "dcmtk/ofstd/ofchrenc.h" #include "dcmtk/dcmdata/dcvrui.h" #include "dcmtk/dcmdata/dcvrsh.h" #include "dcmtk/dcmdata/dcistrmb.h" #include "dcmtk/oflog/loglevel.h" #include "events.h" typedef void (*callback_UpdateDcmImage) (); callback_UpdateDcmImage callback_UpdateDcmImageComplete = NULL; DcmDataset* g_pDcmDataset = NULL; DcmElement* g_pixelDataElement = NULL; bool g_bChange = false; EventHandler* g_pEventHandler = NULL; GLuint textureObj = 0; GLuint g_shaderProgramGray16 = 0; GLuint g_shaderProgramRGB = 0; // Vertex shader GLint g_shaderPanGray16, g_shaderZoomGray16, g_shaderAspectGray16, g_shaderWindowCenterGray16, g_shaderWindowWidthGray16; GLint g_shaderPanRGB, g_shaderZoomRGB, g_shaderAspectRGB, g_shaderWindowCenterRGB, g_shaderWindowWidthRGB; int g_nWindowWidth = 0; int g_nWindowCenter = 0; int g_nPrevWindowWidth = 0; int g_nPrevWindowCenter = 0; int g_nDefaultWindowWidth = 0; int g_nDefaultWindowCenter = 0; int g_nColorType = 0; Uint32 g_nCurrentFrame = 0; int g_nTotalFrames = 0; int g_nFrameTextureWidth = 0; int g_nFrameTextureHeight = 0; int g_nSamplesPerPixel = 0; int g_nBitsAllocated = 0; int g_nFrameSizeUncompressed = 0; int g_nWindowSizeWidth = 0; int g_nWindowSizeHeight = 0; float g_fFrameTime = 0; float g_fFrameDelay = 0; char* g_pBuf = NULL; const GLchar* vertexSourceGray16 = "uniform vec2 pan; \n" "uniform float zoom; \n" "uniform float aspect; \n" "attribute vec4 position; \n" "attribute vec2 a_texCoord; \n" "varying vec2 texCoord; \n" "void main() \n" "{ \n" " gl_Position = vec4(position.xyz, 1.0); \n" " gl_Position.xy += pan; \n" " gl_Position.xy *= zoom; \n" " texCoord = a_texCoord; \n" " gl_Position.y *= aspect; \n" "} \n"; // Fragment/pixel shader const GLchar* fragmentSourceGray16 = "precision mediump float; \n" "varying vec2 texCoord; \n" "uniform sampler2D texSampler; \n" "uniform float fWindowCenter; \n" "uniform float fWindowWidth; \n" "void main() \n" "{ \n" " vec4 colorOut = texture2D(texSampler, texCoord); \n" " float fMin = fWindowCenter - fWindowWidth/2.0;\n" " float fMax = fWindowCenter + fWindowWidth/2.0;\n" " float fData = ( ((colorOut.a + colorOut.r*256.0)*256.0) - fMin)/(fMax-fMin); \n" " fData = ( ((colorOut.a + colorOut.a*256.0)*256.0) - fMin)/(fMax-fMin); \n" " fData = colorOut.r;\n" " fData = (((colorOut.a * 256.0 + colorOut.r)*256.0) - fMin) / (fMax-fMin);" " float fTmpData = fMin;\n" " gl_FragColor = vec4(fData, fData, fData, 1.0); \n" "} \n"; const GLchar* vertexSourceRGB = "uniform vec2 panRGB; \n" "uniform float zoomRGB; \n" "uniform float aspectRGB; \n" "attribute vec4 position; \n" "attribute vec2 a_texCoord; \n" "varying vec2 texCoord; \n" "void main() \n" "{ \n" " gl_Position = vec4(position.xyz, 1.0); \n" " gl_Position.xy += panRGB; \n" " gl_Position.xy *= zoomRGB; \n" " texCoord = a_texCoord; \n" " gl_Position.y *= aspectRGB; \n" "} \n"; // Fragment/pixel shader const GLchar* fragmentSourceRGB = "precision mediump float; \n" "varying vec2 texCoord; \n" "uniform sampler2D texSampler; \n" "uniform float fWindowCenterRGB; \n" "uniform float fWindowWidthRGB; \n" "void main() \n" "{ \n" " vec4 colorOut = texture2D(texSampler, texCoord); \n" " float fMin = fWindowCenterRGB - fWindowWidthRGB/2.0;\n" " float fMax = fWindowCenterRGB + fWindowWidthRGB/2.0;\n" " float fTestValue = (fMax - fMin);\n" " float fR = (colorOut.r*256.0 - fMin) / (fMax-fMin);\n" " float fG = (colorOut.g*256.0 - fMin) / (fMax-fMin);\n" " float fB = (colorOut.b*256.0 - fMin) / (fMax-fMin);\n" " gl_FragColor = vec4(fR, fG, fB, 1.0); \n" //" gl_FragColor = vec4(colorOut.r/fTestValue, 1.0, 1.0, 1.0); \n" "} \n"; void updateShader(EventHandler& eventHandler) { Camera& camera = eventHandler.camera(); printf("updateShader: g_nColorType=%d\n", g_nColorType); if(g_nColorType==0) { glUseProgram(g_shaderProgramGray16); glUniform2fv(g_shaderPanGray16, 1, camera.pan()); glUniform1f(g_shaderZoomGray16, camera.zoom()); glUniform1f(g_shaderAspectGray16, camera.aspect()); } else if(g_nColorType==1) { glUseProgram(g_shaderProgramRGB); glUniform2fv(g_shaderPanRGB, 1, camera.pan()); glUniform1f(g_shaderZoomRGB, camera.zoom()); glUniform1f(g_shaderAspectRGB, camera.aspect()); } } void onErrorData(void* arg) { printf("onErrorData %d\n", (int)arg); } void updateTextureGray16(int nWidth, int nHeight, void* pData) { glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, nWidth, nHeight, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, pData); } void updateTextureRGB(int nWidth, int nHeight, void* pData) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, nWidth, nHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, pData); } void updateWindowWidthLevelGray16(int nWidth, int nLevel) { glUniform1f(g_shaderWindowCenterGray16, (float)nLevel); glUniform1f(g_shaderWindowWidthGray16, (float)nWidth); } void updateWindowWidthLevelRGB(int nWidth, int nLevel) { glUniform1f(g_shaderWindowCenterRGB, (float)nLevel); glUniform1f(g_shaderWindowWidthRGB, (float)nWidth); } void initShaderGray16() { // Create and compile vertex shader GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexSourceGray16, NULL); glCompileShader(vertexShader); // Create and compile fragment shader GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentSourceGray16, NULL); glCompileShader(fragmentShader); // Link vertex and fragment shader into shader program and use it g_shaderProgramGray16 = glCreateProgram(); glAttachShader(g_shaderProgramGray16, vertexShader); glAttachShader(g_shaderProgramGray16, fragmentShader); glLinkProgram(g_shaderProgramGray16); //glUseProgram(g_shaderProgramGray16); // Get shader variables and initialize them g_shaderPanGray16 = glGetUniformLocation(g_shaderProgramGray16, "pan"); g_shaderZoomGray16 = glGetUniformLocation(g_shaderProgramGray16, "zoom"); g_shaderAspectGray16 = glGetUniformLocation(g_shaderProgramGray16, "aspect"); g_shaderWindowCenterGray16 = glGetUniformLocation(g_shaderProgramGray16, "fWindowCenter"); g_shaderWindowWidthGray16 = glGetUniformLocation(g_shaderProgramGray16, "fWindowWidth"); glUniform1f(g_shaderWindowCenterGray16, 128.0f); glUniform1f(g_shaderWindowWidthGray16, 255.0f); //printf("pan:%d, zoom:%d, aspect:%d, g_shaderWindowCenterGray16:%d, g_shaderWindowWidthGray16:%d\n", g_shaderPanGray16, g_shaderZoomGray16, g_shaderAspectGray16, g_shaderWindowCenterGray16, g_shaderWindowWidthGray16); } void initShaderRGB() { // Create and compile vertex shader GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexSourceRGB, NULL); glCompileShader(vertexShader); // Create and compile fragment shader GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentSourceRGB, NULL); glCompileShader(fragmentShader); // Link vertex and fragment shader into shader program and use it g_shaderProgramRGB = glCreateProgram(); //printf("g_shaderProgramRGB: %d\n", g_shaderProgramRGB); glAttachShader(g_shaderProgramRGB, vertexShader); glAttachShader(g_shaderProgramRGB, fragmentShader); glLinkProgram(g_shaderProgramRGB); //glUseProgram(g_shaderProgramRGB); // Get shader variables and initialize them g_shaderPanRGB = glGetUniformLocation(g_shaderProgramRGB, "panRGB"); g_shaderZoomRGB = glGetUniformLocation(g_shaderProgramRGB, "zoomRGB"); g_shaderAspectRGB = glGetUniformLocation(g_shaderProgramRGB, "aspectRGB"); g_shaderWindowCenterRGB = glGetUniformLocation(g_shaderProgramRGB, "fWindowCenterRGB"); g_shaderWindowWidthRGB = glGetUniformLocation(g_shaderProgramRGB, "fWindowWidthRGB"); glUniform1f(g_shaderWindowCenterRGB, 128.0f); glUniform1f(g_shaderWindowWidthRGB, 255.0f); //printf("pan:%d, zoom:%d, aspect:%d, g_shaderWindowCenterRGB:%d, g_shaderWindowWidthRGB:%d\n", g_shaderPanRGB, g_shaderZoomRGB, g_shaderAspectRGB, g_shaderWindowCenterRGB, g_shaderWindowWidthRGB); } GLuint initShader(EventHandler& eventHandler) { initShaderGray16(); initShaderRGB(); updateShader(eventHandler); g_pEventHandler = &eventHandler; return g_shaderProgramGray16; } GLuint g_vbo = 0; void initGeometry(GLuint shaderProgram) { // Create vertex buffer object and copy vertex data into it //printf("g_vbo: %d\n", g_vbo); g_nWindowSizeWidth = (int)g_pEventHandler->camera().windowSize().width; g_nWindowSizeHeight = (int)g_pEventHandler->camera().windowSize().height; float fWindowWidth = (float)g_pEventHandler->camera().windowSize().width; float fWindowHeight = (float)g_pEventHandler->camera().windowSize().height; float fWindowRatio = fWindowWidth / fWindowHeight; float fFrameTextureRatio = (float)g_nFrameTextureWidth / (float)g_nFrameTextureHeight; float fRatioX = 1.0f; float fRatioY = 1.0f; float fRefWidthRatio = (float)g_nFrameTextureWidth / fWindowWidth; float fRefHeightRatio = (float)g_nFrameTextureHeight / fWindowHeight; if(fRefWidthRatio>fRefHeightRatio) { fRatioX = 1.0f; fRatioY = (fWindowWidth*((float)g_nFrameTextureHeight/(float)g_nFrameTextureWidth)) / fWindowHeight; } else { fRatioY = 1.0f; fRatioX = (fWindowHeight*((float)g_nFrameTextureWidth/(float)g_nFrameTextureHeight)) / fWindowWidth; } /* if(fRatioX>1.0f || fRatioY>1.0f) { float fMax = fRatioX; if(fRatioXtransferInit(); { error = g_pDcmDataset->read(dcmBuffer2, EXS_LittleEndianExplicit); g_pDcmDataset->findAndGetOFString(DCM_TransferSyntaxUID, strTransferSyntaxUID); g_pDcmDataset->transferEnd(); dcmBuffer2.releaseBuffer(); delete g_pDcmDataset; g_pDcmDataset = new DcmDataset; } if (strTransferSyntaxUID.size() > 0) { } DcmXfer dcmXfer(strTransferSyntaxUID.c_str()); g_pDcmDataset->transferInit(); //error = g_pDcmDataset->read(dcmBuffer, EXS_JPEGProcess14SV1); error = g_pDcmDataset->read(dcmBuffer, dcmXfer.getXfer()); if(error.bad()) { printf("Dataset State: %u(%s)\n", g_pDcmDataset->transferState(), error.text()); } g_pDcmDataset->transferEnd(); dcmBuffer.releaseBuffer(); g_nTotalFrames = 1; g_nFrameTextureWidth = 0; g_nFrameTextureHeight = 0; g_nSamplesPerPixel = 1; g_nBitsAllocated = 8; Uint16 val = 0; g_pDcmDataset->findAndGetUint16(DCM_Rows, val); g_nFrameTextureHeight = val; g_pDcmDataset->findAndGetUint16(DCM_Columns, val); g_nFrameTextureWidth = val; g_pDcmDataset->findAndGetUint16(DCM_SamplesPerPixel, val); g_nSamplesPerPixel = val; g_pDcmDataset->findAndGetUint16(DCM_BitsAllocated, val); g_nBitsAllocated = val; int nMaxValue = pow(2, g_nBitsAllocated) - 1; int nMinValue = 0; int nDefaultWindowWidth = nMaxValue - nMinValue; int nDefaultWindowCenter = (nMaxValue + nMinValue)/2; Sint32 nFrames = 0; OFString strTmp; OFString strFrames; // g_pDcmDataset->findAndGetSint32(DCM_NumberOfFrames, nFrames); g_pDcmDataset->findAndGetOFString(DCM_NumberOfFrames, strFrames); nFrames = atoi(strFrames.c_str()); if(nFrames<=0) { nFrames = 1; } else { strTmp = ""; g_pDcmDataset->findAndGetOFString(DCM_FrameTime, strTmp); printf("DCM_Frametime: %s\n", strTmp.c_str()); g_fFrameTime = atof(strTmp.c_str()); strTmp = ""; g_pDcmDataset->findAndGetOFString(DCM_FrameDelay, strTmp); printf("DCM_FrameDelay: %s\n", strTmp.c_str()); g_fFrameDelay = atof(strTmp.c_str()); } g_nTotalFrames = nFrames; strTmp = ""; g_pDcmDataset->findAndGetOFString(DCM_WindowCenter, strTmp); g_nDefaultWindowCenter = atoi(strTmp.c_str()); if(g_nDefaultWindowCenter==0) { g_nDefaultWindowCenter = nDefaultWindowCenter; } if(g_nWindowCenter<=0 && g_nDefaultWindowCenter) { g_nWindowCenter = g_nDefaultWindowCenter; } strTmp = ""; g_pDcmDataset->findAndGetOFString(DCM_WindowWidth, strTmp); g_nDefaultWindowWidth = atoi(strTmp.c_str()); if(g_nDefaultWindowWidth==0) { g_nDefaultWindowWidth = nDefaultWindowWidth; } if(g_nWindowWidth<=0 && g_nDefaultWindowWidth>0) { g_nWindowWidth = g_nDefaultWindowWidth; } /* Float64 fValue = 0.0f; fValue = 0; g_nDefaultWindowCenter = 0; g_pDcmDataset->findAndGetFloat64(DCM_WindowCenter, fValue); g_nDefaultWindowCenter = (int)val; if(g_nWindowCenter<=0 && g_nDefaultWindowCenter) { g_nWindowCenter = g_nDefaultWindowCenter; } fValue = 0; g_pDcmDataset->findAndGetFloat64(DCM_WindowWidth, fValue); g_nDefaultWindowWidth = (int)val; if(g_nWindowWidth<=0 && g_nDefaultWindowWidth>0) { g_nWindowWidth = g_nDefaultWindowWidth; } */ printf("File WindowWidth: %d, WindowCenter: %d\n", g_nDefaultWindowWidth, g_nDefaultWindowCenter); g_nPrevWindowCenter = g_nWindowCenter; g_nPrevWindowWidth = g_nWindowWidth; if(g_nSamplesPerPixel==3 && g_nBitsAllocated==8) { g_nColorType = 1; } else { g_nColorType = 0; } printf("ColorType:%d, Width:%d, Height:%d, TotalFrames:(%s)(%d) SamplesPerPixel:%d, BitsAllocated:%d\n", g_nColorType, g_nFrameTextureWidth, g_nFrameTextureHeight, strFrames.c_str(), g_nTotalFrames, g_nSamplesPerPixel, g_nBitsAllocated); if(g_nFrameTextureWidth==0) { DcmElement* pElement = NULL; g_pDcmDataset->findAndGetElement(DCM_Columns, pElement); printf("pElement: %x\n", pElement); } g_pixelDataElement = NULL; g_pDcmDataset->findAndGetElement(DCM_PixelData, g_pixelDataElement); printf("OnLoadedData: g_pixelDataElement: %x\n", g_pixelDataElement); const Uint8* pImageData = NULL; g_pDcmDataset->findAndGetUint8Array(DCM_PixelData, pImageData); if(pImageData!=NULL) { error = g_pDcmDataset->chooseRepresentation(EXS_LittleEndianExplicit, NULL); if(error.bad()) { printf("chooseRepresentation: %s\n", error.text()); } else { g_pDcmDataset->findAndGetUint8Array(DCM_PixelData, pImageData); } } else { printf("Find Pixel Data!!!\n"); if(g_pixelDataElement->isEmpty()==true) { printf("PixelData is Empty!!\n"); } else { printf("ok0\n"); Uint32 nFrameSizeUncompressed = 0; g_pixelDataElement->getUncompressedFrameSize(g_pDcmDataset, nFrameSizeUncompressed); g_nFrameSizeUncompressed = nFrameSizeUncompressed; printf("ok1: %d\n", g_nFrameSizeUncompressed); if(g_pBuf!=NULL) { delete[] g_pBuf; } g_pBuf = new char[g_nFrameSizeUncompressed]; OFCondition ofTest; OFString decompressedColorModel; Uint32 startFragment = 0; ofTest = g_pixelDataElement->getUncompressedFrame(g_pDcmDataset, 1, startFragment, g_pBuf, g_nFrameSizeUncompressed, decompressedColorModel); //printf("updateTextureRGB: %d, %d, %d, %d, %s\nerror: %s\n", g_nFrameTextureWidth, g_nFrameTextureHeight, startFragment, g_nFrameSizeUncompressed, decompressedColorModel.c_str(), ofTest.text()); updateTextureRGB(g_nFrameTextureWidth, g_nFrameTextureHeight, g_pBuf); //printf("sizeF: %d\n", sizeF); } } if(callback_UpdateDcmImageComplete!=NULL) { printf("callback_UpdateDcmImageComplete\n"); callback_UpdateDcmImageComplete(); } g_bChange = true; //g_bChange = false; //printf("load OK!\n"); } void initTextureGray16() { const Uint16* pImageData = NULL; g_pDcmDataset->findAndGetUint16Array(DCM_PixelData, pImageData); int w = g_nFrameTextureWidth; int h = g_nFrameTextureHeight; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); { glGenTextures(1, &textureObj); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textureObj); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); PrintError(); glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, w, h, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, pImageData); PrintError(); GLint nTextureID = glGetUniformLocation(g_shaderProgramGray16, "texSampler"); glActiveTexture(GL_TEXTURE0); glUniform1i(nTextureID, 0); } } void initTextureRGB() { const Uint8* pImageData = NULL; g_pDcmDataset->findAndGetUint8Array(DCM_PixelData, pImageData); int w = g_nFrameTextureWidth; int h = g_nFrameTextureHeight; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GLint format = GL_RGB; if(textureObj>=0) { glBindTexture(GL_TEXTURE_2D, 0); glDeleteTextures(1, &textureObj); } glGenTextures(1, &textureObj); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textureObj); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); PrintError(); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, pImageData); PrintError(); GLint nTextureID = glGetUniformLocation(g_shaderProgramRGB, "texSampler"); glActiveTexture(GL_TEXTURE0); glUniform1i(nTextureID, 0); } void redraw(EventHandler& eventHandler) { int nWindowSizeWidth = (int)g_pEventHandler->camera().windowSize().width; int nWindowSizeHeight = (int)g_pEventHandler->camera().windowSize().height; bool bSizeChange = false; if(nWindowSizeWidth != g_nWindowSizeWidth || nWindowSizeHeight != g_nWindowSizeHeight) { bSizeChange = true; } if(g_bChange==true) { if(g_nColorType==0) { printf("redraw: initTextureGray16\n"); initGeometry(g_shaderProgramGray16); glUseProgram(g_shaderProgramGray16); initTextureGray16(); updateShader(*g_pEventHandler); } else if(g_nColorType==1) { printf("redraw: initTextureRGB\n"); initGeometry(g_shaderProgramRGB); glUseProgram(g_shaderProgramRGB); initTextureRGB(); updateShader(*g_pEventHandler); } g_bChange = false; } if(bSizeChange==true) { if(g_nColorType==0) { printf("redraw: SizeChange initTextureGray16\n"); initGeometry(g_shaderProgramGray16); } else if(g_nColorType==1) { printf("redraw: SizeChange initTextureRGB\n"); initGeometry(g_shaderProgramRGB); } g_nWindowSizeWidth = (int)g_pEventHandler->camera().windowSize().width; g_nWindowSizeHeight = (int)g_pEventHandler->camera().windowSize().height; } if(g_nTotalFrames>1) { OFCondition ofTest; OFString decompressedColorModel; Uint32 nDisplayFrameIndex = g_nCurrentFrame; ofTest = g_pixelDataElement->getUncompressedFrame(g_pDcmDataset, 1, nDisplayFrameIndex, g_pBuf, g_nFrameSizeUncompressed, decompressedColorModel); if(g_nColorType==0) { updateTextureGray16(g_nFrameTextureWidth, g_nFrameTextureHeight, g_pBuf); } else if(g_nColorType==1) { //printf("updateTextureRGB: %d, %d, %d, %d, %s\nerror: %s\n", g_nFrameTextureWidth, g_nFrameTextureHeight, g_nCurrentFrame, g_nFrameSizeUncompressed, decompressedColorModel.c_str(), ofTest.text()); updateTextureRGB(g_nFrameTextureWidth, g_nFrameTextureHeight, g_pBuf); } if(g_nCurrentFrame>=g_nTotalFrames) { g_nCurrentFrame = 0; } } else { /* const Uint8* pImageData = NULL; g_pDcmDataset->findAndGetUint8Array(DCM_PixelData, pImageData); if(g_nColorType==0) { printf("updateTextureGray16: %d\n", g_nCurrentFrame); updateTextureGray16(g_nFrameTextureWidth, g_nFrameTextureHeight, (void*)pImageData); } else if(g_nColorType==1) { printf("updateTextureRGB: %d, %d, %x\n", g_nFrameTextureWidth, g_nFrameTextureHeight, pImageData); //printf("updateTextureRGB: %d, %d, %d, %d, %s\nerror: %s\n", g_nFrameTextureWidth, g_nFrameTextureHeight, g_nCurrentFrame, g_nFrameSizeUncompressed, decompressedColorModel.c_str(), ofTest.text()); updateTextureRGB(g_nFrameTextureWidth, g_nFrameTextureHeight, (void*)pImageData); } */ } if(g_nColorType==0) { updateWindowWidthLevelGray16(g_nPrevWindowWidth, g_nPrevWindowCenter); } else if(g_nColorType==1) { updateWindowWidthLevelRGB(g_nPrevWindowWidth, g_nPrevWindowCenter); } // Clear screen glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); //glUseProgram(g_shaderProgramGray16); // glActiveTexture(GL_TEXTURE0); // glBindTexture(GL_TEXTURE_2D, textureObj); //glBindBuffer(GL_ARRAY_BUFFER, g_vbo); // Draw the vertex buffer glDrawArrays(GL_TRIANGLES, 0, 6); //glDrawArrays(GL_QUADS, 0, 4); // Swap front/back framebuffers eventHandler.swapWindow(); //printf("redraw\n"); } void mainLoop(void* mainLoopArg) { EventHandler& eventHandler = *((EventHandler*)mainLoopArg); eventHandler.processEvents(); int nType = eventHandler.GetEventType(); if(nType==1 || nType==2) { float fDeltaX = eventHandler.GetDeltaX(); float fDeltaY = eventHandler.GetDeltaY(); g_nPrevWindowCenter = g_nWindowCenter+fDeltaY; g_nPrevWindowWidth = g_nWindowWidth + fDeltaX; //printf("DeltaX: %f, DeltaY:%f, (%d, %d)\n", fDeltaX, fDeltaY, g_nPrevWindowCenter, g_nPrevWindowWidth); // glUniform1f(g_shaderWindowCenterGray16, (float)g_nPrevWindowCenter); // glUniform1f(g_shaderWindowWidthGray16, (float)g_nPrevWindowWidth); // } else if(nType==3 || nType==4) { g_nWindowCenter = g_nPrevWindowCenter; g_nWindowWidth = g_nPrevWindowWidth; } // glUniform1f(g_shaderWindowCenterGray16, (float)g_nPrevWindowCenter); // glUniform1f(g_shaderWindowWidthGray16, (float)g_nPrevWindowWidth); // Update shader if camera changed if (eventHandler.camera().updated()) updateShader(eventHandler); redraw(eventHandler); } #ifdef __cplusplus #define EXTERN extern "C" #else #define EXTERN #endif EXTERN EMSCRIPTEN_KEEPALIVE int UpdateDcmImage(std::string strFile) { printf("UpdateDcmImage: %s\n", strFile.c_str()); emscripten_async_wget_data(strFile.c_str(), (void*)135, onLoadedData, onErrorData); return 0; } EXTERN EMSCRIPTEN_KEEPALIVE int SetWindowWidthLevel(int nWindowCenter, int nWindowWidth) { printf("New nWindowCenter:%d, nWindowWidth:%d\n", nWindowCenter, nWindowWidth); g_nWindowCenter = nWindowCenter; g_nWindowWidth = nWindowWidth; g_nPrevWindowCenter = g_nWindowCenter; g_nPrevWindowWidth = g_nWindowWidth; return 0; } EXTERN EMSCRIPTEN_KEEPALIVE int SetDisplayFrameIndex(int nIndex) { g_nCurrentFrame = nIndex; if(g_nCurrentFrame>=g_nTotalFrames) { g_nCurrentFrame = g_nTotalFrames-1; } return 0; } EXTERN EMSCRIPTEN_KEEPALIVE int SetResizeFrame(int nWidth, int nHeight) { printf("SetResizeFrame: (%d, %d)\n", nWidth, nHeight); g_pEventHandler->camera().setWindowSize(nWidth, nHeight); return 0; } EXTERN EMSCRIPTEN_KEEPALIVE int GetWindowWidth() { return g_nWindowWidth; } EXTERN EMSCRIPTEN_KEEPALIVE int GetWindowCenter() { return g_nWindowCenter; } EXTERN EMSCRIPTEN_KEEPALIVE int GetTotalFrames() { return g_nTotalFrames; } EXTERN EMSCRIPTEN_KEEPALIVE float GetFrameUpdateTimeDelay() { return (g_fFrameDelay + g_fFrameTime); } EXTERN EMSCRIPTEN_KEEPALIVE bool SetCallbackUpdateDcmImageComplete(callback_UpdateDcmImage callback_) { printf("SetCallbackUpdateDcmImage: %x\n", callback_); callback_UpdateDcmImageComplete = callback_; return true; } int main(int argc, char** argv) { OFLog::configure(OFLogger::OFF_LOG_LEVEL); EventHandler eventHandler("dcm image viewer"); // Initialize shader and geometry GLuint shaderProgram = initShader(eventHandler); //initTexture(); // Start the main loop void* mainLoopArg = &eventHandler; DJDecoderRegistration::registerCodecs(); DJLSDecoderRegistration::registerCodecs(); DcmRLEDecoderRegistration::registerCodecs(); //emscripten_async_wget_data("http://49.171.226.18:1901/3.dcm", (void*)135, onLoadedData, onErrorData); #ifdef __EMSCRIPTEN__ int fps = 0; // Use browser's requestAnimationFrame emscripten_set_main_loop_arg(mainLoop, mainLoopArg, fps, true); #else while(true) mainLoop(mainLoopArg); #endif glDeleteTextures(1, &textureObj); glBindTexture(GL_TEXTURE_2D, 0); DJDecoderRegistration::cleanup(); DJLSDecoderRegistration::cleanup(); DcmRLEDecoderRegistration::cleanup(); if(g_pDcmDataset!=NULL) { delete g_pDcmDataset; g_pDcmDataset = NULL; } printf("exit!!!!! c++ dcm_image_mod"); return 0; }