720 lines
20 KiB
C++
720 lines
20 KiB
C++
//
|
|
// 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 <emscripten.h>
|
|
#endif
|
|
|
|
#include <SDL2/SDL.h>
|
|
#include <SDL2/SDL_opengles2.h>
|
|
//#include <SDL2/SDL_opengles2_gl2ext.h>
|
|
//#include <GLES3/gl3.h>
|
|
|
|
#include <string>
|
|
|
|
|
|
#include "events.h"
|
|
|
|
extern "C" {
|
|
#include "libavutil/avstring.h"
|
|
#include "libavutil/channel_layout.h"
|
|
#include "libavutil/eval.h"
|
|
#include "libavutil/mathematics.h"
|
|
#include "libavutil/pixdesc.h"
|
|
#include "libavutil/imgutils.h"
|
|
#include "libavutil/dict.h"
|
|
#include "libavutil/fifo.h"
|
|
#include "libavutil/parseutils.h"
|
|
#include "libavutil/samplefmt.h"
|
|
#include "libavutil/time.h"
|
|
#include "libavutil/bprint.h"
|
|
#include "libavformat/avformat.h"
|
|
#include "libavdevice/avdevice.h"
|
|
#include "libswscale/swscale.h"
|
|
#include "libavutil/opt.h"
|
|
#include "libavcodec/avfft.h"
|
|
#include "libavcodec/avcodec.h"
|
|
#include "libswresample/swresample.h"
|
|
|
|
}
|
|
|
|
typedef void (*callback_UpdateDcmImage) ();
|
|
callback_UpdateDcmImage callback_UpdateDcmImageComplete = NULL;
|
|
|
|
|
|
uint8_t* g_pImageData = NULL;
|
|
|
|
SwsContext *img_convert_ctx = NULL;
|
|
AVFormatContext* format_ctx = NULL;
|
|
AVCodecContext* codec_ctx = NULL;
|
|
int video_stream_index = -1;
|
|
|
|
std::string g_strFilename = "";
|
|
bool g_bLoadFile = false;
|
|
|
|
|
|
|
|
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_nColorType = 1;
|
|
|
|
int g_nWindowCenter = 0;
|
|
int g_nWindowWidth = 0;
|
|
|
|
int g_nPrevWindowCenter = 0;
|
|
int g_nPrevWindowWidth = 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;
|
|
|
|
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);
|
|
}
|
|
|
|
void initTextureGray16(void* pImageData)
|
|
{
|
|
//const Uint16* pImageData = NULL;
|
|
//g_pDcmDataset->findAndGetUint16Array(DCM_PixelData, pImageData);
|
|
|
|
int w = g_nFrameWidth;
|
|
int h = g_nFrameHeight;
|
|
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");
|
|
//printf("texSampler: %d\n", nTextureID);
|
|
|
|
glActiveTexture(GL_TEXTURE0);
|
|
|
|
glUniform1i(nTextureID, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void initTextureRGB(void* pImageData)
|
|
{
|
|
printf("initTextureRGB\n");
|
|
//const Uint8* pImageData = NULL;
|
|
//g_pDcmDataset->findAndGetUint8Array(DCM_PixelData, 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);
|
|
}
|
|
|
|
|
|
|
|
void redraw(EventHandler& eventHandler)
|
|
{
|
|
if(g_bChange==true)
|
|
{
|
|
if(g_nColorType==0)
|
|
{
|
|
initGeometry(g_shaderProgramGray16);
|
|
glUseProgram(g_shaderProgramGray16);
|
|
initTextureGray16(g_pImageData);
|
|
updateShader(*g_pEventHandler);
|
|
}
|
|
else if(g_nColorType==1)
|
|
{
|
|
initGeometry(g_shaderProgramRGB);
|
|
glUseProgram(g_shaderProgramRGB);
|
|
initTextureRGB(g_pImageData);
|
|
updateShader(*g_pEventHandler);
|
|
}
|
|
g_bChange = false;
|
|
}
|
|
|
|
if(g_nTotalFrames>0)
|
|
{
|
|
if(g_nColorType==0)
|
|
{
|
|
printf("updateTextureRGB: %d\n", g_nCurrentFrame);
|
|
updateTextureGray16(g_nFrameWidth, g_nFrameHeight, g_pImageData);
|
|
}
|
|
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_pImageData);
|
|
}
|
|
|
|
if(g_nCurrentFrame>=g_nTotalFrames)
|
|
{
|
|
g_nCurrentFrame = 0;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
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);
|
|
|
|
// Draw the vertex buffer
|
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
|
|
// Swap front/back framebuffers
|
|
eventHandler.swapWindow();
|
|
}
|
|
|
|
void mainLoop(void* mainLoopArg)
|
|
{
|
|
EventHandler& eventHandler = *((EventHandler*)mainLoopArg);
|
|
eventHandler.processEvents();
|
|
|
|
if(g_bLoadFile==false && g_strFilename.size()>0)
|
|
{
|
|
AVDictionary *opts = NULL;
|
|
int ret = av_dict_set(&opts, "rtsp_transport", "tcp", 0);
|
|
// av_dict_set(&opts, "rtsp_transport", "tcp", 0);
|
|
|
|
// av_dict_set(&opts, "timeout", "5000", 0);
|
|
|
|
printf("UpdateDcmImage: av_dic_set\n");
|
|
|
|
g_strFilename = "http://localhost:5173/playlist_1080p.m3u8";
|
|
|
|
printf("filename: %s\n", g_strFilename.c_str());
|
|
|
|
//open RTSP
|
|
//
|
|
// printf("avformat_open_input: start1212121212\n");
|
|
|
|
|
|
// format_ctx = avformat_alloc_context();
|
|
|
|
//if (avformat_open_input(&format_ctx, g_strFilename.c_str(), NULL, &opts) != 0)
|
|
if (avformat_open_input(&format_ctx, g_strFilename.c_str(), NULL, NULL) != 0)
|
|
{
|
|
printf("Error avformat_open_input");
|
|
//return EXIT_FAILURE;
|
|
}
|
|
|
|
printf("avformat_open_input: finish\n");
|
|
|
|
|
|
av_dict_free(&opts);
|
|
|
|
callback_UpdateDcmImageComplete();
|
|
|
|
g_bLoadFile = true;
|
|
|
|
}
|
|
|
|
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;
|
|
}
|
|
else if(nType==3 || nType==4)
|
|
{
|
|
g_nWindowCenter = g_nPrevWindowCenter;
|
|
g_nWindowWidth = 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 strURL)
|
|
{
|
|
|
|
printf("UpdateDcmImage: %s\n", strURL.c_str());
|
|
|
|
g_strFilename = strURL;
|
|
/*
|
|
|
|
AVDictionary *opts = NULL;
|
|
int ret = av_dict_set(&opts, "rtsp_transport", "tcp", 0);
|
|
|
|
printf("UpdateDcmImage: av_dic_set\n");
|
|
|
|
//open RTSP
|
|
|
|
if (avformat_open_input(&format_ctx, strURL.c_str(), NULL, &opts) != 0)
|
|
{
|
|
printf("Error avformat_open_input");
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
|
|
av_dict_free(&opts);
|
|
|
|
callback_UpdateDcmImageComplete();
|
|
*/
|
|
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");
|
|
|
|
avdevice_register_all();
|
|
avformat_network_init();
|
|
|
|
if(g_pImageData==NULL)
|
|
{
|
|
g_pImageData = new uint8_t[1920*1080*3];
|
|
int i=0;
|
|
int j=0;
|
|
for(i=0 ; i<1080 ; i++)
|
|
{
|
|
for(j=0 ; j<1920 ; j++)
|
|
{
|
|
g_pImageData[(i*1920+j)*3+0] = 128;
|
|
g_pImageData[(i*1920+j)*3+1] = 128;
|
|
g_pImageData[(i*1920+j)*3+2] = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Initialize shader and geometry
|
|
GLuint shaderProgram = initShader(eventHandler);
|
|
|
|
//initTexture();
|
|
|
|
// Start the main loop
|
|
void* mainLoopArg = &eventHandler;
|
|
|
|
#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);
|
|
|
|
if(g_pImageData!=NULL)
|
|
{
|
|
delete[] g_pImageData;
|
|
g_pImageData = NULL;
|
|
}
|
|
|
|
printf("exit!!!!! c++ dcm_image_mod");
|
|
|
|
return 0;
|
|
}
|