// // 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 "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_nColorType = 0; Uint32 g_nCurrentFrame = 0; int g_nTotalFrames = 0; int g_nFrameWidth = 0; int g_nFrameHeight = 0; int g_nSamplesPerPixel = 0; int g_nBitsAllocated = 0; int g_nFrameSizeUncompressed = 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); glGenBuffers(1, &g_vbo); glBindBuffer(GL_ARRAY_BUFFER, g_vbo); GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, }; glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // Specify the layout of the shader vertex data (positions only, 3 floats) GLint posAttrib = glGetAttribLocation(shaderProgram, "position"); glEnableVertexAttribArray(posAttrib); // glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (GLvoid*)0); // glEnableVertexAttribArray(0); GLint texAttrib = glGetAttribLocation(shaderProgram, "a_texCoord"); glEnableVertexAttribArray(texAttrib); glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (GLvoid*)(3*sizeof(GLfloat))); //glEnableVertexAttribArray(2); // glBindBuffer(GL_ARRAY_BUFFER, 0); //printf("initGeometry(%d, %d)\n", posAttrib, texAttrib); } void PrintError() { int nError = 0; nError = glGetError(); printf("Error Code: %d\n", nError); } void onLoadedData(void* arg, void* buffer, int nSize) { //printf("onLoadedData %d, %d\n", (int)arg, nSize); OFCondition error; E_TransferSyntax opt_ixfer = EXS_Unknown; E_FileReadMode opt_readMode = ERM_autoDetect; Uint8* pData = (Uint8*)buffer; int nFindIndex = 0; bool bFind = false; int i=0; Uint8* pDataTmp = (Uint8*)buffer; for(i=0 ; itransferInit(); { 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_nFrameWidth = 0; g_nFrameHeight = 0; g_nSamplesPerPixel = 1; g_nBitsAllocated = 8; Uint16 val = 0; g_pDcmDataset->findAndGetUint16(DCM_Rows, val); g_nFrameHeight = val; g_pDcmDataset->findAndGetUint16(DCM_Columns, val); g_nFrameWidth = val; g_pDcmDataset->findAndGetUint16(DCM_SamplesPerPixel, val); g_nSamplesPerPixel = val; g_pDcmDataset->findAndGetUint16(DCM_BitsAllocated, val); g_nBitsAllocated = val; Sint32 nFrames = 0; OFString strFrames; // g_pDcmDataset->findAndGetSint32(DCM_NumberOfFrames, nFrames); g_pDcmDataset->findAndGetOFString(DCM_NumberOfFrames, strFrames); nFrames = atoi(strFrames.c_str()); if(nFrames<=0) { nFrames = 1; } g_nTotalFrames = nFrames; OFString strTmp; strTmp = ""; g_pDcmDataset->findAndGetOFString(DCM_WindowCenter, strTmp); if(g_nWindowCenter<=0) g_nWindowCenter = atoi(strTmp.c_str()); strTmp = ""; g_pDcmDataset->findAndGetOFString(DCM_WindowWidth, strTmp); if(g_nWindowWidth<=0) g_nWindowWidth = atoi(strTmp.c_str()); 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_nFrameWidth, g_nFrameHeight, strFrames.c_str(), g_nTotalFrames, g_nSamplesPerPixel, g_nBitsAllocated); if(g_nFrameWidth==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); 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_nFrameWidth, g_nFrameHeight, startFragment, g_nFrameSizeUncompressed, decompressedColorModel.c_str(), ofTest.text()); updateTextureRGB(g_nFrameWidth, g_nFrameHeight, 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->findAndGetUint8Array(DCM_PixelData, pImageData); g_pDcmDataset->findAndGetUint16Array(DCM_PixelData, pImageData); //printf("PixelPointer: %x\n", pImageData); int w = g_nFrameWidth; int h = g_nFrameHeight; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //SDL_Surface* image = SDL_CreateRGBSurface(0, w, h, 24, 0, 0, 0, 0); //memset(image->pixels, 0x1f, image->w * image->h * 3); // //Uint8* pData = new Uint8[1920*1080*4]; //memset(pData, 0xff, 1920*1080*4); //if(image!=NULL) { 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, format, w, h, 0, format, GL_UNSIGNED_BYTE, pData); glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, w, h, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, pImageData); // glTexImage2D(GL_TEXTURE_2D, 0, GL_R16I, w, h, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, pData16); PrintError(); GLint nTextureID = glGetUniformLocation(g_shaderProgramGray16, "texSampler"); //printf("texSampler: %d\n", nTextureID); glActiveTexture(GL_TEXTURE0); glUniform1i(nTextureID, 0); // glBindTexture(GL_TEXTURE_2D, 0); } // updateWindowWidthLevelGray16(g_nWindowWidth, g_nWindowCenter); // glUniform1f(g_shaderWindowCenterGray16, (float)g_nWindowCenter); // glUniform1f(g_shaderWindowWidthGray16, (float)g_nWindowWidth); //printf("WindowCenter: %d, WindowWidth: %d\n", g_nWindowCenter, g_nWindowWidth); //delete g_pDcmDataset; //glUseProgram(g_shaderProgramGray16); } void initTextureRGB() { //printf("initTextureRGB\n"); const Uint8* pImageData = NULL; g_pDcmDataset->findAndGetUint8Array(DCM_PixelData, pImageData); //printf("PixelPointer: %x\n", pImageData); int w = g_nFrameWidth; int h = g_nFrameHeight; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GLint format = GL_RGB; //printf("textureObj: %d\n", textureObj); 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"); //printf("texSampler: %d\n", nTextureID); glActiveTexture(GL_TEXTURE0); glUniform1i(nTextureID, 0); // updateWindowWidthLevelRGB(g_nWindowWidth, g_nWindowCenter); // glUniform1f(g_shaderWindowCenterRGB, (float)g_nWindowCenter); // glUniform1f(g_shaderWindowWidthRGB, (float)g_nWindowWidth); // printf("WindowCenter: %d, WindowWidth: %d\n", g_nWindowCenter, g_nWindowWidth); /* if(g_pDcmDataset!=NULL) { delete g_pDcmDataset; g_pDcmDataset = NULL; } */ } void redraw(EventHandler& eventHandler) { if(g_bChange==true) { if(g_nColorType==0) { initGeometry(g_shaderProgramGray16); glUseProgram(g_shaderProgramGray16); initTextureGray16(); updateShader(*g_pEventHandler); } else if(g_nColorType==1) { initGeometry(g_shaderProgramRGB); glUseProgram(g_shaderProgramRGB); initTextureRGB(); updateShader(*g_pEventHandler); } g_bChange = false; } //printf("g_nTotalFrames: %d\n", g_nTotalFrames); if(g_nTotalFrames>0) { OFCondition ofTest; OFString decompressedColorModel; ofTest = g_pixelDataElement->getUncompressedFrame(g_pDcmDataset, 1, g_nCurrentFrame, g_pBuf, g_nFrameSizeUncompressed, decompressedColorModel); if(g_nColorType==0) { printf("updateTextureRGB: %d\n", g_nCurrentFrame); updateTextureGray16(g_nFrameWidth, g_nFrameHeight, g_pBuf); } else if(g_nColorType==1) { //printf("updateTextureRGB: %d, %d, %d, %d, %s\nerror: %s\n", g_nFrameWidth, g_nFrameHeight, g_nCurrentFrame, g_nFrameSizeUncompressed, decompressedColorModel.c_str(), ofTest.text()); updateTextureRGB(g_nFrameWidth, g_nFrameHeight, g_pBuf); } if(g_nCurrentFrame>=g_nTotalFrames) { g_nCurrentFrame = 0; } } if(g_nColorType==0) { updateWindowWidthLevelGray16(g_nPrevWindowWidth, g_nPrevWindowCenter); // glUniform1f(g_shaderWindowCenterGray16, (float)g_nPrevWindowCenter); // glUniform1f(g_shaderWindowWidthGray16, (float)g_nPrevWindowWidth); } else if(g_nColorType==1) { updateWindowWidthLevelRGB(g_nPrevWindowWidth, g_nPrevWindowCenter); // glUniform1f(g_shaderWindowCenterRGB, (float)g_nPrevWindowCenter); // glUniform1f(g_shaderWindowWidthRGB, (float)g_nPrevWindowWidth); } // 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 GetWindowWidth() { return g_nWindowWidth; } EXTERN EMSCRIPTEN_KEEPALIVE int GetWindowCenter() { return g_nWindowCenter; } EXTERN EMSCRIPTEN_KEEPALIVE bool SetCallbackUpdateDcmImageComplete(callback_UpdateDcmImage callback_) { printf("SetCallbackUpdateDcmImage: %x\n", callback_); callback_UpdateDcmImageComplete = callback_; return true; } int main(int argc, char** argv) { 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; }