Adding chipmunk implementation for physics adaptor
[platform/core/uifw/dali-toolkit.git] / dali-physics / internal / bullet-impl / bullet-physics-debug-renderer.cpp
1 /*
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 // Class header
18 #include <dali-physics/internal/bullet-impl/bullet-physics-debug-renderer.h>
19
20 // External Includes
21 #include <dali/dali.h>
22
23 // Internal Includes
24 #include <dali-physics/internal/physics-adaptor-impl.h>
25
26 using Dali::Degree;
27 using Dali::Matrix;
28 using Dali::Quaternion;
29 using Dali::Radian;
30 using Dali::Vector3;
31 using Dali::Vector4;
32
33 namespace
34 {
35 GLuint LoadShader(GLenum shaderType, const char* shaderSource)
36 {
37   GLuint shader = glCreateShader(shaderType);
38   if(shader != 0)
39   {
40     glShaderSource(shader, 1, &shaderSource, NULL);
41     glCompileShader(shader);
42     GLint compiled = 0;
43     glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
44     if(compiled != GL_TRUE)
45     {
46       GLint infoLen = 0;
47       glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
48
49       if(infoLen > 0)
50       {
51         std::vector<char> logBuffer;
52         logBuffer.resize(infoLen + 1);
53         glGetShaderInfoLog(shader, infoLen, NULL, &logBuffer[0]);
54         fprintf(stderr, "%s\n", &logBuffer[0]);
55         fflush(stderr);
56
57         glDeleteShader(shader);
58         shader = 0;
59       }
60     }
61   }
62   return shader;
63 }
64
65 GLuint CreateProgram(const char* vertexSource, const char* fragmentSource)
66 {
67   GLuint vertexShader = LoadShader(GL_VERTEX_SHADER, vertexSource);
68   if(!vertexShader)
69   {
70     return 0;
71   }
72   GLuint fragmentShader = LoadShader(GL_FRAGMENT_SHADER, fragmentSource);
73   if(!fragmentShader)
74   {
75     return 0;
76   }
77   GLuint program = glCreateProgram();
78   if(program)
79   {
80     glAttachShader(program, vertexShader);
81     glAttachShader(program, fragmentShader);
82     glLinkProgram(program);
83     GLint linkStatus = GL_FALSE;
84     glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
85     if(linkStatus != GL_TRUE)
86     {
87       GLint bufLength = 0;
88       glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
89       if(bufLength)
90       {
91         std::vector<char> logBuffer;
92         logBuffer.resize(bufLength + 1);
93         glGetProgramInfoLog(program, bufLength, NULL, &logBuffer[0]);
94         fprintf(stderr, "%s\n", &logBuffer[0]);
95         fflush(stderr);
96       }
97       glDeleteProgram(program);
98       program = 0;
99     }
100   }
101   return program;
102 }
103 } // namespace
104
105 namespace Dali::Toolkit::Physics::Internal
106 {
107 std::unique_ptr<PhysicsDebugRenderer> PhysicsDebugRenderer::New(uint32_t width, uint32_t height, Dali::CameraActor camera, PhysicsAdaptor* adaptor)
108 {
109   auto renderer             = std::make_unique<PhysicsDebugRenderer>(width, height, camera, adaptor);
110   renderer->mRenderCallback = Dali::RenderCallback::New<PhysicsDebugRenderer>(renderer.get(), &PhysicsDebugRenderer::OnRender);
111   return renderer;
112 }
113
114 PhysicsDebugRenderer::PhysicsDebugRenderer(uint32_t width, uint32_t height, Dali::CameraActor camera, PhysicsAdaptor* adaptor)
115 : mCamera(camera),
116   mWidth(width),
117   mHeight(height),
118   mAdaptor(*adaptor)
119 {
120 }
121
122 bool PhysicsDebugRenderer::OnRender(const Dali::RenderCallbackInput& input)
123 {
124   if(mState == State::INIT)
125   {
126     Setup();
127     mState = State::RENDER;
128   }
129   glViewport(0, 0, mWidth, mHeight);
130
131   RenderLines(input);
132
133   return false;
134 }
135
136 // Run on first invocation of callback
137 void PhysicsDebugRenderer::Setup()
138 {
139   PrepareShader();
140   mVertexLocation       = glGetAttribLocation(mProgramId, "vertexPosition");
141   mVertexColourLocation = glGetAttribLocation(mProgramId, "vertexColour");
142   mProjectionLocation   = glGetUniformLocation(mProgramId, "projection");
143   mModelViewLocation    = glGetUniformLocation(mProgramId, "modelView");
144
145   glEnable(GL_DEPTH_TEST);
146   glViewport(0, 0, mWidth, mHeight);
147
148   glGenBuffers(1, &mBufferId);
149 }
150
151 void PhysicsDebugRenderer::UpdateWindowSize(Dali::Vector2 size)
152 {
153   mWidth  = size.width;
154   mHeight = size.height;
155 }
156
157 void PhysicsDebugRenderer::PrepareShader()
158 {
159   static const char glVertexShader[] =
160     "attribute vec4 vertexPosition;\n"
161     "attribute vec3 vertexColour;\n"
162     "varying vec3 fragColour;\n"
163     "uniform mat4 projection;\n"
164     "uniform mat4 modelView;\n"
165     "void main()\n"
166     "{\n"
167     "    gl_Position = projection * modelView * vertexPosition;\n"
168     "    fragColour = vertexColour;\n"
169     "}\n";
170
171   static const char glFragmentShader[] =
172     "precision mediump float;\n"
173     "varying vec3 fragColour;\n"
174     "void main()\n"
175     "{\n"
176     "    gl_FragColor = vec4(fragColour, 1.0);\n"
177     "}\n";
178
179   mProgramId = CreateProgram(glVertexShader, glFragmentShader);
180 }
181
182 void PhysicsDebugRenderer::RenderLines(const Dali::RenderCallbackInput& input)
183 {
184   mModelViewMatrix.SetIdentity();
185   mProjectionMatrix = input.projection;
186
187   Matrix::Multiply(mModelViewMatrix, mModelViewMatrix, input.view);
188   glUseProgram(mProgramId);
189
190   // In theory, input.clippingBox should tell us the actor position in clip-space.
191   // But, it appears to be bugged.
192
193   glBindBuffer(GL_ARRAY_BUFFER, mBufferId);
194   glBufferData(GL_ARRAY_BUFFER, mLines.size() * sizeof(VertexLine), &mLines[0], GL_STATIC_DRAW);
195
196   glVertexAttribPointer(mVertexLocation, 3, GL_FLOAT, GL_FALSE, 24, 0);
197   glEnableVertexAttribArray(mVertexLocation);
198   glVertexAttribPointer(mVertexColourLocation, 3, GL_FLOAT, GL_FALSE, 24, reinterpret_cast<const void*>(12));
199   glEnableVertexAttribArray(mVertexColourLocation);
200   glUniformMatrix4fv(mProjectionLocation, 1, GL_FALSE, mProjectionMatrix.AsFloat());
201   glUniformMatrix4fv(mModelViewLocation, 1, GL_FALSE, mModelViewMatrix.AsFloat());
202
203   glDrawArrays(GL_LINES, 0, mLines.size());
204   mLines.clear();
205 }
206
207 void PhysicsDebugRenderer::drawLine(const btVector3& from, const btVector3& to, const btVector3& color)
208 {
209   mLines.push_back(VertexLine{mAdaptor.TranslateFromPhysicsSpace(Vector3(from.x(), from.y(), from.z())),
210                               Vector3(color.x(), color.y(), color.z())});
211   mLines.push_back(VertexLine{mAdaptor.TranslateFromPhysicsSpace(Vector3(to.x(), to.y(), to.z())), Vector3(color.x(), color.y(), color.z())});
212 }
213
214 void PhysicsDebugRenderer::drawLine(const btVector3& from, const btVector3& to, const btVector3& fromColor, const btVector3& toColor)
215 {
216   mLines.push_back(VertexLine{mAdaptor.TranslateFromPhysicsSpace(Vector3(from.x(), from.y(), from.z())), Vector3(fromColor.x(), fromColor.y(), fromColor.z())});
217   mLines.push_back(VertexLine{mAdaptor.TranslateFromPhysicsSpace(Vector3(to.x(), to.y(), to.z())), Vector3(toColor.x(), toColor.y(), toColor.z())});
218 }
219
220 void PhysicsDebugRenderer::drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color)
221 {
222 }
223
224 void PhysicsDebugRenderer::reportErrorWarning(const char* warningString)
225 {
226 }
227
228 void PhysicsDebugRenderer::draw3dText(const btVector3& location, const char* textString)
229 {
230 }
231
232 void PhysicsDebugRenderer::setDebugMode(int debugMode)
233 {
234 }
235
236 int PhysicsDebugRenderer::getDebugMode() const
237 {
238   return true;
239 }
240
241 } // namespace Dali::Toolkit::Physics::Internal