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)
122 bool PhysicsDebugRenderer::OnRender(const Dali::RenderCallbackInput& input)
124 if(mState == State::INIT)
127 mState = State::RENDER;
129 glViewport(0, 0, mWidth, mHeight);
136 // Run on first invocation of callback
137 void PhysicsDebugRenderer::Setup()
140 mVertexLocation = glGetAttribLocation(mProgramId, "vertexPosition");
141 mVertexColourLocation = glGetAttribLocation(mProgramId, "vertexColour");
142 mProjectionLocation = glGetUniformLocation(mProgramId, "projection");
143 mModelViewLocation = glGetUniformLocation(mProgramId, "modelView");
145 glEnable(GL_DEPTH_TEST);
146 glViewport(0, 0, mWidth, mHeight);
148 glGenBuffers(1, &mBufferId);
151 void PhysicsDebugRenderer::UpdateWindowSize(Dali::Vector2 size)
154 mHeight = size.height;
157 void PhysicsDebugRenderer::PrepareShader()
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"
167 " gl_Position = projection * modelView * vertexPosition;\n"
168 " fragColour = vertexColour;\n"
171 static const char glFragmentShader[] =
172 "precision mediump float;\n"
173 "varying vec3 fragColour;\n"
176 " gl_FragColor = vec4(fragColour, 1.0);\n"
179 mProgramId = CreateProgram(glVertexShader, glFragmentShader);
182 void PhysicsDebugRenderer::RenderLines(const Dali::RenderCallbackInput& input)
184 mModelViewMatrix.SetIdentity();
185 mProjectionMatrix = input.projection;
187 Matrix::Multiply(mModelViewMatrix, mModelViewMatrix, input.view);
188 glUseProgram(mProgramId);
190 // In theory, input.clippingBox should tell us the actor position in clip-space.
191 // But, it appears to be bugged.
193 glBindBuffer(GL_ARRAY_BUFFER, mBufferId);
194 glBufferData(GL_ARRAY_BUFFER, mLines.size() * sizeof(VertexLine), &mLines[0], GL_STATIC_DRAW);
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());
203 glDrawArrays(GL_LINES, 0, mLines.size());
207 void PhysicsDebugRenderer::drawLine(const btVector3& from, const btVector3& to, const btVector3& color)
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())});
214 void PhysicsDebugRenderer::drawLine(const btVector3& from, const btVector3& to, const btVector3& fromColor, const btVector3& toColor)
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())});
220 void PhysicsDebugRenderer::drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color)
224 void PhysicsDebugRenderer::reportErrorWarning(const char* warningString)
228 void PhysicsDebugRenderer::draw3dText(const btVector3& location, const char* textString)
232 void PhysicsDebugRenderer::setDebugMode(int debugMode)
236 int PhysicsDebugRenderer::getDebugMode() const
241 } // namespace Dali::Toolkit::Physics::Internal