2 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <dali-physics/internal/bullet-impl/bullet-physics-debug-renderer.h>
21 #include <dali/dali.h>
24 #include <dali-physics/internal/physics-adaptor-impl.h>
28 using Dali::Quaternion;
35 GLuint LoadShader(GLenum shaderType, const char* shaderSource)
37 GLuint shader = glCreateShader(shaderType);
40 glShaderSource(shader, 1, &shaderSource, NULL);
41 glCompileShader(shader);
43 glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
44 if(compiled != GL_TRUE)
47 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
51 std::vector<char> logBuffer;
52 logBuffer.resize(infoLen + 1);
53 glGetShaderInfoLog(shader, infoLen, NULL, &logBuffer[0]);
54 fprintf(stderr, "%s\n", &logBuffer[0]);
57 glDeleteShader(shader);
65 GLuint CreateProgram(const char* vertexSource, const char* fragmentSource)
67 GLuint vertexShader = LoadShader(GL_VERTEX_SHADER, vertexSource);
72 GLuint fragmentShader = LoadShader(GL_FRAGMENT_SHADER, fragmentSource);
77 GLuint program = glCreateProgram();
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)
88 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
91 std::vector<char> logBuffer;
92 logBuffer.resize(bufLength + 1);
93 glGetProgramInfoLog(program, bufLength, NULL, &logBuffer[0]);
94 fprintf(stderr, "%s\n", &logBuffer[0]);
97 glDeleteProgram(program);
105 namespace Dali::Toolkit::Physics::Internal
107 std::unique_ptr<PhysicsDebugRenderer> PhysicsDebugRenderer::New(uint32_t width, uint32_t height, Dali::CameraActor camera, PhysicsAdaptor* adaptor)
109 auto renderer = std::make_unique<PhysicsDebugRenderer>(width, height, camera, adaptor);
110 renderer->mRenderCallback = Dali::RenderCallback::New<PhysicsDebugRenderer>(renderer.get(), &PhysicsDebugRenderer::OnRender);
114 PhysicsDebugRenderer::PhysicsDebugRenderer(uint32_t width, uint32_t height, Dali::CameraActor camera, PhysicsAdaptor* adaptor)
120 mVertexColourLocation(-1),
121 mProjectionLocation(-1),
122 mModelViewLocation(-1),
128 bool PhysicsDebugRenderer::OnRender(const Dali::RenderCallbackInput& input)
130 if(mState == State::INIT)
133 mState = State::RENDER;
135 glViewport(0, 0, mWidth, mHeight);
142 // Run on first invocation of callback
143 void PhysicsDebugRenderer::Setup()
146 mVertexLocation = glGetAttribLocation(mProgramId, "vertexPosition");
147 mVertexColourLocation = glGetAttribLocation(mProgramId, "vertexColour");
148 mProjectionLocation = glGetUniformLocation(mProgramId, "projection");
149 mModelViewLocation = glGetUniformLocation(mProgramId, "modelView");
151 glEnable(GL_DEPTH_TEST);
152 glViewport(0, 0, mWidth, mHeight);
154 glGenBuffers(1, &mBufferId);
157 void PhysicsDebugRenderer::UpdateWindowSize(Dali::Vector2 size)
160 mHeight = size.height;
163 void PhysicsDebugRenderer::PrepareShader()
165 static const char glVertexShader[] =
166 "attribute vec4 vertexPosition;\n"
167 "attribute vec3 vertexColour;\n"
168 "varying vec3 fragColour;\n"
169 "uniform mat4 projection;\n"
170 "uniform mat4 modelView;\n"
173 " gl_Position = projection * modelView * vertexPosition;\n"
174 " fragColour = vertexColour;\n"
177 static const char glFragmentShader[] =
178 "precision mediump float;\n"
179 "varying vec3 fragColour;\n"
182 " gl_FragColor = vec4(fragColour, 1.0);\n"
185 mProgramId = CreateProgram(glVertexShader, glFragmentShader);
188 void PhysicsDebugRenderer::RenderLines(const Dali::RenderCallbackInput& input)
190 mModelViewMatrix.SetIdentity();
191 mProjectionMatrix = input.projection;
193 Matrix::Multiply(mModelViewMatrix, mModelViewMatrix, input.view);
194 glUseProgram(mProgramId);
196 // In theory, input.clippingBox should tell us the actor position in clip-space.
197 // But, it appears to be bugged.
199 glBindBuffer(GL_ARRAY_BUFFER, mBufferId);
200 glBufferData(GL_ARRAY_BUFFER, GLsizeiptr(mLines.size() * sizeof(VertexLine)), &mLines[0], GL_STATIC_DRAW);
202 glVertexAttribPointer(mVertexLocation, 3, GL_FLOAT, GL_FALSE, 24, 0);
203 glEnableVertexAttribArray(mVertexLocation);
204 glVertexAttribPointer(mVertexColourLocation, 3, GL_FLOAT, GL_FALSE, 24, reinterpret_cast<const void*>(12));
205 glEnableVertexAttribArray(mVertexColourLocation);
206 glUniformMatrix4fv(mProjectionLocation, 1, GL_FALSE, mProjectionMatrix.AsFloat());
207 glUniformMatrix4fv(mModelViewLocation, 1, GL_FALSE, mModelViewMatrix.AsFloat());
209 glDrawArrays(GL_LINES, 0, mLines.size());
213 void PhysicsDebugRenderer::drawLine(const btVector3& from, const btVector3& to, const btVector3& color)
215 mLines.push_back(VertexLine{mAdaptor.TranslateFromPhysicsSpace(Vector3(from.x(), from.y(), from.z())),
216 Vector3(color.x(), color.y(), color.z())});
217 mLines.push_back(VertexLine{mAdaptor.TranslateFromPhysicsSpace(Vector3(to.x(), to.y(), to.z())), Vector3(color.x(), color.y(), color.z())});
220 void PhysicsDebugRenderer::drawLine(const btVector3& from, const btVector3& to, const btVector3& fromColor, const btVector3& toColor)
222 mLines.push_back(VertexLine{mAdaptor.TranslateFromPhysicsSpace(Vector3(from.x(), from.y(), from.z())), Vector3(fromColor.x(), fromColor.y(), fromColor.z())});
223 mLines.push_back(VertexLine{mAdaptor.TranslateFromPhysicsSpace(Vector3(to.x(), to.y(), to.z())), Vector3(toColor.x(), toColor.y(), toColor.z())});
226 void PhysicsDebugRenderer::drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color)
230 void PhysicsDebugRenderer::reportErrorWarning(const char* warningString)
234 void PhysicsDebugRenderer::draw3dText(const btVector3& location, const char* textString)
238 void PhysicsDebugRenderer::setDebugMode(int debugMode)
242 int PhysicsDebugRenderer::getDebugMode() const
247 } // namespace Dali::Toolkit::Physics::Internal