webgl.C 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. /*
  2. * Copyright (C) 2010 Emweb bvba, Heverlee, Belgium.
  3. *
  4. * See the LICENSE file for terms of use.
  5. */
  6. #include <Wt/WApplication>
  7. #include <Wt/WBreak>
  8. #include <Wt/WContainerWidget>
  9. #include <Wt/WText>
  10. #include <Wt/WGLWidget>
  11. #include <Wt/WMatrix4x4>
  12. #include <Wt/WGenericMatrix>
  13. using namespace Wt;
  14. const char *fragmentShaderSrc =
  15. "#ifdef GL_ES\n"
  16. "precision highp float;\n"
  17. "#endif\n"
  18. "\n"
  19. "varying vec4 vColor;\n"
  20. "\n"
  21. "void main(void) {\n"
  22. " gl_FragColor = vColor;\n"
  23. "}\n";
  24. const char *vertexShaderSrc =
  25. "attribute vec3 aVertexPosition;\n"
  26. "attribute vec4 aVertexColor;\n"
  27. "\n"
  28. "uniform mat4 uMVMatrix;\n"
  29. "uniform mat4 uCMatrix;\n"
  30. "uniform mat4 uPMatrix;\n"
  31. "\n"
  32. "varying vec4 vColor;\n"
  33. "\n"
  34. "void main(void) {\n"
  35. " gl_Position = uPMatrix * uCMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n"
  36. " vColor = aVertexColor;\n"
  37. "}\n";
  38. const char *texFragmentShaderSrc =
  39. "#ifdef GL_ES\n"
  40. "precision highp float;\n"
  41. "#endif\n"
  42. ""
  43. "varying vec2 vTextureCoord;\n"
  44. ""
  45. "uniform sampler2D uSampler;\n"
  46. ""
  47. "void main(void) {\n"
  48. " gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));\n"
  49. "}\n";
  50. const char *texVertexShaderSrc =
  51. "attribute vec3 aVertexPosition;\n"
  52. "attribute vec2 aTextureCoord;\n"
  53. ""
  54. "uniform mat4 uMVMatrix;\n"
  55. "uniform mat4 uCMatrix;\n"
  56. "uniform mat4 uPMatrix;\n"
  57. ""
  58. "varying vec2 vTextureCoord;\n"
  59. ""
  60. "void main(void) {\n"
  61. " gl_Position = uPMatrix * uCMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n"
  62. " vTextureCoord = aTextureCoord;\n"
  63. "}\n";
  64. class PaintWidget: public WGLWidget
  65. {
  66. public:
  67. PaintWidget(WContainerWidget *root):
  68. WGLWidget(root)
  69. {
  70. jsMatrix_ = JavaScriptMatrix4x4();
  71. addJavaScriptMatrix4(jsMatrix_);
  72. }
  73. void initializeGL()
  74. {
  75. initJavaScriptMatrix4(jsMatrix_);
  76. WMatrix4x4 worldTransform;
  77. worldTransform.lookAt(0, 0, 5, 0, 0, -1, 0, 1, 0);
  78. setJavaScriptMatrix4(jsMatrix_, worldTransform);
  79. //setClientSideWalkHandler(jsMatrix_, 1./20, 1./100);
  80. setClientSideLookAtHandler(jsMatrix_, 0, 0, 0, 0, 1, 0, 0.005, 0.005);
  81. // First, load a simple shader
  82. Shader fragmentShader = createShader(FRAGMENT_SHADER);
  83. shaderSource(fragmentShader, fragmentShaderSrc);
  84. compileShader(fragmentShader);
  85. Shader vertexShader = createShader(VERTEX_SHADER);
  86. shaderSource(vertexShader, vertexShaderSrc);
  87. compileShader(vertexShader);
  88. shaderProgram_ = createProgram();
  89. attachShader(shaderProgram_, vertexShader);
  90. attachShader(shaderProgram_, fragmentShader);
  91. linkProgram(shaderProgram_);
  92. useProgram(shaderProgram_);
  93. vertexPositionAttribute_ = getAttribLocation(shaderProgram_, "aVertexPosition");
  94. enableVertexAttribArray(vertexPositionAttribute_);
  95. vertexColorAttribute_ = getAttribLocation(shaderProgram_, "aVertexColor");
  96. enableVertexAttribArray(vertexColorAttribute_);
  97. pMatrixUniform_ = getUniformLocation(shaderProgram_, "uPMatrix");
  98. cMatrixUniform_ = getUniformLocation(shaderProgram_, "uCMatrix");
  99. mvMatrixUniform_ = getUniformLocation(shaderProgram_, "uMVMatrix");
  100. // Next, load a texture shader
  101. Shader texFragmentShader = createShader(FRAGMENT_SHADER);
  102. shaderSource(texFragmentShader, texFragmentShaderSrc);
  103. compileShader(texFragmentShader);
  104. Shader texVertexShader = createShader(VERTEX_SHADER);
  105. shaderSource(texVertexShader, texVertexShaderSrc);
  106. compileShader(texVertexShader);
  107. texShaderProgram_ = createProgram();
  108. attachShader(texShaderProgram_, texVertexShader);
  109. attachShader(texShaderProgram_, texFragmentShader);
  110. linkProgram(texShaderProgram_);
  111. useProgram(texShaderProgram_);
  112. texVertexPositionAttribute_ = getAttribLocation(texShaderProgram_, "aVertexPosition");
  113. enableVertexAttribArray(texVertexPositionAttribute_);
  114. texCoordAttribute_ = getAttribLocation(texShaderProgram_, "aTextureCoord");
  115. enableVertexAttribArray(texCoordAttribute_);
  116. texPMatrixUniform_ = getUniformLocation(texShaderProgram_, "uPMatrix");
  117. texCMatrixUniform_ = getUniformLocation(shaderProgram_, "uCMatrix");
  118. texMvMatrixUniform_ = getUniformLocation(texShaderProgram_, "uMVMatrix");
  119. texSamplerUniform_ = getUniformLocation(texShaderProgram_, "uSampler");
  120. // Now, preload buffers
  121. triangleVertexPositionBuffer_ = createBuffer();
  122. bindBuffer(ARRAY_BUFFER, triangleVertexPositionBuffer_);
  123. double trianglePosition[] = {
  124. 0.0, 1.0, 0.0,
  125. -1.0,-1.0, 0.0,
  126. 1.0,-1.0, 0.0
  127. };
  128. bufferDatafv(ARRAY_BUFFER, trianglePosition, 9, STATIC_DRAW);
  129. triangleVertexColorBuffer_ = createBuffer();
  130. bindBuffer(ARRAY_BUFFER, triangleVertexColorBuffer_);
  131. double triangleColor[] = {
  132. 1.0,0.0,0.0,1.0,
  133. 0.0,1.0,0.0,1.0,
  134. 0.0,0.0,1.0,1.0
  135. };
  136. bufferDatafv(ARRAY_BUFFER, triangleColor, 12, STATIC_DRAW);
  137. squareVertexPositionBuffer_ = createBuffer();
  138. bindBuffer(ARRAY_BUFFER, squareVertexPositionBuffer_);
  139. double squarePosition[] = {
  140. 1.0, 1.0,0.0,
  141. -1.0, 1.0,0.0,
  142. 1.0,-1.0,0.0,
  143. -1.0,-1.0,0.0
  144. };
  145. bufferDatafv(ARRAY_BUFFER, squarePosition, 12, STATIC_DRAW);
  146. squareVertexColorBuffer_ = createBuffer();
  147. bindBuffer(ARRAY_BUFFER, squareVertexColorBuffer_);
  148. double squareColor[] = {
  149. 1.0,0.0,0.0,1.0,
  150. 0.0,1.0,0.0,1.0,
  151. 0.0,0.0,1.0,1.0,
  152. 0.0,1.0,1.0,1.0
  153. };
  154. bufferDatafv(ARRAY_BUFFER, squareColor, 16, STATIC_DRAW);
  155. squareElementBuffer_ = createBuffer();
  156. bindBuffer(ELEMENT_ARRAY_BUFFER, squareElementBuffer_);
  157. int elements[] = {
  158. 0, 1, 2, 3
  159. };
  160. bufferDataiv(ELEMENT_ARRAY_BUFFER, elements, 4, STATIC_DRAW, DT_UNSIGNED_BYTE);
  161. texture_ = createTextureAndLoad("texture.jpg");
  162. bindTexture(TEXTURE_2D, texture_);
  163. pixelStorei(UNPACK_FLIP_Y_WEBGL, true);
  164. texImage2D(TEXTURE_2D, 0, RGB, RGB, PT_UNSIGNED_BYTE, texture_);
  165. texParameteri(TEXTURE_2D, TEXTURE_MAG_FILTER, LINEAR);
  166. texParameteri(TEXTURE_2D, TEXTURE_MIN_FILTER, LINEAR);
  167. textureCoordBuffer_ = createBuffer();
  168. bindBuffer(ARRAY_BUFFER, textureCoordBuffer_);
  169. float textureCoords[] = {
  170. 1, 1,
  171. 0, 1,
  172. 1, 0,
  173. 0, 0
  174. };
  175. bufferDatafv(ARRAY_BUFFER, textureCoords, 8, STATIC_DRAW);
  176. }
  177. void paintGL()
  178. {
  179. // Drawing starts here!
  180. //clearColor(0.8, 0.8, 0.8, 1);
  181. clearColor(0, 0, 0, 1);
  182. clearDepth(1);
  183. disable(DEPTH_TEST);
  184. disable(CULL_FACE);
  185. depthFunc(LEQUAL);
  186. viewport(0, 0, 640, 360);
  187. clear(COLOR_BUFFER_BIT | DEPTH_BUFFER_BIT);
  188. WMatrix4x4 proj;
  189. proj.perspective(90, 1, 1, 40);
  190. useProgram(shaderProgram_);
  191. // Set projection matrix
  192. uniformMatrix4(pMatrixUniform_, proj);
  193. uniformMatrix4(cMatrixUniform_, jsMatrix_);
  194. // Draw the scene
  195. #if 0
  196. bindBuffer(ARRAY_BUFFER, triangleVertexPositionBuffer_);
  197. vertexAttribPointer(vertexPositionAttribute_, 3, FLOAT, false, 0, 0);
  198. bindBuffer(ARRAY_BUFFER, triangleVertexColorBuffer_);
  199. vertexAttribPointer(vertexColorAttribute_, 4, FLOAT, false, 0, 0);
  200. WMatrix4x4 modelMatrix1(
  201. 1, 0, 0, 0,
  202. 0, 1, 0, 0,
  203. 0, 0, 1, 0,
  204. -2.0, 0, 0, 1
  205. );
  206. modelMatrix1.rotate(45, 0, 1, 0);
  207. uniformMatrix4fv(mvMatrixUniform_, false, modelMatrix1);
  208. drawArrays(TRIANGLES, 0, 3);
  209. #endif
  210. bindBuffer(ARRAY_BUFFER, squareVertexPositionBuffer_);
  211. vertexAttribPointer(vertexPositionAttribute_, 3, FLOAT, false, 0, 0);
  212. bindBuffer(ARRAY_BUFFER, squareVertexColorBuffer_);
  213. vertexAttribPointer(vertexColorAttribute_, 4, FLOAT, false, 0, 0);
  214. WMatrix4x4 modelMatrix2(
  215. 1, 0, 0, 0,
  216. 0, 1, 0, 0,
  217. 0, 0, 1, 0,
  218. 0, 0, 0, 1
  219. );
  220. //modelMatrix2.rotate(45, 1, 0, 0);
  221. //modelMatrix2.translate(0, 0, -2);
  222. uniformMatrix4(mvMatrixUniform_, modelMatrix2);
  223. //drawArrays(TRIANGLE_STRIP, 0, 4);
  224. bindBuffer(ELEMENT_ARRAY_BUFFER, squareElementBuffer_);
  225. drawElements(TRIANGLE_STRIP, 4, DT_UNSIGNED_BYTE, 0);
  226. #if 0
  227. // now draw something textured
  228. useProgram(texShaderProgram_);
  229. uniformMatrix4fv(texPMatrixUniform_, false, projectionMatrix);
  230. //WMatrix4x4 mm3(
  231. // 2, 0, 0, 0,
  232. // 0, 1, 0, -2.5,
  233. // 0, 0, 1, 0,
  234. // 0, 0, 0, 1
  235. // );
  236. WMatrix4x4 mm3;
  237. //mm3.scale(.5, 2, 1);
  238. mm3.rotate(45, 0, 0, 1);
  239. uniformMatrix4fv(texMvMatrixUniform_, false, mm3.data());
  240. bindBuffer(ARRAY_BUFFER, textureCoordBuffer_);
  241. vertexAttribPointer(texCoordAttribute_, 2, FLOAT, false, 0, 0);
  242. activeTexture(TEXTURE0);
  243. bindTexture(TEXTURE_2D, texture_);
  244. uniform1i(texSamplerUniform_, 0);
  245. bindBuffer(ARRAY_BUFFER, squareVertexPositionBuffer_);
  246. vertexAttribPointer(texVertexPositionAttribute_, 3, FLOAT, false, 0, 0);
  247. drawArrays(TRIANGLE_STRIP, 0, 4);
  248. #endif
  249. }
  250. void resizeGL(int width, int height)
  251. {
  252. }
  253. private:
  254. Program shaderProgram_;
  255. AttribLocation vertexPositionAttribute_;
  256. AttribLocation vertexColorAttribute_;
  257. UniformLocation pMatrixUniform_;
  258. UniformLocation cMatrixUniform_;
  259. UniformLocation mvMatrixUniform_;
  260. Program texShaderProgram_;
  261. AttribLocation texVertexPositionAttribute_;
  262. AttribLocation texCoordAttribute_;
  263. UniformLocation texPMatrixUniform_;
  264. UniformLocation texCMatrixUniform_;
  265. UniformLocation texMvMatrixUniform_;
  266. UniformLocation texSamplerUniform_;
  267. JavaScriptMatrix4x4 jsMatrix_;
  268. Buffer triangleVertexPositionBuffer_;
  269. Buffer triangleVertexColorBuffer_;
  270. Buffer squareVertexPositionBuffer_;
  271. Buffer squareVertexColorBuffer_;
  272. Buffer squareElementBuffer_;
  273. Buffer textureCoordBuffer_;
  274. Texture texture_;
  275. };
  276. /*
  277. * A simple WebGL demo application
  278. */
  279. class WebGLDemo : public WApplication
  280. {
  281. public:
  282. WebGLDemo(const WEnvironment& env);
  283. };
  284. WebGLDemo::WebGLDemo(const WEnvironment& env)
  285. : WApplication(env)
  286. {
  287. setTitle("WebGL Demo");
  288. root()->addWidget(new WText("This is a preliminary WebGL demo. It will "
  289. "become more spectacular in time. This technology preview has only "
  290. "been tested on Chrome Canary builds. No 3D because I did "
  291. "not yet invest in 3D projection matrices."));
  292. root()->addWidget(new WBreak());
  293. PaintWidget *gl = new PaintWidget(root());
  294. gl->resize(640, 640);
  295. }
  296. WApplication *createApplication(const WEnvironment& env)
  297. {
  298. return new WebGLDemo(env);
  299. }
  300. int main(int argc, char **argv)
  301. {
  302. WGenericMatrix<double, 3, 6> gm1;
  303. WGenericMatrix<double, 3, 6> gm2(gm1);
  304. WGenericMatrix<double, 3, 6> gm3;
  305. WGenericMatrix<double, 6, 3> gm4;
  306. double foo[] = {1, 2, 3, 4};
  307. WGenericMatrix<double, 2, 2> gm5(foo);
  308. std::cout << gm5.constData()[0] << std::endl;
  309. std::cout << gm5(0, 0) << std::endl;
  310. std::cout << gm5 << std::endl;
  311. gm5.copyDataTo(foo);
  312. WGenericMatrix<double, 2, 2> const gm6(foo);
  313. std::cout << "equality test: " << (gm5 == gm6 ? "OK" : "NOK") << std::endl;
  314. std::cout << "inequality test: " << (gm5 != gm6 ? "NOK" : "OK") << std::endl;
  315. std::cout << gm5.data()[0] << std::endl;
  316. std::cout << gm6.constData()[0] << std::endl;
  317. gm3.fill(42);
  318. std::cout << gm3 << std::endl;
  319. std::cout << gm3.transposed() << std::endl;
  320. std::cout << "isidentity non-square: " << (gm2.isIdentity() ? "OK" : "NOK") << std::endl;
  321. std::cout << "isidentity non-square: " << (!gm3.isIdentity() ? "OK" : "NOK") << std::endl;
  322. gm3.setToIdentity();
  323. std::cout << gm3 << std::endl;
  324. std::cout << "isidentity non-square: " << (gm3.isIdentity() ? "OK" : "NOK") << std::endl;
  325. #if 1
  326. std::cout << gm1 << std::endl;
  327. gm3 = gm1 + gm2;
  328. std::cout << gm3 << std::endl;
  329. gm3 = gm1 - gm2;
  330. std::cout << gm3 << std::endl;
  331. gm3 = -gm2;
  332. std::cout << gm3 << std::endl;
  333. gm3 = gm2 * 2.0;
  334. std::cout << gm3 << std::endl;
  335. gm3 = gm2 / 2.0;
  336. std::cout << gm3 << std::endl;
  337. gm3 = 2.0 * gm2;
  338. std::cout << gm3 << std::endl;
  339. std::cout << gm3 * gm4 << std::endl;
  340. WGenericMatrix<double, 3, 3> gm7= gm3 * gm4;
  341. #endif
  342. gm3 *= 2.0;
  343. std::cout << gm3 << std::endl;
  344. gm3 /= 2.0;
  345. std::cout << gm3 << std::endl;
  346. gm3 += gm1;
  347. std::cout << gm3 << std::endl;
  348. gm3 -= gm1;
  349. std::cout << gm3 << std::endl;
  350. WMatrix4x4 m1;
  351. std::cout << m1 << std::endl;
  352. std::cout << "Determinant: " << m1.determinant() << std::endl;
  353. std::cout << "Inverted: ";
  354. std::cout << m1.inverted() << std::endl;
  355. std::cout << "Identity? " << m1.isIdentity() << std::endl;
  356. WMatrix4x4 m2;
  357. m2.rotate(0, 0, 0, 1);
  358. std::cout << m2 << std::endl;
  359. m2.rotate(0, 0, 0, 2);
  360. std::cout << m2 << std::endl;
  361. m2.rotate(0, 0, 2, 0);
  362. std::cout << m2 << std::endl;
  363. m2.rotate(0, 2, 0, 0);
  364. std::cout << m2 << std::endl;
  365. m2.rotate(0, 1, 1, 1);
  366. std::cout << m2 << std::endl;
  367. m2.rotate(90, 1, 0, 0);
  368. std::cout << m2 << std::endl;
  369. m2.rotate(-90, 1, 0, 0);
  370. std::cout << m2 << std::endl;
  371. m2.rotate(45, 1, 0, 0);
  372. std::cout << m2 << std::endl;
  373. m2.rotate(-45, 1, 0, 0);
  374. std::cout << m2 << std::endl;
  375. WMatrix4x4 m3;
  376. m3 = m1 * m2;
  377. WMatrix4x4 m4(m1*m2);
  378. m3.setToIdentity();
  379. m3.lookAt(0, 0, 0, 0, 0, -1, 0, 1, 0);
  380. std::cout << m3 << std::endl;
  381. m3.setToIdentity();
  382. m3.lookAt(0, 0, 0, 0, 0, -2, 0, 8, 0);
  383. std::cout << m3 << std::endl;
  384. m3.setToIdentity();
  385. m3.lookAt(0, 0, -1, 0, 0, -2, 0, 1, 0);
  386. std::cout << m3 << std::endl;
  387. m3.setToIdentity();
  388. m3.lookAt(0, 0, 0, 0, 0, 0, 0, 1, 0);
  389. std::cout << m3 << std::endl;
  390. m3.setToIdentity();
  391. m3.lookAt(0, 0, 0,1, 1, 1, 0, 1, 0);
  392. std::cout << m3 << std::endl;
  393. return WRun(argc, argv, &createApplication);
  394. }