teapot.C 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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/WImage>
  10. #include <Wt/WPushButton>
  11. #include <Wt/WTabWidget>
  12. #include <Wt/WText>
  13. #include <Wt/WTextArea>
  14. #include <Wt/WServer>
  15. #include <Wt/WEnvironment>
  16. #include "readObj.h"
  17. #include "PaintWidget.h"
  18. using namespace Wt;
  19. const char *fragmentShaderSrc =
  20. "#ifdef GL_ES\n"
  21. "precision highp float;\n"
  22. "#endif\n"
  23. "\n"
  24. "varying vec3 vLightWeighting;\n"
  25. "\n"
  26. "void main(void) {\n"
  27. " vec4 matColor = vec4(0.278, 0.768, 0.353, 1.0);\n"
  28. " gl_FragColor = vec4(matColor.rgb * vLightWeighting, matColor.a);\n"
  29. "}\n";
  30. const char *vertexShaderSrc =
  31. "attribute vec3 aVertexPosition;\n"
  32. "attribute vec3 aVertexNormal;\n"
  33. "\n"
  34. "uniform mat4 uMVMatrix; // [M]odel[V]iew matrix\n"
  35. "uniform mat4 uCMatrix; // Client-side manipulated [C]amera matrix\n"
  36. "uniform mat4 uPMatrix; // Perspective [P]rojection matrix\n"
  37. "uniform mat4 uNMatrix; // [N]ormal transformation\n"
  38. "// uNMatrix is the transpose of the inverse of uCMatrix * uMVMatrix\n"
  39. "\n"
  40. "varying vec3 vLightWeighting;\n"
  41. "\n"
  42. "void main(void) {\n"
  43. " // Calculate the position of this vertex\n"
  44. " gl_Position = uPMatrix * uCMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\n"
  45. "\n"
  46. " // Phong shading\n"
  47. " vec3 transformedNormal = normalize((uNMatrix * vec4(normalize(aVertexNormal), 0)).xyz);\n"
  48. " vec3 lightingDirection = normalize(vec3(1, 1, 1));\n"
  49. " float directionalLightWeighting = max(dot(transformedNormal, lightingDirection), 0.0);\n"
  50. " vec3 uAmbientLightColor = vec3(0.2, 0.2, 0.2);\n"
  51. " vec3 uDirectionalColor = vec3(0.8, 0.8, 0.8);\n"
  52. " vLightWeighting = uAmbientLightColor + uDirectionalColor * directionalLightWeighting;\n"
  53. "}\n";
  54. /*
  55. * A pretty basic WebGL demo application
  56. */
  57. std::vector<float> data;
  58. class WebGLDemo : public WApplication
  59. {
  60. public:
  61. WebGLDemo(const WEnvironment& env);
  62. private:
  63. void updateShaders();
  64. void resetShaders();
  65. WContainerWidget *glContainer_;
  66. PaintWidget *paintWidget_;
  67. WTextArea *fragmentShaderText_;
  68. WTextArea *vertexShaderText_;
  69. };
  70. WebGLDemo::WebGLDemo(const WEnvironment& env)
  71. : WApplication(env)
  72. {
  73. setTitle("WebGL Demo");
  74. root()->addWidget(new WText("If your browser supports WebGL, you'll "
  75. "see a teapot below.<br/>Use your mouse to move around the teapot.<br/>"
  76. "Edit the shaders below the teapot to change how the teapot is rendered."));
  77. root()->addWidget(new WBreak());
  78. paintWidget_ = 0;
  79. glContainer_ = new WContainerWidget(root());
  80. glContainer_->resize(500, 500);
  81. glContainer_->setInline(false);
  82. WPushButton *updateButton = new WPushButton("Update shaders", root());
  83. updateButton->clicked().connect(this, &WebGLDemo::updateShaders);
  84. WPushButton *resetButton = new WPushButton("Reset shaders", root());
  85. resetButton->clicked().connect(this, &WebGLDemo::resetShaders);
  86. WTabWidget *tabs = new WTabWidget(root());
  87. fragmentShaderText_ = new WTextArea;
  88. fragmentShaderText_->resize(750, 250);
  89. tabs->addTab(fragmentShaderText_, "Fragment Shader");
  90. vertexShaderText_ = new WTextArea;
  91. vertexShaderText_->resize(750, 250);
  92. tabs->addTab(vertexShaderText_, "Vertex Shader");
  93. resetShaders();
  94. }
  95. void WebGLDemo::updateShaders()
  96. {
  97. // check if binary buffers are enabled
  98. // i.e. if your application url is "webgl" on localhost:8080, use this to enable binary buffers:
  99. // localhost:8080/webgl?binaryBuffers
  100. // query given URL arguments...
  101. Http::ParameterValues pv = wApp->environment().getParameterValues("binaryBuffers");
  102. bool useBinaryBuffers = false;
  103. if (!pv.empty())
  104. {
  105. useBinaryBuffers = true;
  106. }
  107. delete paintWidget_;
  108. paintWidget_ = new PaintWidget(glContainer_, useBinaryBuffers);
  109. paintWidget_->resize(500, 500);
  110. paintWidget_->setShaders(vertexShaderText_->text().toUTF8(),
  111. fragmentShaderText_->text().toUTF8());
  112. paintWidget_->setAlternativeContent(new WImage("nowebgl.png"));
  113. }
  114. void WebGLDemo::resetShaders()
  115. {
  116. fragmentShaderText_->setText(fragmentShaderSrc);
  117. vertexShaderText_->setText(vertexShaderSrc);
  118. updateShaders();
  119. }
  120. WApplication *createApplication(const WEnvironment& env)
  121. {
  122. return new WebGLDemo(env);
  123. }
  124. int main(int argc, char **argv)
  125. {
  126. try {
  127. WServer server(argc, argv, WTHTTP_CONFIGURATION);
  128. readObj(WApplication::appRoot() + "teapot.obj", data);
  129. server.addEntryPoint(Wt::Application, createApplication);
  130. server.run();
  131. } catch (WServer::Exception& e) {
  132. std::cerr << e.what() << "\n";
  133. return 1;
  134. } catch (std::exception& e) {
  135. std::cerr << "exception: " << e.what() << "\n";
  136. return 1;
  137. }
  138. }