Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Thomas Pitiot
CGoGN
Commits
47d0007d
Commit
47d0007d
authored
Apr 20, 2011
by
Sylvain Thery
Browse files
sauvegarde avant suppression tous les cout cerr
parent
cfe6d910
Changes
5
Hide whitespace changes
Inline
Side-by-side
Apps/Tuto/tuto4.cpp
View file @
47d0007d
...
...
@@ -245,6 +245,9 @@ int main(int argc, char **argv)
// show final pour premier redraw
sqt
.
show
();
CGoGNout
.
out2Console
(
&
sqt
);
CGoGNerr
.
out2Console
(
&
sqt
);
// et on attend la fin.
return
app
.
exec
();
...
...
include/Container/sizeblock.h
View file @
47d0007d
...
...
@@ -26,6 +26,7 @@
#define _SIZEBLOCK_H_
#include
"gzstream.h"
#include
"Utils/cgognStream.h"
#define _BLOCKSIZE_ 4096
...
...
include/Utils/cgognStream.h
View file @
47d0007d
...
...
@@ -25,13 +25,12 @@
#ifndef _CGOGNSTREAM_H_
#define _CGOGNSTREAM_H_
// pb of compilation ??
#ifndef DBG_MAX_LEVEL
#define DBG_MAX_LEVEL 5
#endif
#include
<string>
#include
<iostream>
#include
<sstream>
...
...
include/Utils/cgognStream.hpp
View file @
47d0007d
...
...
@@ -192,9 +192,7 @@ Out<LEVEL>& Out<LEVEL>::operator<< (Special& os )
{
if
(
&
os
==
&
CGoGNendl
)
{
m_buffer
<<
std
::
endl
;
char
bufc
[
512
];
m_buffer
.
getline
(
bufc
,
512
);
// for cout & cerr just do the endl
if
(
m_out_mode
&
STDOUT
)
...
...
@@ -203,31 +201,56 @@ Out<LEVEL>& Out<LEVEL>::operator<< (Special& os )
std
::
cerr
<<
std
::
endl
;
if
(
m_out_mode
&
FILEOUT
)
*
m_ofs
<<
bufc
<<
std
::
endl
;
{
while
(
!
m_buffer
.
eof
())
{
m_buffer
.
getline
(
bufc
,
512
);
*
m_ofs
<<
bufc
<<
std
::
endl
;
}
}
if
(
m_out_mode
&
QTSTATUSBAR
)
m_sqt_bar
->
statusMsg
(
bufc
);
{
while
(
!
m_buffer
.
eof
())
{
m_buffer
.
getline
(
bufc
,
512
);
m_sqt_bar
->
statusMsg
(
bufc
);
}
}
if
(
m_out_mode
&
QTCONSOLE
)
{
if
(
m_code
>=
100
)
m_sqt_console
->
console
()
->
setTextColor
(
QColor
(
0
,
150
-
(
m_code
-
100
)
*
20
,
50
+
(
m_code
-
100
)
*
20
)
);
else
while
(
!
m_buffer
.
eof
())
{
if
(
m_code
>
0
)
m_sqt_console
->
console
()
->
setTextColor
(
QColor
(
150
,
0
,
0
)
);
m_buffer
.
getline
(
bufc
,
512
);
if
(
m_code
>=
100
)
m_sqt_console
->
console
()
->
setTextColor
(
QColor
(
0
,
150
-
(
m_code
-
100
)
*
20
,
50
+
(
m_code
-
100
)
*
20
)
);
else
m_sqt_console
->
console
()
->
setTextColor
(
QColor
(
0
,
0
,
150
)
);
{
if
(
m_code
>
0
)
m_sqt_console
->
console
()
->
setTextColor
(
QColor
(
150
,
0
,
0
)
);
else
m_sqt_console
->
console
()
->
setTextColor
(
QColor
(
0
,
0
,
150
)
);
}
m_sqt_console
->
console
()
->
insertPlainText
(
QString
(
bufc
));
m_sqt_console
->
console
()
->
insertPlainText
(
QString
(
"
\n
"
));
}
m_sqt_console
->
console
()
->
insertPlainText
(
QString
(
bufc
));
m_sqt_console
->
console
()
->
insertPlainText
(
QString
(
"
\n
"
));
}
if
(
m_out_mode
&
SSBUFFER
)
*
m_oss
<<
bufc
<<
std
::
endl
;
{
while
(
!
m_buffer
.
eof
())
{
m_buffer
.
getline
(
bufc
,
512
);
*
m_oss
<<
bufc
<<
std
::
endl
;
}
}
}
}
m_buffer
.
clear
();
return
*
this
;
}
...
...
src/Utils/GLSLShader.cpp
View file @
47d0007d
...
...
@@ -27,6 +27,7 @@
#include
<iostream>
#include
<fstream>
#include
<vector>
#include
"Utils/cgognStream.h"
#include
"glm/gtx/inverse_transpose.hpp"
...
...
@@ -166,7 +167,7 @@ char* GLSLShader::loadSourceFile( const std::string& filename)
if
(
!
file
.
good
()
)
{
std
::
c
err
<<
"ERROR - GLSLShader::loadSourceFile() - unable to open the file "
<<
filename
<<
"."
<<
std
::
endl
;
CGoGN
err
<<
"ERROR - GLSLShader::loadSourceFile() - unable to open the file "
<<
filename
<<
"."
<<
CGoGN
endl
;
return
NULL
;
}
...
...
@@ -188,7 +189,7 @@ char* GLSLShader::loadSourceFile( const std::string& filename)
}
catch
(
std
::
exception
&
io_exception
)
{
std
::
c
err
<<
"ERROR - GLSLShader::loadSourceFile() - "
<<
io_exception
.
what
()
<<
std
::
endl
;
CGoGN
err
<<
"ERROR - GLSLShader::loadSourceFile() - "
<<
io_exception
.
what
()
<<
CGoGN
endl
;
file
.
close
();
return
NULL
;
}
...
...
@@ -212,7 +213,7 @@ bool GLSLShader::loadVertexShader( const std::string& filename )
if
(
!
m_vertex_shader_source
)
{
std
::
c
err
<<
"ERROR - GLSLShader::loadVertexShader() - error occured while loading source file."
<<
std
::
endl
;
CGoGN
err
<<
"ERROR - GLSLShader::loadVertexShader() - error occured while loading source file."
<<
CGoGN
endl
;
return
false
;
}
...
...
@@ -236,7 +237,7 @@ bool GLSLShader::loadFragmentShader(const std::string& filename )
if
(
!
m_fragment_shader_source
)
{
std
::
c
err
<<
"ERROR - GLSLShader::loadFragmentShader() - error occured while loading source file."
<<
std
::
endl
;
CGoGN
err
<<
"ERROR - GLSLShader::loadFragmentShader() - error occured while loading source file."
<<
CGoGN
endl
;
return
false
;
}
...
...
@@ -264,7 +265,7 @@ bool GLSLShader::loadGeometryShader(const std::string& filename )
if
(
!
m_geom_shader_source
)
{
std
::
c
err
<<
"ERROR - GLSLShader::loadGeometryShader() - error occured while loading source file."
<<
std
::
endl
;
CGoGN
err
<<
"ERROR - GLSLShader::loadGeometryShader() - error occured while loading source file."
<<
CGoGN
endl
;
return
false
;
}
...
...
@@ -292,7 +293,7 @@ bool GLSLShader::loadVertexShaderSourceString( const char *vertex_shader_source
if
(
!
m_vertex_shader_object
)
{
std
::
c
err
<<
"ERROR - GLSLShader::loadVertexShader() - unable to create shader object."
<<
std
::
endl
;
CGoGN
err
<<
"ERROR - GLSLShader::loadVertexShader() - unable to create shader object."
<<
CGoGN
endl
;
return
false
;
}
...
...
@@ -300,7 +301,7 @@ bool GLSLShader::loadVertexShaderSourceString( const char *vertex_shader_source
/*** load source file ***/
if
(
!
vertex_shader_source
)
{
std
::
c
err
<<
"ERROR - GLSLShader::loadVertexShader() - source string is empty."
<<
std
::
endl
;
CGoGN
err
<<
"ERROR - GLSLShader::loadVertexShader() - source string is empty."
<<
CGoGN
endl
;
glDeleteObjectARB
(
m_vertex_shader_object
);
m_vertex_shader_object
=
0
;
...
...
@@ -317,10 +318,9 @@ bool GLSLShader::loadVertexShaderSourceString( const char *vertex_shader_source
glGetObjectParameterivARB
(
m_vertex_shader_object
,
GL_OBJECT_COMPILE_STATUS_ARB
,
&
status
);
if
(
!
status
)
{
std
::
c
err
<<
"ERROR - GLshader::loadVertexShader() - error occured while compiling shader
.
"
<<
std
::
endl
;
CGoGN
err
<<
"ERROR - GLshader::loadVertexShader() - error occured while compiling shader
"
<<
m_nameVS
<<
CGoGN
endl
;
info_log
=
getInfoLog
(
m_vertex_shader_object
);
std
::
cerr
<<
" COMPILATION OF "
<<
m_nameVS
<<
std
::
endl
;
std
::
cerr
<<
info_log
<<
std
::
endl
;
CGoGNerr
<<
info_log
<<
CGoGNendl
;
delete
[]
info_log
;
glDeleteObjectARB
(
m_vertex_shader_object
);
...
...
@@ -351,7 +351,7 @@ bool GLSLShader::loadFragmentShaderSourceString( const char *fragment_shader_sou
if
(
!
m_fragment_shader_object
)
{
std
::
c
err
<<
"ERROR - GLSLShader::loadFragmentShader() - unable to create shader object."
<<
std
::
endl
;
CGoGN
err
<<
"ERROR - GLSLShader::loadFragmentShader() - unable to create shader object."
<<
CGoGN
endl
;
return
false
;
}
...
...
@@ -359,7 +359,7 @@ bool GLSLShader::loadFragmentShaderSourceString( const char *fragment_shader_sou
/*** load source file ***/
if
(
!
fragment_shader_source
)
{
std
::
c
err
<<
"ERROR - GLSLShader::loadFragmentShader() - source string is empty."
<<
std
::
endl
;
CGoGN
err
<<
"ERROR - GLSLShader::loadFragmentShader() - source string is empty."
<<
CGoGN
endl
;
glDeleteObjectARB
(
m_fragment_shader_object
);
m_fragment_shader_object
=
0
;
...
...
@@ -376,9 +376,9 @@ bool GLSLShader::loadFragmentShaderSourceString( const char *fragment_shader_sou
glGetObjectParameterivARB
(
m_fragment_shader_object
,
GL_OBJECT_COMPILE_STATUS_ARB
,
&
status
);
if
(
!
status
)
{
std
::
c
err
<<
"ERROR - GLshader::loadFragmentShader() - error occured while compiling shader
.
"
<<
std
::
endl
;
CGoGN
err
<<
"ERROR - GLshader::loadFragmentShader() - error occured while compiling shader
"
<<
m_nameFS
<<
CGoGN
endl
;
info_log
=
getInfoLog
(
m_fragment_shader_object
);
std
::
c
err
<<
" COMPILATION OF "
<<
m_nameFS
<<
std
::
endl
<<
info_log
<<
std
::
endl
;
CGoGN
err
<<
info_log
<<
CGoGN
endl
;
delete
[]
info_log
;
glDeleteObjectARB
(
m_fragment_shader_object
);
...
...
@@ -410,7 +410,7 @@ bool GLSLShader::loadGeometryShaderSourceString( const char *geom_shader_source
if
(
!
m_geom_shader_object
)
{
std
::
c
err
<<
"ERROR - GLSLShader::loadGeometryShader() - unable to create shader object."
<<
std
::
endl
;
CGoGN
err
<<
"ERROR - GLSLShader::loadGeometryShader() - unable to create shader object."
<<
CGoGN
endl
;
return
false
;
}
...
...
@@ -418,7 +418,7 @@ bool GLSLShader::loadGeometryShaderSourceString( const char *geom_shader_source
/*** load source file ***/
if
(
!
geom_shader_source
)
{
std
::
c
err
<<
"ERROR - GLSLShader::loadGeometryShader() - source string is empty."
<<
std
::
endl
;
CGoGN
err
<<
"ERROR - GLSLShader::loadGeometryShader() - source string is empty."
<<
CGoGN
endl
;
glDeleteObjectARB
(
m_geom_shader_object
);
m_geom_shader_object
=
0
;
...
...
@@ -435,10 +435,9 @@ bool GLSLShader::loadGeometryShaderSourceString( const char *geom_shader_source
glGetObjectParameterivARB
(
m_geom_shader_object
,
GL_OBJECT_COMPILE_STATUS_ARB
,
&
status
);
if
(
!
status
)
{
std
::
c
err
<<
"ERROR - GLshader::loadGeometryShader() - error occured while compiling shader
."
<<
std
::
endl
;
CGoGN
err
<<
"ERROR - GLshader::loadGeometryShader() - error occured while compiling shader
"
<<
m_nameGS
<<
CGoGN
endl
;
info_log
=
getInfoLog
(
m_geom_shader_object
);
std
::
cerr
<<
" COMPILATION OF "
<<
m_nameGS
<<
std
::
endl
;
std
::
cerr
<<
info_log
<<
std
::
endl
;
CGoGNerr
<<
info_log
<<
CGoGNendl
;
delete
[]
info_log
;
glDeleteObjectARB
(
m_geom_shader_object
);
...
...
@@ -481,7 +480,7 @@ bool GLSLShader::create(GLint inputGeometryPrimitive,GLint outputGeometryPrimiti
/*** check if shaders are loaded ***/
if
(
!
m_vertex_shader_object
||
!
m_fragment_shader_object
)
{
std
::
c
err
<<
"ERROR - GLSLShader::create() - shaders are not defined."
<<
std
::
endl
;
CGoGN
err
<<
"ERROR - GLSLShader::create() - shaders are not defined."
<<
CGoGN
endl
;
return
false
;
}
...
...
@@ -491,7 +490,7 @@ bool GLSLShader::create(GLint inputGeometryPrimitive,GLint outputGeometryPrimiti
if
(
!
m_program_object
)
{
std
::
c
err
<<
"ERROR - GLSLShader::create() - unable to create program object."
<<
std
::
endl
;
CGoGN
err
<<
"ERROR - GLSLShader::create() - unable to create program object."
<<
CGoGN
endl
;
return
false
;
}
...
...
@@ -517,9 +516,9 @@ bool GLSLShader::create(GLint inputGeometryPrimitive,GLint outputGeometryPrimiti
glGetObjectParameterivARB
(
m_program_object
,
GL_OBJECT_LINK_STATUS_ARB
,
&
status
);
if
(
!
status
)
{
std
::
c
err
<<
"ERROR - GLSLShader::create() - error occured while linking shader program."
<<
std
::
endl
;
CGoGN
err
<<
"ERROR - GLSLShader::create() - error occured while linking shader program."
<<
CGoGN
endl
;
info_log
=
getInfoLog
(
m_program_object
);
std
::
c
err
<<
" LINK "
<<
info_log
<<
std
::
endl
;
CGoGN
err
<<
" LINK "
<<
info_log
<<
CGoGN
endl
;
delete
[]
info_log
;
glDetachObjectARB
(
m_program_object
,
m_vertex_shader_object
);
...
...
@@ -553,9 +552,9 @@ bool GLSLShader::link()
glGetObjectParameterivARB
(
m_program_object
,
GL_OBJECT_LINK_STATUS_ARB
,
&
status
);
if
(
!
status
)
{
std
::
c
err
<<
"ERROR - GLSLShader::create() - error occured while linking shader program."
<<
std
::
endl
;
CGoGN
err
<<
"ERROR - GLSLShader::create() - error occured while linking shader program."
<<
CGoGN
endl
;
info_log
=
getInfoLog
(
m_program_object
);
std
::
c
err
<<
" LINK "
<<
info_log
<<
std
::
endl
;
CGoGN
err
<<
" LINK "
<<
info_log
<<
CGoGN
endl
;
delete
[]
info_log
;
glDetachObjectARB
(
m_program_object
,
m_vertex_shader_object
);
...
...
@@ -677,15 +676,15 @@ bool GLSLShader::init()
GLenum
error
=
glewInit
();
if
(
error
!=
GLEW_OK
)
std
::
c
err
<<
"Error: "
<<
glewGetErrorString
(
error
)
<<
std
::
endl
;
CGoGN
err
<<
"Error: "
<<
glewGetErrorString
(
error
)
<<
CGoGN
endl
;
else
std
::
c
out
<<
"Status: Using GLEW "
<<
glewGetString
(
GLEW_VERSION
)
<<
std
::
endl
;
CGoGN
out
<<
"Status: Using GLEW "
<<
glewGetString
(
GLEW_VERSION
)
<<
CGoGN
endl
;
if
(
!
areVBOSupported
())
std
::
c
out
<<
"VBO not supported !"
<<
std
::
endl
;
CGoGN
out
<<
"VBO not supported !"
<<
CGoGN
endl
;
if
(
!
areShadersSupported
())
{
std
::
c
out
<<
"Shaders not supported !"
<<
std
::
endl
;
CGoGN
out
<<
"Shaders not supported !"
<<
CGoGN
endl
;
return
false
;
}
return
true
;
...
...
@@ -703,10 +702,10 @@ bool GLSLShader::loadShaders(const std::string& vs, const std::string& ps)
if
(
!
loadFragmentShader
(
pss
))
return
false
;
if
(
!
create
())
{
std
::
c
out
<<
"Unable to create the shaders !"
<<
std
::
endl
;
CGoGN
out
<<
"Unable to create the shaders !"
<<
CGoGN
endl
;
return
false
;
}
std
::
c
out
<<
"Shaders loaded ("
<<
vs
<<
","
<<
ps
<<
")"
<<
std
::
endl
;
CGoGN
out
<<
"Shaders loaded ("
<<
vs
<<
","
<<
ps
<<
")"
<<
CGoGN
endl
;
return
true
;
}
...
...
@@ -727,17 +726,17 @@ bool GLSLShader::loadShaders(const std::string& vs, const std::string& ps, const
if
(
!
geomShaderLoaded
)
{
std
::
c
err
<<
"Error while loading geometry shader"
<<
std
::
endl
;
CGoGN
err
<<
"Error while loading geometry shader"
<<
CGoGN
endl
;
}
if
(
!
create
(
inputGeometryPrimitive
,
outputGeometryPrimitive
))
{
std
::
c
out
<<
"Unable to create the shaders !"
<<
std
::
endl
;
CGoGN
out
<<
"Unable to create the shaders !"
<<
CGoGN
endl
;
return
false
;
}
std
::
c
out
<<
"Shaders loaded ("
<<
vs
<<
","
<<
ps
<<
","
<<
gs
<<
")"
<<
std
::
endl
;
CGoGN
out
<<
"Shaders loaded ("
<<
vs
<<
","
<<
ps
<<
","
<<
gs
<<
")"
<<
CGoGN
endl
;
return
true
;
}
...
...
@@ -767,7 +766,7 @@ bool GLSLShader::loadShadersFromMemory(const char* vs, const char* fs)
if
(
!
create
())
{
std
::
c
out
<<
"Unable to create the shaders !"
<<
std
::
endl
;
CGoGN
out
<<
"Unable to create the shaders !"
<<
CGoGN
endl
;
return
false
;
}
return
true
;
...
...
@@ -805,7 +804,7 @@ bool GLSLShader::loadShadersFromMemory(const char* vs, const char* fs, const cha
if
(
!
create
(
inputGeometryPrimitive
,
outputGeometryPrimitive
))
{
std
::
c
out
<<
"Unable to create the shaders !"
<<
std
::
endl
;
CGoGN
out
<<
"Unable to create the shaders !"
<<
CGoGN
endl
;
return
false
;
}
...
...
@@ -861,16 +860,14 @@ bool GLSLShader::recompile()
if
(
!
create
(
m_geom_inputPrimitives
,
m_geom_outputPrimitives
))
{
std
::
cout
<<
"Unable to create the shaders !"
<<
std
::
endl
;
CGoGNerr
<<
"Unable to create the shaders !"
<<
CGoGN
endl
;
return
false
;
}
std
::
cout
<<
"DDDD"
<<
std
::
endl
;
m_uniMat_Proj
=
glGetUniformLocation
(
m_program_object
,
"ProjectionMatrix"
);
m_uniMat_Model
=
glGetUniformLocation
(
m_program_object
,
"ModelViewMatrix"
);
m_uniMat_ModelProj
=
glGetUniformLocation
(
m_program_object
,
"ModelViewProjectionMatrix"
);
m_uniMat_Normal
=
glGetUniformLocation
(
m_program_object
,
"NormalMatrix"
);
std
::
cout
<<
"EEEE"
<<
std
::
endl
;
restoreUniformsAttribs
();
...
...
@@ -889,12 +886,12 @@ bool GLSLShader::validateProgram()
if
(
Result
==
GL_FALSE
)
{
std
::
c
out
<<
"Validate program:"
<<
std
::
endl
;
CGoGN
out
<<
"Validate program:"
<<
CGoGN
endl
;
int
InfoLogLength
;
glGetProgramiv
(
m_program_object
,
GL_INFO_LOG_LENGTH
,
&
InfoLogLength
);
std
::
vector
<
char
>
Buffer
(
InfoLogLength
);
glGetProgramInfoLog
(
m_program_object
,
InfoLogLength
,
NULL
,
&
Buffer
[
0
]);
std
::
c
out
<<
&
(
Buffer
[
0
])
<<
std
::
endl
;
CGoGN
out
<<
&
(
Buffer
[
0
])
<<
CGoGN
endl
;
return
false
;
}
...
...
@@ -910,7 +907,7 @@ bool GLSLShader::checkProgram()
glGetProgramiv
(
m_program_object
,
GL_INFO_LOG_LENGTH
,
&
InfoLogLength
);
std
::
vector
<
char
>
Buffer
(
std
::
max
(
InfoLogLength
,
int
(
1
)));
glGetProgramInfoLog
(
m_program_object
,
InfoLogLength
,
NULL
,
&
Buffer
[
0
]);
std
::
c
out
<<
&
Buffer
[
0
]
<<
std
::
endl
;
CGoGN
out
<<
&
Buffer
[
0
]
<<
CGoGN
endl
;
return
Result
==
GL_TRUE
;
}
...
...
@@ -933,7 +930,7 @@ bool GLSLShader::checkShader(int shaderType)
id
=
m_geom_shader_object
;
break
;
default:
std
::
c
err
<<
"Error unkown shader type"
<<
std
::
endl
;
CGoGN
err
<<
"Error unkown shader type"
<<
CGoGN
endl
;
return
false
;
break
;
}
...
...
@@ -942,7 +939,7 @@ bool GLSLShader::checkShader(int shaderType)
glGetShaderiv
(
id
,
GL_INFO_LOG_LENGTH
,
&
InfoLogLength
);
std
::
vector
<
char
>
Buffer
(
InfoLogLength
);
glGetShaderInfoLog
(
id
,
InfoLogLength
,
NULL
,
&
Buffer
[
0
]);
std
::
c
out
<<
&
Buffer
[
0
]
<<
std
::
endl
;
CGoGN
out
<<
&
Buffer
[
0
]
<<
CGoGN
endl
;
return
Result
==
GL_TRUE
;
}
...
...
@@ -983,7 +980,7 @@ unsigned int GLSLShader::bindVA_VBO(const std::string& name, VBO* vbo)
//valid ?
if
(
idVA
<
0
)
{
std
::
c
err
<<
"GLSLShader: Attribute "
<<
name
<<
" does not exist in shader"
<<
std
::
endl
;
CGoGN
err
<<
"GLSLShader: Attribute "
<<
name
<<
" does not exist in shader"
<<
CGoGN
endl
;
return
idVA
;
}
// search if name already exist
...
...
@@ -1015,7 +1012,7 @@ void GLSLShader::unbindVA(const std::string& name)
//valid ?
if
(
idVA
<
0
)
{
std
::
c
err
<<
"GLSLShader: Attribute "
<<
name
<<
" does not exist in shader, not unbinded"
<<
std
::
endl
;
CGoGN
err
<<
"GLSLShader: Attribute "
<<
name
<<
" does not exist in shader, not unbinded"
<<
CGoGN
endl
;
return
;
}
// search if name already exist
...
...
@@ -1030,7 +1027,7 @@ void GLSLShader::unbindVA(const std::string& name)
return
;
}
}
std
::
c
err
<<
"GLSLShader: Attribute "
<<
name
<<
" not binded"
<<
std
::
endl
;
CGoGN
err
<<
"GLSLShader: Attribute "
<<
name
<<
" not binded"
<<
CGoGN
endl
;
}
void
GLSLShader
::
setCurrentOGLVersion
(
unsigned
int
version
)
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment