glm-math http://www.e-learn.cn/tag/glm-math zh-hans Glm Quaternion lookat function http://www.e-learn.cn/topic/4111371 <span>Glm Quaternion lookat function</span> <span><span lang="" about="/user/198" typeof="schema:Person" property="schema:name" datatype="">别来无恙</span></span> <span>2021-02-18 03:38:05</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>I am trying to write a lookat function that uses glm::quat to represent rotations, based of off this answer. I am running into trouble getting a correct angle however. This is my lookat function:</p> <pre><code>void Camera::LookAt(float x, float y, float z) { glm::vec3 lookVector = glm::vec3(x, y, z); assert(lookVector != position); glm::vec3 direction = glm::normalize(lookVector-position); float dot = glm::dot(glm::vec3(0, 0, -1), direction); if (fabs(dot - (-1.0f)) &lt; 0.000001f) rotation = glm::quat(RadiansToDegrees(M_PI), 0.0f, 1.0f, 0.0f); if (fabs(dot - (1.0f)) &lt; 0.000001f) rotation = glm::quat(); float angle = RadiansToDegrees(acosf(dot)); glm::vec3 cross = (glm::cross(glm::vec3(0, 0, -1), direction)); rotation = glm::normalize(glm::angleAxis(angle, cross)); std::cout &lt;&lt; glm::eulerAngles(rotation).x &lt;&lt; " " &lt;&lt; glm::eulerAngles(rotation).y &lt;&lt; " " &lt;&lt; glm::eulerAngles(rotation).z &lt;&lt; "\n"; } </code></pre> <p>When I call LookAt(0.0f, 0.0f, 0.0f) when my camera is at (0.0f, 0.0f, -10.0f), this outputs a correct rotation of 0,0,0. However if I translate my camera to (0.0f, -0.01f, -10.0f) or more I get a rotation of about 124,0,0. This goes down if I continue to translate y by -0.01f. If I do not normalize the quaternion I do not get this problem. The rotation is still 124 about the x axis, but the appearance is fine. If however I normalize the quaternion later it once again appears to rotate to about 124. I can not normalize <code>cross</code>, because doing so throws an assert. What would cause me to get euler angles of 124 about x from my lookat function, and how can I fix it?</p> <br /><h3>回答1:</h3><br /><p>Since version 0.9.9.0 there is a function in <code>&lt;glm/gtx/quaternion.hpp&gt;</code> doing mostly what you want:</p> <pre><code>template&lt;typename T, qualifier Q&gt; tquat&lt;T, Q&gt; quatLookAt(vec&lt;3, T, Q&gt; const&amp; direction, vec&lt;3, T, Q&gt; const&amp; up); </code></pre> <p>It was added by this pull request and has been merged into master July 24, 2017.</p> <p><strong>But</strong>:</p> <ol><li>direction has to be a normalized vector!</li> <li>direction can't be parallel to up!</li> </ol><p>So you may want to write a safer wrapper around the function:</p> <pre><code>glm::quat safeQuatLookAt( glm::vec3 const&amp; lookFrom, glm::vec3 const&amp; lookTo, glm::vec3 const&amp; up, glm::vec3 const&amp; alternativeUp) { glm::vec3 direction = lookTo - lookFrom; float directionLength = glm::length(direction); // Check if the direction is valid; Also deals with NaN if(!(directionLength &gt; 0.0001)) return glm::quat(1, 0, 0, 0); // Just return identity // Normalize direction direction /= directionLength; // Is the normal up (nearly) parallel to direction? if(glm::abs(glm::dot(direction, up)) &gt; .9999f) { // Use alternative up return glm::quatLookAt(direction, alternativeUp); } else { return glm::quatLookAt(direction, up); } } </code></pre> <br /><br /><br /><h3>回答2:</h3><br /><p>I have fixed the problem with the following code:</p> <pre><code>void Camera::LookAt(float x, float y, float z) { glm::vec3 lookVector = glm::vec3(x, y, z); assert(lookVector != position); glm::vec3 direction = glm::normalize(lookVector-position); float dot = glm::dot(glm::vec3(0, 0, 1), direction); if (fabs(dot - (-1.0f)) &lt; 0.000001f) { rotation = glm::angleAxis(RadiansToDegrees(M_PI), glm::vec3(0, 1, 0)); return; } else if (fabs(dot - (1.0f)) &lt; 0.000001f) { rotation = glm::quat(); return; } float angle = -RadiansToDegrees(acosf(dot)); glm::vec3 cross = glm::normalize(glm::cross(glm::vec3(0, 0, 1), direction)); rotation = glm::normalize(glm::angleAxis(angle, cross)); } </code></pre> <p>I do not however understand the necessity of the negative on <code>angle</code>. It fixed the last of my problems, and an explanation of the math of why would be helpful.</p> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/18172388/glm-quaternion-lookat-function</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/c-0" hreflang="zh-hans">c++</a></div> <div class="field--item"><a href="/tag/opengl" hreflang="zh-hans">opengl</a></div> <div class="field--item"><a href="/tag/quaternions" hreflang="zh-hans">quaternions</a></div> <div class="field--item"><a href="/tag/glm-math" hreflang="zh-hans">glm-math</a></div> </div> </div> Wed, 17 Feb 2021 19:38:05 +0000 别来无恙 4111371 at http://www.e-learn.cn light shows but the cube does not appear http://www.e-learn.cn/topic/4108432 <span>light shows but the cube does not appear</span> <span><span lang="" about="/user/72" typeof="schema:Person" property="schema:name" datatype="">本小妞迷上赌</span></span> <span>2021-02-17 03:16:45</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>I am trying to use lighting on a cube but I don't understand where am going wrong. I can be able to view the light source but the rest of the screen appears black so I don't understand why the cube is disappearing.</p> <p>Here is the code:</p> <pre><code>/*Header Inclusions*/ #include &lt;iostream&gt; #include &lt;GL/Glew.h&gt; #include &lt;GL/freeglut.h&gt; // GLM Math inclusions #include &lt;glm/glm.hpp&gt; #include &lt;glm/gtc/matrix_transform.hpp&gt; #include&lt;glm/gtc/type_ptr.hpp&gt; using namespace std; // Uses the standard namespace #define WINDOW_TITLE "Modern OpenGL" // Macro for window title //Vertex and fragment shader #ifndef GLSL #define GLSL(Version, source) "#version " #Version "\n" #source #endif // Variable declarations for shaders, and window size initialization, buffer and vertex array object GLint cubeShaderProgram, lampShaderProgram, WindowWidth = 800, WindowHeight = 600; GLuint VBO, CubeVAO, LightVAO; // subject position and scale glm::vec3 cubePosition(0.0f, 0.0f, 0.0f); glm::vec3 cubeScale(2.0f); //cube and light color glm::vec3 objectColor(0.6f, 0.5f, 0.75f); glm::vec3 lightColor(1.0f, 1.0f, 1.0f); //light position and scale glm::vec3 lightPosition(0.5f, 0.5f, -3.0f); glm::vec3 lightScale(0.3f); //camera position glm::vec3 cameraPosition(0.0f, 0.0f, -6.0f); //camera rotation float cameraRotation = glm::radians(-25.0f); /* User-defined Function prototypes to:*/ void UResizeWindow(int,int); void URenderGraphics(void); void UCreateShader(void); void UCreateBuffers(void); /*Cube Vertex shader source code*/ const GLchar * cubeVertexShaderSource = GLSL(330, layout (location = 0) in vec3 position; layout (location = 1) in vec3 normal; out vec3 Normal; //declare a vec 3 variable out vec3 FragmentPos; //Global variables for the transform matrices uniform mat4 model; uniform mat4 view; uniform mat4 projection; void main(){ gl_Position = projection * view * model * vec4(position, 1.0f);//transform vertices FragmentPos = vec3(model * vec4(position, 1.0f)); Normal = mat3(transpose(inverse(model))) * normal; } ); /*Cube Fragment shader program source code*/ const GLchar * cubeFragmentShaderSource = GLSL(330, in vec3 Normal; in vec3 FragmentPos; out vec4 cubeColor; //uniform variables uniform vec3 objectColor; uniform vec3 lightColor; uniform vec3 lightPos; uniform vec3 viewPosition; void main(){ //phong lighting model calculations to generate ambient, diffuse, and specular components //calculate ambient lighting float ambientStrength = 0.1f; vec3 ambient = ambientStrength * lightColor; //calculater diffuse lighting vec3 norm = normalize(Normal); vec3 lightDirection = normalize(lightPos - FragmentPos); float impact = max(dot(norm, lightDirection), 0.0); vec3 diffuse = impact * lightColor; //calculate specular lighting float specularIntensity = 1.8f; float highlightSize = 16.0f; vec3 viewDir = normalize(viewPosition - FragmentPos); vec3 reflectDir = reflect(-lightDirection, norm); //calculate specular component float specularComponent = pow(max(dot(viewDir, reflectDir), 0.0), highlightSize); vec3 specular = specularIntensity * specularComponent * lightColor; //calculate phong result vec3 phong = (ambient + diffue + specular) * objectColor; cubeColor = vec4(phong, 1.0f); } ); /* lamp shader source code*/ const GLchar * lampVertexShaderSource = GLSL(330, layout (location = 0) in vec3 position; //Global variables for the transform matrices uniform mat4 model; uniform mat4 view; uniform mat4 projection; void main() { gl_Position = projection * view * model * vec4(position, 1.0f);//transform vertices } ); /*Fragment Shader Source Code*/ const GLchar * lampFragmentShaderSource = GLSL(330, out vec4 color; void main() { color = vec4(1.0f); } ); //main program int main(int argc, char* argv[]) { glutInit(&amp;argc, argv); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); glutInitWindowSize(WindowWidth, WindowHeight); glutCreateWindow(WINDOW_TITLE); glutReshapeFunc(UResizeWindow); glewExperimental = GL_TRUE; if (glewInit()!= GLEW_OK) { std::cout &lt;&lt; "Failed to initialize GLEW" &lt;&lt; std::endl; return -1; } UCreateShader(); UCreateBuffers(); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color glutDisplayFunc(URenderGraphics); glutMainLoop(); // Destroys Buffer objects once used glDeleteVertexArrays(1, &amp;CubeVAO); glDeleteVertexArrays(1, &amp;LightVAO); glDeleteBuffers(1, &amp;VBO); return 0; } /* Resizes the window*/ void UResizeWindow(int w, int h) { WindowWidth = w; WindowHeight = h; glViewport(0, 0, WindowWidth, WindowHeight); } /* Renders graphics */ void URenderGraphics(void) { glEnable(GL_DEPTH_TEST); // Enable z-depth glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clears the screen GLint modelLoc, viewLoc, projLoc, objectColorLoc, lightColorLoc, lightPositionLoc, viewPositionLoc; glm::mat4 model; glm::mat4 view; glm::mat4 projection; //use cube shader and activate cube VAO glUseProgram(cubeShaderProgram); glBindVertexArray(CubeVAO); //transform the cube model = glm::translate(model, cameraPosition); model = glm::scale(model, cubeScale); // Transforms the camera view = glm::translate(view, cameraPosition); view = glm::rotate(view, cameraRotation, glm::vec3(0.0f, 1.0f, 0.0f)); //set the camera projection to perspective projection = glm::perspective(45.0f, (GLfloat)WindowWidth / (GLfloat)WindowHeight, 0.1f, 100.0f); // reference matrix uniforms from the cube shader program modelLoc = glGetUniformLocation(cubeShaderProgram, "model"); viewLoc = glGetUniformLocation(cubeShaderProgram, "view"); projLoc = glGetUniformLocation(cubeShaderProgram, "projection"); //pass matrix data to the cube shader program's matrix uniforms glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection)); // reference matrix uniforms from the cube shader program for the cube color, light color, light position, and camera position objectColorLoc = glGetUniformLocation(cubeShaderProgram, "objectColor"); lightColorLoc = glGetUniformLocation(cubeShaderProgram, "lightColor"); lightPositionLoc = glGetUniformLocation(cubeShaderProgram, "lightPos"); viewPositionLoc = glGetUniformLocation(cubeShaderProgram, "viewPosition"); //pass color, light, and camera data to the cube shader program's corresponding uniforms glUniform3f(objectColorLoc, objectColor.r, objectColor.g, objectColor.b); glUniform3f(lightColorLoc, lightColor.r, lightColor.g, lightColor.b); glUniform3f(lightPositionLoc, lightPosition.x, lightPosition.y, lightPosition.z); glUniform3f(viewPositionLoc, cameraPosition.x, cameraPosition.y, cameraPosition.z); glDrawArrays(GL_TRIANGLES, 0, 36); // use the lamp shader and activate the LVAO glUseProgram(lampShaderProgram); glBindVertexArray(LightVAO); // transform the smaller cube model = glm::translate(model, lightPosition); model = glm::scale(model, lightScale); // reference matrix uniforms from the lamp shader program modelLoc = glGetUniformLocation(lampShaderProgram, "model"); viewLoc = glGetUniformLocation(lampShaderProgram, "view"); projLoc = glGetUniformLocation(lampShaderProgram, "projection"); //pass matrix data to the lamp shader program's matrix uniforms glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection)); glDrawArrays(GL_TRIANGLES,0, 36); glBindVertexArray(0); // Deactivate the Vertex Array Object glutPostRedisplay(); glutSwapBuffers(); } /*Creates the Shader program*/ void UCreateShader() { // cube Vertex shader GLint cubeVertexShader = glCreateShader(GL_VERTEX_SHADER); // Creates the Vertex Shader glShaderSource(cubeVertexShader, 1, &amp;cubeVertexShaderSource, NULL); // Attaches the Vertex Shader to the source code glCompileShader(cubeVertexShader); // Compiles the Vertex Shader // cube Fragment Shader GLint cubeFragmentShader = glCreateShader(GL_FRAGMENT_SHADER); // Creates the Fragment Shader glShaderSource(cubeFragmentShader, 1, &amp;cubeFragmentShaderSource, NULL);// Attaches the Fragment Shader to the source code glCompileShader(cubeFragmentShader); // Compiles the Fragment Shader // Cube Shader program cubeShaderProgram = glCreateProgram(); // Creates the Shader program and returns an id glAttachShader(cubeShaderProgram, cubeVertexShader); // Attach Vertex Shader to the Shader program glAttachShader(cubeShaderProgram, cubeFragmentShader);; // Attach Fragment Shader to the Shader program glLinkProgram(cubeShaderProgram); //Link Vertex and Fragment shader, to Shader program // Delete the cube Vertex and Fragment shaders once linked glDeleteShader(cubeVertexShader); glDeleteShader(cubeFragmentShader); // Lamp Vertex Shader GLint lampVertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(lampVertexShader, 1, &amp;lampVertexShaderSource, NULL); glCompileShader(lampVertexShader); // Lamp Fragment Shader GLint lampFragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(lampFragmentShader, 1, &amp;lampFragmentShaderSource, NULL); glCompileShader(lampFragmentShader); // Cube Shader program lampShaderProgram = glCreateProgram(); // Creates the Shader program and returns an id glAttachShader(lampShaderProgram, lampVertexShader); // Attach Vertex Shader to the Shader program glAttachShader(lampShaderProgram, lampFragmentShader);; // Attach Fragment Shader to the Shader program glLinkProgram(lampShaderProgram); //Link Vertex and Fragment shader, to Shader program // Delete the lamp Vertex and Fragment shaders once linked glDeleteShader(lampVertexShader); glDeleteShader(lampFragmentShader); } /*creates the buffer and array object*/ void UCreateBuffers() { </code></pre> <p>I have tried testing the vertices on their own and i can see the cube. I dont understand why its disapering after adding the lighting. </p> <pre><code> //position and color data GLfloat vertices[] = { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.5f, -0.5f, -0.5f, 0.0f,0.0f, -1.0f, 0.5f, 0.5f, -0.5f, 0.0f,0.0f, -1.0f, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f,-1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 0.0f,-1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f,-1.0f, -0.5f, -0.5f, 0.5f, 0.0f,0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 0.0f,0.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.0f,0.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.0f,0.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f,0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f,0.0f, 1.0f, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f,0.0f, -0.5f, 0.5f, -0.5f, -1.0f, 0.0f,0.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f,0.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f,0.0f, -0.5f, -0.5f, 0.5f, -1.0f, 0.0f,0.0f, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f,0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f,0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 0.0f,0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f,0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f,0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f,0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f,0.0f, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f,0.0f, 0.5f, -0.5f, -0.5f, 0.0f, -1.0f,0.0f, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f,0.0f, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f,0.0f, -0.5f, -0.5f, 0.5f, 0.0f, -1.0f,0.0f, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f,0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f,0.0f, 0.5f, 0.5f, -0.5f, 0.0f, 1.0f,0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f,0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f,0.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f,0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f,0.0f }; //Generate buffer id, glGenVertexArrays(1, &amp;CubeVAO); glGenBuffers(1,&amp;VBO); // Activate the Vertex Array Object before binding and setting any VB0s and Vertex Attribute Pointers. glBindVertexArray(CubeVAO); // Activate the VBO glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); //Copy vertices to VBO // Set attribute pointer 0 to hold Position data glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); // Enables vertex attribute // Set attribute pointer 1 to hold normal data glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(1); // Enables vertex attribute glBindVertexArray(0); // Deactivates the VAC, which is good practice /*Generate buffer ids for lamp (smaller cube)*/ glGenVertexArrays(1, &amp;LightVAO); // activate the VAO glBindVertexArray(LightVAO); // referencing the same VBO glBindBuffer(GL_ARRAY_BUFFER, VBO); // set attribute pointer 0 to hold position data for the lamp glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); glBindVertexArray(0); } </code></pre> <br /><h3>回答1:</h3><br /><p>The "cube" fragment shader fails to compile. The variable <code>diffus</code> does not exist, it has to be <code>diffuse</code>:</p> <p><s><code>vec3 phong = (ambient + diffus + specular) * objectColor;</code></s> </p> <pre class="lang-c prettyprint-override"><code>vec3 phong = (ambient + diffuse + specular) * objectColor; </code></pre> <hr /><p>I recommend to verify if compiling the shader succeeded by glGetShaderiv(..., GL_COMPILE_STATUS, ...) and linking succeeded by glGetProgramiv(..., GL_LINK_STATUS, ...).</p> <p>Implement functions which validate a shader and a program and log the error messages:</p> <pre class="lang-cpp prettyprint-override"><code>#include &lt;iostream&gt; #include &lt;vector&gt; void CompileStatus( GLuint shader ) { GLint status = GL_TRUE; glGetShaderiv( shader, GL_COMPILE_STATUS, &amp;status ); if (status == GL_FALSE) { GLint logLen; glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &amp;logLen ); std::vector&lt; char &gt;log( logLen ); GLsizei written; glGetShaderInfoLog( shader, logLen, &amp;written, log.data() ); std::cout &lt;&lt; "compile error:" &lt;&lt; std::endl &lt;&lt; log.data() &lt;&lt; std::endl; } } void LinkStatus( GLuint program ) { GLint status = GL_TRUE; glGetProgramiv( program, GL_LINK_STATUS, &amp;status ); if (status == GL_FALSE) { GLint logLen; glGetProgramiv( program, GL_INFO_LOG_LENGTH, &amp;logLen ); std::vector&lt; char &gt;log( logLen ); GLsizei written; glGetProgramInfoLog( program, logLen, &amp;written, log.data() ); std::cout &lt;&lt; "link error:" &lt;&lt; std::endl &lt;&lt; log.data() &lt;&lt; std::endl; } } </code></pre> <p>Validate the shaders after <code>glCompileShader</code> and the program after <code>glLinkProgram</code>:</p> <pre class="lang-cpp prettyprint-override"><code>void UCreateShader() { // cube Vertex shader GLint cubeVertexShader = glCreateShader(GL_VERTEX_SHADER); // Creates the Vertex Shader glShaderSource(cubeVertexShader, 1, &amp;cubeVertexShaderSource, NULL); // Attaches the Vertex Shader to the source code glCompileShader(cubeVertexShader); // Compiles the Vertex Shader CompileStatus( cubeVertexShader ); // cube Fragment Shader GLint cubeFragmentShader = glCreateShader(GL_FRAGMENT_SHADER); // Creates the Fragment Shader glShaderSource(cubeFragmentShader, 1, &amp;cubeFragmentShaderSource, NULL);// Attaches the Fragment Shader to the source code glCompileShader(cubeFragmentShader); // Compiles the Fragment Shader CompileStatus( cubeFragmentShader ); // Cube Shader program cubeShaderProgram = glCreateProgram(); // Creates the Shader program and returns an id glAttachShader(cubeShaderProgram, cubeVertexShader); // Attach Vertex Shader to the Shader program glAttachShader(cubeShaderProgram, cubeFragmentShader);; // Attach Fragment Shader to the Shader program glLinkProgram(cubeShaderProgram); //Link Vertex and Fragment shader, to Shader program LinkStatus( cubeShaderProgram ); // [...] } </code></pre> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/59235204/light-shows-but-the-cube-does-not-appear</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/c-0" hreflang="zh-hans">c++</a></div> <div class="field--item"><a href="/tag/opengl" hreflang="zh-hans">opengl</a></div> <div class="field--item"><a href="/tag/glut" hreflang="zh-hans">glut</a></div> <div class="field--item"><a href="/tag/glm-math" hreflang="zh-hans">glm-math</a></div> <div class="field--item"><a href="/tag/vao" hreflang="zh-hans">vao</a></div> </div> </div> Tue, 16 Feb 2021 19:16:45 +0000 本小妞迷上赌 4108432 at http://www.e-learn.cn light shows but the cube does not appear http://www.e-learn.cn/topic/4108425 <span>light shows but the cube does not appear</span> <span><span lang="" about="/user/189" typeof="schema:Person" property="schema:name" datatype="">怎甘沉沦</span></span> <span>2021-02-17 03:16:19</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>I am trying to use lighting on a cube but I don't understand where am going wrong. I can be able to view the light source but the rest of the screen appears black so I don't understand why the cube is disappearing.</p> <p>Here is the code:</p> <pre><code>/*Header Inclusions*/ #include &lt;iostream&gt; #include &lt;GL/Glew.h&gt; #include &lt;GL/freeglut.h&gt; // GLM Math inclusions #include &lt;glm/glm.hpp&gt; #include &lt;glm/gtc/matrix_transform.hpp&gt; #include&lt;glm/gtc/type_ptr.hpp&gt; using namespace std; // Uses the standard namespace #define WINDOW_TITLE "Modern OpenGL" // Macro for window title //Vertex and fragment shader #ifndef GLSL #define GLSL(Version, source) "#version " #Version "\n" #source #endif // Variable declarations for shaders, and window size initialization, buffer and vertex array object GLint cubeShaderProgram, lampShaderProgram, WindowWidth = 800, WindowHeight = 600; GLuint VBO, CubeVAO, LightVAO; // subject position and scale glm::vec3 cubePosition(0.0f, 0.0f, 0.0f); glm::vec3 cubeScale(2.0f); //cube and light color glm::vec3 objectColor(0.6f, 0.5f, 0.75f); glm::vec3 lightColor(1.0f, 1.0f, 1.0f); //light position and scale glm::vec3 lightPosition(0.5f, 0.5f, -3.0f); glm::vec3 lightScale(0.3f); //camera position glm::vec3 cameraPosition(0.0f, 0.0f, -6.0f); //camera rotation float cameraRotation = glm::radians(-25.0f); /* User-defined Function prototypes to:*/ void UResizeWindow(int,int); void URenderGraphics(void); void UCreateShader(void); void UCreateBuffers(void); /*Cube Vertex shader source code*/ const GLchar * cubeVertexShaderSource = GLSL(330, layout (location = 0) in vec3 position; layout (location = 1) in vec3 normal; out vec3 Normal; //declare a vec 3 variable out vec3 FragmentPos; //Global variables for the transform matrices uniform mat4 model; uniform mat4 view; uniform mat4 projection; void main(){ gl_Position = projection * view * model * vec4(position, 1.0f);//transform vertices FragmentPos = vec3(model * vec4(position, 1.0f)); Normal = mat3(transpose(inverse(model))) * normal; } ); /*Cube Fragment shader program source code*/ const GLchar * cubeFragmentShaderSource = GLSL(330, in vec3 Normal; in vec3 FragmentPos; out vec4 cubeColor; //uniform variables uniform vec3 objectColor; uniform vec3 lightColor; uniform vec3 lightPos; uniform vec3 viewPosition; void main(){ //phong lighting model calculations to generate ambient, diffuse, and specular components //calculate ambient lighting float ambientStrength = 0.1f; vec3 ambient = ambientStrength * lightColor; //calculater diffuse lighting vec3 norm = normalize(Normal); vec3 lightDirection = normalize(lightPos - FragmentPos); float impact = max(dot(norm, lightDirection), 0.0); vec3 diffuse = impact * lightColor; //calculate specular lighting float specularIntensity = 1.8f; float highlightSize = 16.0f; vec3 viewDir = normalize(viewPosition - FragmentPos); vec3 reflectDir = reflect(-lightDirection, norm); //calculate specular component float specularComponent = pow(max(dot(viewDir, reflectDir), 0.0), highlightSize); vec3 specular = specularIntensity * specularComponent * lightColor; //calculate phong result vec3 phong = (ambient + diffue + specular) * objectColor; cubeColor = vec4(phong, 1.0f); } ); /* lamp shader source code*/ const GLchar * lampVertexShaderSource = GLSL(330, layout (location = 0) in vec3 position; //Global variables for the transform matrices uniform mat4 model; uniform mat4 view; uniform mat4 projection; void main() { gl_Position = projection * view * model * vec4(position, 1.0f);//transform vertices } ); /*Fragment Shader Source Code*/ const GLchar * lampFragmentShaderSource = GLSL(330, out vec4 color; void main() { color = vec4(1.0f); } ); //main program int main(int argc, char* argv[]) { glutInit(&amp;argc, argv); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); glutInitWindowSize(WindowWidth, WindowHeight); glutCreateWindow(WINDOW_TITLE); glutReshapeFunc(UResizeWindow); glewExperimental = GL_TRUE; if (glewInit()!= GLEW_OK) { std::cout &lt;&lt; "Failed to initialize GLEW" &lt;&lt; std::endl; return -1; } UCreateShader(); UCreateBuffers(); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color glutDisplayFunc(URenderGraphics); glutMainLoop(); // Destroys Buffer objects once used glDeleteVertexArrays(1, &amp;CubeVAO); glDeleteVertexArrays(1, &amp;LightVAO); glDeleteBuffers(1, &amp;VBO); return 0; } /* Resizes the window*/ void UResizeWindow(int w, int h) { WindowWidth = w; WindowHeight = h; glViewport(0, 0, WindowWidth, WindowHeight); } /* Renders graphics */ void URenderGraphics(void) { glEnable(GL_DEPTH_TEST); // Enable z-depth glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clears the screen GLint modelLoc, viewLoc, projLoc, objectColorLoc, lightColorLoc, lightPositionLoc, viewPositionLoc; glm::mat4 model; glm::mat4 view; glm::mat4 projection; //use cube shader and activate cube VAO glUseProgram(cubeShaderProgram); glBindVertexArray(CubeVAO); //transform the cube model = glm::translate(model, cameraPosition); model = glm::scale(model, cubeScale); // Transforms the camera view = glm::translate(view, cameraPosition); view = glm::rotate(view, cameraRotation, glm::vec3(0.0f, 1.0f, 0.0f)); //set the camera projection to perspective projection = glm::perspective(45.0f, (GLfloat)WindowWidth / (GLfloat)WindowHeight, 0.1f, 100.0f); // reference matrix uniforms from the cube shader program modelLoc = glGetUniformLocation(cubeShaderProgram, "model"); viewLoc = glGetUniformLocation(cubeShaderProgram, "view"); projLoc = glGetUniformLocation(cubeShaderProgram, "projection"); //pass matrix data to the cube shader program's matrix uniforms glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection)); // reference matrix uniforms from the cube shader program for the cube color, light color, light position, and camera position objectColorLoc = glGetUniformLocation(cubeShaderProgram, "objectColor"); lightColorLoc = glGetUniformLocation(cubeShaderProgram, "lightColor"); lightPositionLoc = glGetUniformLocation(cubeShaderProgram, "lightPos"); viewPositionLoc = glGetUniformLocation(cubeShaderProgram, "viewPosition"); //pass color, light, and camera data to the cube shader program's corresponding uniforms glUniform3f(objectColorLoc, objectColor.r, objectColor.g, objectColor.b); glUniform3f(lightColorLoc, lightColor.r, lightColor.g, lightColor.b); glUniform3f(lightPositionLoc, lightPosition.x, lightPosition.y, lightPosition.z); glUniform3f(viewPositionLoc, cameraPosition.x, cameraPosition.y, cameraPosition.z); glDrawArrays(GL_TRIANGLES, 0, 36); // use the lamp shader and activate the LVAO glUseProgram(lampShaderProgram); glBindVertexArray(LightVAO); // transform the smaller cube model = glm::translate(model, lightPosition); model = glm::scale(model, lightScale); // reference matrix uniforms from the lamp shader program modelLoc = glGetUniformLocation(lampShaderProgram, "model"); viewLoc = glGetUniformLocation(lampShaderProgram, "view"); projLoc = glGetUniformLocation(lampShaderProgram, "projection"); //pass matrix data to the lamp shader program's matrix uniforms glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection)); glDrawArrays(GL_TRIANGLES,0, 36); glBindVertexArray(0); // Deactivate the Vertex Array Object glutPostRedisplay(); glutSwapBuffers(); } /*Creates the Shader program*/ void UCreateShader() { // cube Vertex shader GLint cubeVertexShader = glCreateShader(GL_VERTEX_SHADER); // Creates the Vertex Shader glShaderSource(cubeVertexShader, 1, &amp;cubeVertexShaderSource, NULL); // Attaches the Vertex Shader to the source code glCompileShader(cubeVertexShader); // Compiles the Vertex Shader // cube Fragment Shader GLint cubeFragmentShader = glCreateShader(GL_FRAGMENT_SHADER); // Creates the Fragment Shader glShaderSource(cubeFragmentShader, 1, &amp;cubeFragmentShaderSource, NULL);// Attaches the Fragment Shader to the source code glCompileShader(cubeFragmentShader); // Compiles the Fragment Shader // Cube Shader program cubeShaderProgram = glCreateProgram(); // Creates the Shader program and returns an id glAttachShader(cubeShaderProgram, cubeVertexShader); // Attach Vertex Shader to the Shader program glAttachShader(cubeShaderProgram, cubeFragmentShader);; // Attach Fragment Shader to the Shader program glLinkProgram(cubeShaderProgram); //Link Vertex and Fragment shader, to Shader program // Delete the cube Vertex and Fragment shaders once linked glDeleteShader(cubeVertexShader); glDeleteShader(cubeFragmentShader); // Lamp Vertex Shader GLint lampVertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(lampVertexShader, 1, &amp;lampVertexShaderSource, NULL); glCompileShader(lampVertexShader); // Lamp Fragment Shader GLint lampFragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(lampFragmentShader, 1, &amp;lampFragmentShaderSource, NULL); glCompileShader(lampFragmentShader); // Cube Shader program lampShaderProgram = glCreateProgram(); // Creates the Shader program and returns an id glAttachShader(lampShaderProgram, lampVertexShader); // Attach Vertex Shader to the Shader program glAttachShader(lampShaderProgram, lampFragmentShader);; // Attach Fragment Shader to the Shader program glLinkProgram(lampShaderProgram); //Link Vertex and Fragment shader, to Shader program // Delete the lamp Vertex and Fragment shaders once linked glDeleteShader(lampVertexShader); glDeleteShader(lampFragmentShader); } /*creates the buffer and array object*/ void UCreateBuffers() { </code></pre> <p>I have tried testing the vertices on their own and i can see the cube. I dont understand why its disapering after adding the lighting. </p> <pre><code> //position and color data GLfloat vertices[] = { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.5f, -0.5f, -0.5f, 0.0f,0.0f, -1.0f, 0.5f, 0.5f, -0.5f, 0.0f,0.0f, -1.0f, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f,-1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 0.0f,-1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f,-1.0f, -0.5f, -0.5f, 0.5f, 0.0f,0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 0.0f,0.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.0f,0.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.0f,0.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f,0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f,0.0f, 1.0f, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f,0.0f, -0.5f, 0.5f, -0.5f, -1.0f, 0.0f,0.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f,0.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f,0.0f, -0.5f, -0.5f, 0.5f, -1.0f, 0.0f,0.0f, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f,0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f,0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 0.0f,0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f,0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f,0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f,0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f,0.0f, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f,0.0f, 0.5f, -0.5f, -0.5f, 0.0f, -1.0f,0.0f, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f,0.0f, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f,0.0f, -0.5f, -0.5f, 0.5f, 0.0f, -1.0f,0.0f, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f,0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f,0.0f, 0.5f, 0.5f, -0.5f, 0.0f, 1.0f,0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f,0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f,0.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f,0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f,0.0f }; //Generate buffer id, glGenVertexArrays(1, &amp;CubeVAO); glGenBuffers(1,&amp;VBO); // Activate the Vertex Array Object before binding and setting any VB0s and Vertex Attribute Pointers. glBindVertexArray(CubeVAO); // Activate the VBO glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); //Copy vertices to VBO // Set attribute pointer 0 to hold Position data glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); // Enables vertex attribute // Set attribute pointer 1 to hold normal data glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(1); // Enables vertex attribute glBindVertexArray(0); // Deactivates the VAC, which is good practice /*Generate buffer ids for lamp (smaller cube)*/ glGenVertexArrays(1, &amp;LightVAO); // activate the VAO glBindVertexArray(LightVAO); // referencing the same VBO glBindBuffer(GL_ARRAY_BUFFER, VBO); // set attribute pointer 0 to hold position data for the lamp glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); glBindVertexArray(0); } </code></pre> <br /><h3>回答1:</h3><br /><p>The "cube" fragment shader fails to compile. The variable <code>diffus</code> does not exist, it has to be <code>diffuse</code>:</p> <p><s><code>vec3 phong = (ambient + diffus + specular) * objectColor;</code></s> </p> <pre class="lang-c prettyprint-override"><code>vec3 phong = (ambient + diffuse + specular) * objectColor; </code></pre> <hr /><p>I recommend to verify if compiling the shader succeeded by glGetShaderiv(..., GL_COMPILE_STATUS, ...) and linking succeeded by glGetProgramiv(..., GL_LINK_STATUS, ...).</p> <p>Implement functions which validate a shader and a program and log the error messages:</p> <pre class="lang-cpp prettyprint-override"><code>#include &lt;iostream&gt; #include &lt;vector&gt; void CompileStatus( GLuint shader ) { GLint status = GL_TRUE; glGetShaderiv( shader, GL_COMPILE_STATUS, &amp;status ); if (status == GL_FALSE) { GLint logLen; glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &amp;logLen ); std::vector&lt; char &gt;log( logLen ); GLsizei written; glGetShaderInfoLog( shader, logLen, &amp;written, log.data() ); std::cout &lt;&lt; "compile error:" &lt;&lt; std::endl &lt;&lt; log.data() &lt;&lt; std::endl; } } void LinkStatus( GLuint program ) { GLint status = GL_TRUE; glGetProgramiv( program, GL_LINK_STATUS, &amp;status ); if (status == GL_FALSE) { GLint logLen; glGetProgramiv( program, GL_INFO_LOG_LENGTH, &amp;logLen ); std::vector&lt; char &gt;log( logLen ); GLsizei written; glGetProgramInfoLog( program, logLen, &amp;written, log.data() ); std::cout &lt;&lt; "link error:" &lt;&lt; std::endl &lt;&lt; log.data() &lt;&lt; std::endl; } } </code></pre> <p>Validate the shaders after <code>glCompileShader</code> and the program after <code>glLinkProgram</code>:</p> <pre class="lang-cpp prettyprint-override"><code>void UCreateShader() { // cube Vertex shader GLint cubeVertexShader = glCreateShader(GL_VERTEX_SHADER); // Creates the Vertex Shader glShaderSource(cubeVertexShader, 1, &amp;cubeVertexShaderSource, NULL); // Attaches the Vertex Shader to the source code glCompileShader(cubeVertexShader); // Compiles the Vertex Shader CompileStatus( cubeVertexShader ); // cube Fragment Shader GLint cubeFragmentShader = glCreateShader(GL_FRAGMENT_SHADER); // Creates the Fragment Shader glShaderSource(cubeFragmentShader, 1, &amp;cubeFragmentShaderSource, NULL);// Attaches the Fragment Shader to the source code glCompileShader(cubeFragmentShader); // Compiles the Fragment Shader CompileStatus( cubeFragmentShader ); // Cube Shader program cubeShaderProgram = glCreateProgram(); // Creates the Shader program and returns an id glAttachShader(cubeShaderProgram, cubeVertexShader); // Attach Vertex Shader to the Shader program glAttachShader(cubeShaderProgram, cubeFragmentShader);; // Attach Fragment Shader to the Shader program glLinkProgram(cubeShaderProgram); //Link Vertex and Fragment shader, to Shader program LinkStatus( cubeShaderProgram ); // [...] } </code></pre> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/59235204/light-shows-but-the-cube-does-not-appear</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/c-0" hreflang="zh-hans">c++</a></div> <div class="field--item"><a href="/tag/opengl" hreflang="zh-hans">opengl</a></div> <div class="field--item"><a href="/tag/glut" hreflang="zh-hans">glut</a></div> <div class="field--item"><a href="/tag/glm-math" hreflang="zh-hans">glm-math</a></div> <div class="field--item"><a href="/tag/vao" hreflang="zh-hans">vao</a></div> </div> </div> Tue, 16 Feb 2021 19:16:19 +0000 怎甘沉沦 4108425 at http://www.e-learn.cn Instancing cubes next to each other OpenGL http://www.e-learn.cn/topic/4094229 <span>Instancing cubes next to each other OpenGL</span> <span><span lang="" about="/user/66" typeof="schema:Person" property="schema:name" datatype="">自古美人都是妖i</span></span> <span>2021-02-11 07:59:12</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>I tried to instance many cubes side by side each other. </p> <p>My understanding is that I need to create a <code>MVP</code> matrix for each cube and bind this then somehow change the position. then run this in a for loop for how many cubes you'd want.</p> <p>This is what I've tried:</p> <pre><code>while (!glfwWindowShouldClose(window)) { glClearColor(0.0f / 255.0f, 170.0f / 255.0f, 204.0f / 255.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(programID); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0 ); computeMatricesFromInputs(); glm::mat4 ProjectionMatrix = getProjectionMatrix(); glm::mat4 ViewMatrix = getViewMatrix(); glm::mat4 ModelMatrix = glm::mat4(1.0); glm::mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix; for (int i = 0; i == cubes; i++) { GLuint MatrixID = glGetUniformLocation(programID, "MVP"); glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &amp;MVP[0][0]); glDrawArraysInstanced(GL_TRIANGLES, 0, 1, i); } //GLuint MatrixID = glGetUniformLocation(programID, "MVP"); //glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &amp;MVP[0][0]); //glDrawArrays(GL_TRIANGLES, 0, 12*3); glDisableVertexAttribArray(0); glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, texturebuffer); glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0 ); glfwSwapBuffers(window); glfwPollEvents(); } </code></pre> <p>This doesn't draw any cubes at all and I can't figure out how I would change the position for each cube to be side by side each other. So why does this code not draw instanced cubes and how would I be able to change the position of each cube to rest next to each other?</p> <br /><h3>回答1:</h3><br /><p>The 3rd parameter of glDrawArraysInstanced is the number of vertices you want to draw respectively of the cube (just like as glDrawArrays), the 4th is the number of instances to be drawn by 1 draw call, not the index of an instance.</p> <p>Anyway You don't need glDrawArraysInstanced at all, because you draw each cube separately. Use glDrawArrays instead:</p> <pre class="lang-cpp prettyprint-override"><code>for (int i = 0; i &lt; cubes; i++) { GLuint MatrixID = glGetUniformLocation(programID, "MVP"); glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &amp;MVP[0][0]); glDrawArrays(GL_TRIANGLES, 0, noOfVertices); } </code></pre> <p>This can be substituted by <code>glDrawArraysInstanced</code>:</p> <pre class="lang-cpp prettyprint-override"><code>glDrawArraysInstanced(GL_TRIANGLES, 0, noOfVertices, cubes); </code></pre> <p>That will draw all the cubes <code>cubes</code> at once. To make that work, you have to find a way to use a different model matrix for each instance.<br /> One possibility is to use a Shader Storage Buffer Object (SSBO), to store all the model matrices in an array. In the vertex shader the index of the instance (index of the cube) can be get by the built-in input gl_InstanceID. That variable can be used to get the proper model matrix for the instance form the array.</p> <p>e.g:</p> <pre class="lang-c prettyprint-override"><code>layout(std430) buffer Matrices { mat4 mvpArray[]; }; void main() { mat4 mvp = mvpArray[gl_InstanceID]; // [...] } </code></pre> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/61036711/instancing-cubes-next-to-each-other-opengl</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/c-0" hreflang="zh-hans">c++</a></div> <div class="field--item"><a href="/tag/opengl" hreflang="zh-hans">opengl</a></div> <div class="field--item"><a href="/tag/instance" hreflang="zh-hans">instance</a></div> <div class="field--item"><a href="/tag/glfw" hreflang="zh-hans">glfw</a></div> <div class="field--item"><a href="/tag/glm-math" hreflang="zh-hans">glm-math</a></div> </div> </div> Wed, 10 Feb 2021 23:59:12 +0000 自古美人都是妖i 4094229 at http://www.e-learn.cn OpenGL Perspective Projection Clipping Polygon with Vertex Outside Frustum = Wrong texture mapping? http://www.e-learn.cn/topic/4054158 <span>OpenGL Perspective Projection Clipping Polygon with Vertex Outside Frustum = Wrong texture mapping?</span> <span><span lang="" about="/user/97" typeof="schema:Person" property="schema:name" datatype="">两盒软妹~`</span></span> <span>2021-02-05 09:02:29</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>I see an issue where I can correctly draw a textured polygon if all vertices remain onscreen within a perspective projection, BUT if I scale the quad large enough such that one more more vertices fall 'too far behind' the viewing volume, then the resulting OpenGL drawing is incorrect (see screenshots). The texture mapping becomes skewed, and it appears as though the offscreen vertex 'moved' and becomes distorted. I am using GLES 2.0 code on a GLES 3.0 compliant driver (details at bottom). I will now explain my test in more detail --</p> <p>I am drawing a GL_TRIANGLE_STRIP 'square' made of two simple polygons, and applying simplistic texture map on the quad (the texture maps perfectly onto the quad once only, with no repeats. UV coordinates 0-&gt;1 mapped as you would expect.</p> <p>Seperately, I am using GLM functions to give me helpers for matrix transformations, and subsequently using glm::PerspectiveFov() to set up the viewing volume (frustum). The result is a camera looking slightly downward onto the quad, creating a 'ground' like surface with a checker patterned texture on it.</p> <p>correctly drawn view of quad screenshot</p> <p>From here, if I increase the scale transformation factor on the quad any further, or rotate the camera such that the offscreen corner vertices lie 'further back' from the viewing area, I see suddenly extreme weird behavior, as though the texture mapping changes, or if one vertex of the polygon is shifting incorrectly. See here:</p> <p>polygon texture mapping becomes wrong</p> <p>For the camera rotation I am using glm::lookAt() -- effectively I move the 'eye' position while keeping the target at 0,0 in the scene (center of the polygon).</p> <p>Also note that when I cross this threshold, I see the red debug line I draw connecting all the vertices suddenly shift its orientation from where it should be.</p> <p>Does anyone know how this problem originates? Is there a way to solve it so I can draw a big huge quad and have vertices offscreen without these problems/artifacts? Thanks!!!</p> <p>GPU Info:</p> <p>GL Vendor: Vivante Corporation</p> <p>GL Renderer: Vivante GC2000</p> <p>GL Version: OpenGL ES 3.0 V5.0.11.p8.41671</p> <p>GLSL Version: OpenGL ES GLSL ES 3.00</p> <br /><h3>回答1:</h3><br /><p>Some research and comments on my original question have led me to believe that the observed effect is the result of a bug in the OpenGL driver implementation on the Vivante GPU GC2000. Apparently such bugs are common on embedded GPU hardware drivers - a problem exacerbated by the fact that the source code for such ES implementations is never available. </p> <p>To solve this one via a workaround, I was able to take the dimensions of my original square and instead create a grid array of textured squares so that all polygons end up being small enough to 'fit' close enough to the viewing area (or alternatively be completely clipped, avoiding the bug behavior). Code in C++:</p> <pre><code>// measurements we will add as we move along the grid float tile_size = 1.0 / num_grid_subdivisions; // square width 1 float tile_uv_dist = 1.0 / num_grid_subdivisions; // assume 0-&gt;1 texture mapping XY curr_bl = XY(-0.5, -0.5); // quad from -0.5 to 0.5 in x and y (1x1) float cu = 0; //current texture coordinates in x dimension float cv = 0; //current texture coordinates in y dimension for (int row = 0; row &lt; num_grid_subdivisions; ++row) { for (int row_item = 0; row_item &lt; num_grid_subdivisions; ++row_item) { // GL_TRIANGLES to keep simple, but could use STRIP later VertXYUV bl(curr_bl, cu, cv); // bottomleft // if we know bottomleft, we know the rest of the points of the square VertXYUV tl(XY(curr_bl.x, curr_bl.y + tile_size), cu, cv + tile_uv_dist); VertXYUV br(XY(curr_bl.x + tile_size, curr_bl.y), cu+ tile_uv_dist, cv ); VertXYUV tr(XY(curr_bl.x + tile_size, curr_bl.y + tile_size), cu + tile_uv_dist, cv + tile_uv_dist); // our square tile is two triangle polygons AddVert(bl); AddVert(tl); AddVert(br); // triangle 1 AddVert(br); AddVert(tl); AddVert(tr); // triangle 2 // current info should always be tracking 'bl' of current tile // increment row item, moving across to the right (+x) cu += tile_uv_dist; curr_bl.x += tile_size; } // current info should always be tracking 'bl' of current tile // incrementing row, moving up (+y) cv += tile_uv_dist; cu = 0; // reset x space texture coordinate back to left side (0) curr_bl.y += tile_size; curr_bl.x = grid_bl.x; } </code></pre> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/44512396/opengl-perspective-projection-clipping-polygon-with-vertex-outside-frustum-wro</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/c-0" hreflang="zh-hans">c++</a></div> <div class="field--item"><a href="/tag/opengl-es" hreflang="zh-hans">opengl-es</a></div> <div class="field--item"><a href="/tag/embedded" hreflang="zh-hans">embedded</a></div> <div class="field--item"><a href="/tag/glm-math" hreflang="zh-hans">glm-math</a></div> </div> </div> Fri, 05 Feb 2021 01:02:29 +0000 两盒软妹~` 4054158 at http://www.e-learn.cn How does glm get away with not declaring a function inline and defining it inline in another (unconnected?) file? http://www.e-learn.cn/topic/4039071 <span>How does glm get away with not declaring a function inline and defining it inline in another (unconnected?) file?</span> <span><span lang="" about="/user/52" typeof="schema:Person" property="schema:name" datatype="">◇◆丶佛笑我妖孽</span></span> <span>2021-01-29 11:24:13</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>glm has some code that looks like this, once pre-processor macros are resolved on my particular setup:</p> <p>type_vec3.hpp</p> <pre><code>struct vec3 { /*...*/ vec3&amp; operator=(vec3 const &amp; v); /*...*/ } </code></pre> <p>type_vec3.inl</p> <pre><code>inline vec3&amp; vec3::operator=(vec3 const &amp; v) { /* implementation */ } </code></pre> <p>I couldn't find any related header include within the .inl file. When I try to rewrite with this kind of layout, I either get linker errors (which I believe is due to mismatch between header file declaration and the <code>inline</code>-specified definition) or namespacing issues (if the header isn't included in the inl file).</p> <p>Here is glm on GitHub: https://github.com/g-truc/glm. The files in question are here:</p> <p>https://github.com/g-truc/glm/blob/master/glm/detail/type_vec3.hpp (L179)</p> <p>https://github.com/g-truc/glm/blob/master/glm/detail/type_vec3.inl (L214)</p> <p>The headers included in these two files are not present in the version of glm I'm using, which seems to behave fine.</p> <p>Could someone please explain just what's going on here? </p> <br /><h3>回答1:</h3><br /><p>This is just a way to split the implementation and the declaration into separate files. The <code>.hpp</code> file declares <code>vec3</code>, then <code>#include</code>s the <code>.inl</code> file (unless a non-inline version was requested). It's easy to miss the <code>#include</code> as it is at the end of the <code>.hpp</code>, but it is there. Despite the claim that the files are unconnected, they are connected, albeit in the opposite direction than was expected.</p> <p>(Presumably, if <code>GLM_EXTERNAL_TEMPLATE</code> is defined, the definition of <code>vec3::operator=</code> would be provided in a separate component, not as an inline function.)</p> <p>Another aspect worth noting is that these files are in a directory called "detail". That is a convention that says those files are subject to change without notice. In particular, they might not exist in older versions. (They also might not exist in newer versions, but that is more of an academic point when you are looking at the newest version.)</p> <p>So the overall picture is that you <code>#include</code> one of the normal header files, which will make sure both <code>type_vec3.hpp</code> and <code>type_vec3.inl</code> are <code>#include</code>d in that order. That puts the inline definition in every translation unit that has the <code>vec3</code> declaration.</p> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/56844624/how-does-glm-get-away-with-not-declaring-a-function-inline-and-defining-it-inlin</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/c-0" hreflang="zh-hans">c++</a></div> <div class="field--item"><a href="/tag/glm-math" hreflang="zh-hans">glm-math</a></div> </div> </div> Fri, 29 Jan 2021 03:24:13 +0000 ◇◆丶佛笑我妖孽 4039071 at http://www.e-learn.cn How can I parse a simple .obj file into triangles? http://www.e-learn.cn/topic/4033995 <span>How can I parse a simple .obj file into triangles?</span> <span><span lang="" about="/user/89" typeof="schema:Person" property="schema:name" datatype="">巧了我就是萌</span></span> <span>2021-01-29 05:32:07</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>I'm trying to implement a ray caster and I'm starting out with simple .obj files (utah-teapot) and currently I only made classes for Spheres and Triangles, I basically have all the functions for the intersections, generating view rays, etc.. all ready but I just can't seem to be able to parse the .obj file into triangles (three vectors each) so I can have the ray casting possible on custom .obj files instead of just spheres.</p> <p>This is my current .obj file parser (didn't include the full working code here)</p> <pre><code>char lineHeader[512]; // read the first word of the line int res = fscanf(file, "%s", lineHeader); if (res == EOF) break; // EOF // else : parse lineHeader if (strcmp(lineHeader, "v") == 0) { glm::vec3 vertex; fscanf(file, "%f %f %f\n", &amp;vertex.x, &amp;vertex.y, &amp;vertex.z); vertex.x *= scale; vertex.y *= scale; vertex.z *= scale; temp_vertices.push_back(vertex); } else if (strcmp(lineHeader, "vt") == 0) { glm::vec2 uv; fscanf(file, "%f %f\n", &amp;uv.x, &amp;uv.y); uv.y = -uv.y; // Invert V coordinate since we will only use DDS texture, which are inverted. Remove if you want to use TGA or BMP loaders. temp_uvs.push_back(uv); } else if (strcmp(lineHeader, "vn") == 0) { glm::vec3 normal; fscanf(file, "%f %f %f\n", &amp;normal.x, &amp;normal.y, &amp;normal.z); temp_normals.push_back(normal); } else if (strcmp(lineHeader, "f") == 0) { std::string vertex1, vertex2, vertex3; unsigned int vertexIndex[3] = { 0 }, uvIndex[3] = { 0 }, normalIndex[3] = { 0 }; char stupidBuffer[1024]; fgets(stupidBuffer, 1024, file); int matches = sscanf(stupidBuffer, "%d/%d/%d %d/%d/%d %d/%d/%d\n", &amp;vertexIndex[0], &amp;uvIndex[0], &amp;normalIndex[0], &amp;vertexIndex[1], &amp;uvIndex[1], &amp;normalIndex[1], &amp;vertexIndex[2], &amp;uvIndex[2], &amp;normalIndex[2]); if (matches != 9) { vertexIndex[3] = { 0 }, uvIndex[3] = { 0 }, normalIndex[3] = { 0 }; matches = sscanf(stupidBuffer, "%d//%d %d//%d %d//%d\n", &amp;vertexIndex[0], &amp;normalIndex[0], &amp;vertexIndex[1], &amp;normalIndex[1], &amp;vertexIndex[2], &amp;normalIndex[2]); if (matches != 6) { vertexIndex[3] = { 0 }, uvIndex[3] = { 0 }, normalIndex[3] = { 0 }; matches = sscanf(stupidBuffer, "%d %d %d\n", &amp;vertexIndex[0], &amp;vertexIndex[1], &amp;vertexIndex[2]); if (matches != 3) { printf("File can't be read \n"); fclose(file); return false; } } } } </code></pre> <p>This is my triangle class</p> <pre><code>class Triangle { public: Vector p0, p1, p2; Vector color; Vector normal(void); }; </code></pre> <p>I can't figure out how to parse the info from the .obj file into triangles that consist of three 3d vectors (points). I don't need code, I just need to understand how (if possible?) to parse all that info into triangles. Any other ideas are welcome. I want to make a simple puzzle game on the long run but I'm just taking it a step at a time.</p> <br /><h3>回答1:</h3><br /><p>You're 90% of the way there. In your face element parser use the parsed position/normal/texcoord indexes of each face-vertex to grab info from the <code>temp_*</code> vectors. If a face element has three vertices you can emit a triangle as-is, otherwise for 4+ vertices I've generally assumed the the resulting polygon is convex &amp; co-planar, in which case you can triangulate by pretending it's a triangle fan.</p> <p>All together:</p> <pre><code>struct Vertex { glm::vec3 position; glm::vec2 texcoord; glm::vec3 normal; }; struct VertRef { VertRef( int v, int vt, int vn ) : v(v), vt(vt), vn(vn) { } int v, vt, vn; }; std::vector&lt; Vertex &gt; LoadOBJ( std::istream&amp; in ) { std::vector&lt; Vertex &gt; verts; std::vector&lt; glm::vec4 &gt; positions( 1, glm::vec4( 0, 0, 0, 0 ) ); std::vector&lt; glm::vec3 &gt; texcoords( 1, glm::vec3( 0, 0, 0 ) ); std::vector&lt; glm::vec3 &gt; normals( 1, glm::vec3( 0, 0, 0 ) ); std::string lineStr; while( std::getline( in, lineStr ) ) { std::istringstream lineSS( lineStr ); std::string lineType; lineSS &gt;&gt; lineType; // vertex if( lineType == "v" ) { float x = 0, y = 0, z = 0, w = 1; lineSS &gt;&gt; x &gt;&gt; y &gt;&gt; z &gt;&gt; w; positions.push_back( glm::vec4( x, y, z, w ) ); } // texture if( lineType == "vt" ) { float u = 0, v = 0, w = 0; lineSS &gt;&gt; u &gt;&gt; v &gt;&gt; w; texcoords.push_back( glm::vec3( u, v, w ) ); } // normal if( lineType == "vn" ) { float i = 0, j = 0, k = 0; lineSS &gt;&gt; i &gt;&gt; j &gt;&gt; k; normals.push_back( glm::normalize( glm::vec3( i, j, k ) ) ); } // polygon if( lineType == "f" ) { std::vector&lt; VertRef &gt; refs; std::string refStr; while( lineSS &gt;&gt; refStr ) { std::istringstream ref( refStr ); std::string vStr, vtStr, vnStr; std::getline( ref, vStr, '/' ); std::getline( ref, vtStr, '/' ); std::getline( ref, vnStr, '/' ); int v = atoi( vStr.c_str() ); int vt = atoi( vtStr.c_str() ); int vn = atoi( vnStr.c_str() ); v = ( v &gt;= 0 ? v : positions.size() + v ); vt = ( vt &gt;= 0 ? vt : texcoords.size() + vt ); vn = ( vn &gt;= 0 ? vn : normals.size() + vn ); refs.push_back( VertRef( v, vt, vn ) ); } // triangulate, assuming n&gt;3-gons are convex and coplanar for( size_t i = 1; i+1 &lt; refs.size(); ++i ) { const VertRef* p[3] = { &amp;refs[0], &amp;refs[i], &amp;refs[i+1] }; // http://www.opengl.org/wiki/Calculating_a_Surface_Normal glm::vec3 U( positions[ p[1]-&gt;v ] - positions[ p[0]-&gt;v ] ); glm::vec3 V( positions[ p[2]-&gt;v ] - positions[ p[0]-&gt;v ] ); glm::vec3 faceNormal = glm::normalize( glm::cross( U, V ) ); for( size_t j = 0; j &lt; 3; ++j ) { Vertex vert; vert.position = glm::vec3( positions[ p[j]-&gt;v ] ); vert.texcoord = glm::vec2( texcoords[ p[j]-&gt;vt ] ); vert.normal = ( p[j]-&gt;vn != 0 ? normals[ p[j]-&gt;vn ] : faceNormal ); verts.push_back( vert ); } } } } return verts; } </code></pre> <p>See the full program here.</p> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/52824956/how-can-i-parse-a-simple-obj-file-into-triangles</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/c-0" hreflang="zh-hans">c++</a></div> <div class="field--item"><a href="/tag/opengl" hreflang="zh-hans">opengl</a></div> <div class="field--item"><a href="/tag/glm-math" hreflang="zh-hans">glm-math</a></div> <div class="field--item"><a href="/tag/wavefront" hreflang="zh-hans">wavefront</a></div> </div> </div> Thu, 28 Jan 2021 21:32:07 +0000 巧了我就是萌 4033995 at http://www.e-learn.cn Trouble with separating axis theorem C++ http://www.e-learn.cn/topic/3977913 <span>Trouble with separating axis theorem C++</span> <span><span lang="" about="/user/81" typeof="schema:Person" property="schema:name" datatype="">人盡茶涼</span></span> <span>2020-12-26 12:45:58</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>I am trying to perform separating axis theorem on two triangles to test for collisions between them however it is not working.</p> <p>My relevant code is:</p> <pre><code>glm::vec3 CalcSurfaceNormal(glm::vec3 tri1, glm::vec3 tri2, glm::vec3 tri3) { //Get surface normal of a triangle glm::vec3 u = tri2 - tri1; glm::vec3 v = tri3 - tri1; glm::vec3 nrmcross = glm::cross(u, v); nrmcross = glm::normalize(nrmcross); return nrmcross; } bool SATTriangleCheck(glm::vec3 axis, glm::vec3 tri1vert1, glm::vec3 tri1vert2, glm::vec3 tri1vert3, glm::vec3 tri2vert1, glm::vec3 tri2vert2, glm::vec3 tri2vert3) { //Dot each vertex with the axis and get the min and max int t1v1 = glm::dot(axis, tri1vert1); int t1v2 = glm::dot(axis, tri1vert2); int t1v3 = glm::dot(axis, tri1vert3); int t2v1 = glm::dot(axis, tri2vert1); int t2v2 = glm::dot(axis, tri2vert2); int t2v3 = glm::dot(axis, tri2vert3); int t1min = glm::min(t1v1, glm::min(t1v2, t1v3)); int t1max = glm::min(t1v1, glm::min(t1v2, t1v3)); int t2min = glm::min(t2v1, glm::min(t2v2, t2v3)); int t2max = glm::min(t2v1, glm::min(t2v2, t2v3)); //Test for overlaps if ((t1min &lt; t2max &amp;&amp; t1min &gt; t2min) || (t1max &lt; t2max &amp;&amp; t1max &gt; t2min) || (t2min &lt; t1max &amp;&amp; t2min &gt; t1min) || (t2max &lt; t1max &amp;&amp; t2max &gt; t1min)) return true; return false; } bool CollisionHelper::isTriangleIntersectingTriangle(glm::vec3 tri1, glm::vec3 tri2, glm::vec3 tri3, glm::vec3 otherTri1, glm::vec3 otherTri2, glm::vec3 otherTri3) { //Triangle surface normals, 2 axes to test glm::vec3 tri1FaceNrml = CalcSurfaceNormal(tri1, tri2, tri3); glm::vec3 tri2FaceNrml = CalcSurfaceNormal(otherTri1, otherTri2, otherTri3); //Calculate edges glm::vec3 tri1Edge1 = tri2 - tri1; glm::vec3 tri1Edge2 = tri3 - tri1; glm::vec3 tri1Edge3 = tri3 - tri2; glm::vec3 tri2Edge1 = otherTri2 - otherTri1; glm::vec3 tri2Edge2 = otherTri3 - otherTri1; glm::vec3 tri2Edge3 = otherTri3 - otherTri2; //Calculate all axes glm::vec3 axis1 = tri1FaceNrml; glm::vec3 axis2 = tri2FaceNrml; glm::vec3 axis3 = glm::normalize(glm::cross(tri1Edge1, tri2Edge1)); glm::vec3 axis4 = glm::normalize(glm::cross(tri1Edge1, tri2Edge2)); glm::vec3 axis5 = glm::normalize(glm::cross(tri1Edge1, tri2Edge3)); glm::vec3 axis6 = glm::normalize(glm::cross(tri1Edge2, tri2Edge1)); glm::vec3 axis7 = glm::normalize(glm::cross(tri1Edge2, tri2Edge2)); glm::vec3 axis8 = glm::normalize(glm::cross(tri1Edge2, tri2Edge3)); glm::vec3 axis9 = glm::normalize(glm::cross(tri1Edge3, tri2Edge1)); glm::vec3 axis10 = glm::normalize(glm::cross(tri1Edge3, tri2Edge2)); glm::vec3 axis11 = glm::normalize(glm::cross(tri1Edge3, tri2Edge3)); //Perform SAT if (SATTriangleCheck(axis1, tri1, tri2, tri3, otherTri1, otherTri2, otherTri3)) return true; if (SATTriangleCheck(axis2, tri1, tri2, tri3, otherTri1, otherTri2, otherTri3)) return true; if (SATTriangleCheck(axis3, tri1, tri2, tri3, otherTri1, otherTri2, otherTri3)) return true; if (SATTriangleCheck(axis4, tri1, tri2, tri3, otherTri1, otherTri2, otherTri3)) return true; if (SATTriangleCheck(axis5, tri1, tri2, tri3, otherTri1, otherTri2, otherTri3)) return true; if (SATTriangleCheck(axis6, tri1, tri2, tri3, otherTri1, otherTri2, otherTri3)) return true; if (SATTriangleCheck(axis7, tri1, tri2, tri3, otherTri1, otherTri2, otherTri3)) return true; if (SATTriangleCheck(axis8, tri1, tri2, tri3, otherTri1, otherTri2, otherTri3)) return true; if (SATTriangleCheck(axis9, tri1, tri2, tri3, otherTri1, otherTri2, otherTri3)) return true; if (SATTriangleCheck(axis10, tri1, tri2, tri3, otherTri1, otherTri2, otherTri3)) return true; if (SATTriangleCheck(axis11, tri1, tri2, tri3, otherTri1, otherTri2, otherTri3)) return true; return false; } </code></pre> <p>The code that calls and verifies these functions is in a main game loop every frame that passes in the x y and z coords of both triangles:</p> <pre><code>if (CollisionHelper::isTriangleIntersectingTriangle(glm::vec3(tri11.x, tri11.y, tri11.z), glm::vec3(tri22.x, tri22.y, tri22.z), glm::vec3(tri33.x, tri33.y, tri33.z), glm::vec3(othertri11.x, othertri11.y, othertri11.z), glm::vec3(othertri22.x, othertri22.y, othertri22.z), glm::vec3(othertri33.x, othertri33.y, othertri33.z))) { std::cout &lt;&lt; "Triangle intersection\n"; } </code></pre> <p>I never get anything printed to the console. One of the triangles is rotated 90 degrees from the other</p> <p>来源:<code>https://stackoverflow.com/questions/63943600/trouble-with-separating-axis-theorem-c</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/c-0" hreflang="zh-hans">c++</a></div> <div class="field--item"><a href="/tag/algorithm" hreflang="zh-hans">algorithm</a></div> <div class="field--item"><a href="/tag/collision-detection" hreflang="zh-hans">collision-detection</a></div> <div class="field--item"><a href="/tag/game-development" hreflang="zh-hans">game-development</a></div> <div class="field--item"><a href="/tag/glm-math" hreflang="zh-hans">glm-math</a></div> </div> </div> Sat, 26 Dec 2020 04:45:58 +0000 人盡茶涼 3977913 at http://www.e-learn.cn Quaternion based point rotations using GLM http://www.e-learn.cn/topic/3838422 <span>Quaternion based point rotations using GLM</span> <span><span lang="" about="/user/78" typeof="schema:Person" property="schema:name" datatype="">懵懂的女人</span></span> <span>2020-10-01 19:18:06</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><p>来源:<code>https://stackoverflow.com/questions/62937791/quaternion-based-point-rotations-using-glm</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/c-0" hreflang="zh-hans">c++</a></div> <div class="field--item"><a href="/tag/math" hreflang="zh-hans">math</a></div> <div class="field--item"><a href="/tag/rotation" hreflang="zh-hans">rotation</a></div> <div class="field--item"><a href="/tag/quaternions" hreflang="zh-hans">quaternions</a></div> <div class="field--item"><a href="/tag/glm-math" hreflang="zh-hans">glm-math</a></div> </div> </div> Thu, 01 Oct 2020 11:18:06 +0000 懵懂的女人 3838422 at http://www.e-learn.cn How to write a debugging helper for qtcreator? http://www.e-learn.cn/topic/3782357 <span>How to write a debugging helper for qtcreator?</span> <span><span lang="" about="/user/31" typeof="schema:Person" property="schema:name" datatype="">China☆狼群</span></span> <span>2020-08-23 08:02:06</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>When debugging my C++ program using the glm::vec3 class with gdb, the vector classes are quite cumbersome to work with:<br /></p> <p>I've read in the manual, that it's possible to write debug helpers.<br /> I've managed to get qtcreator to load the file (the debugger exits immediately with an error, if my python file has a syntax error).</p> <p>How can I write a minimalistic debugging helper?</p> <h3>What I've already tried:</h3> <p>Here's the C++ code</p> <pre><code>#include &lt;glm/glm.hpp&gt; class Foo { }; int main(int, char**) { glm::vec3 vec3(42, 64, 256); Foo foo; (void)vec3; (void)foo; return 0; } </code></pre> <p>This is my debugging helper:</p> <pre><code>from dumper import * def qdump__glm__vec3(d, value): d.put("Yay, vec3 works :)") def qdump__Foo(d, value): d.put("Yay, Foo works :)") </code></pre> <p>The vec3 code seems not to have any visible effect. For foo, it seems to do something, but instead of printing <code>Yay, Foo works :)</code> , qtcreator just shows <code>&lt;not accessible&gt;</code>. See the following screenshot:</p> <p></p> <br /><h3>回答1:</h3><br /><h1>The short Answer: A Minimum example</h1> <p>Here's a minimum example for a debug helper:</p> <p>C++ code:</p> <pre><code>class Foo { }; int main(int, char**) { Foo foo; (void)foo; return 0; } </code></pre> <p>The debug-helper:</p> <pre><code>from dumper import * def qdump__Foo(d, value): d.putNumChild(0) d.putValue("Yay, Foo works :)") </code></pre> <p>The result:</p> <p></p> <h2>Explanation</h2> <p>You've mixed up <code>put</code> and <code>putValue</code>. To quote from the link you've provided:</p> <blockquote> <p><em>put(self, value)</em> - Low level function to directly append to the output string. That is also the fastest way to append output.</p> </blockquote> <p><code>put</code> is a low level function and requires a very specific formating and thus may not be the optimal starting point for a minimum example.<br /> Use instead <code>putValue</code>, this function can be used to print the value of a variable.</p> <h1>The short Answer for glm::vec3</h1> <p>Here's the working example for glm::vec3:</p> <p>C++ code:</p> <pre><code>#include &lt;glm/glm.hpp&gt; int main(int, char**) { glm::vec3 vec3(42, 64, 256); (void)vec3; return 0; } </code></pre> <p>The debug-helper:</p> <pre><code>from dumper import * def qdump__glm__tvec3(d, value): d.putValue("[{0}, {1}, {2}]".format(value["x"], value["y"], value["z"])) d.putNumChild(3) if d.isExpanded(): with Children(d): d.putSubItem("x", value["x"]) d.putSubItem("y", value["y"]) d.putSubItem("z", value["z"]) </code></pre> <p>The result:<br /></p> <p>And to match your first screenshot for debugging a ray:<br /></p> <h2>Explanation</h2> <p>The reason, vec3 doesn't show up is, that <code>glm::vec3</code> is not the type, but just a typedef. glm::tvec3 is the type you are looking for:</p> <pre><code>typedef tvec3&lt;float, highp&gt; highp_vec3; // [...] typedef highp_vec3 vec3; </code></pre> <p>So by replacing <code>def qdump__glm__vec3(d, value):</code> with <code>def qdump__glm__tvec3(d, value):</code>, gdb will be able to find your function.</p> <p>To access the members themselves, for example the member <code>x</code>, use <code>value["x"]</code>. This way you can use <code>d.putValue</code> for a pleasing output.<br /> For showing the members themselves in an expandable way, I've used the example from the link you've provided.</p> <br /><br /><br /><h3>回答2:</h3><br /><p><strong>Update 2020</strong></p> <p>As of glm 0.9.9.7 (2020), it seems that the typedef changed :</p> <pre class="lang-cpp prettyprint-override"><code>typedef vec&lt;3, float, defaultp&gt; vec3; </code></pre> <p>Therefore, the debug-helper should be updated to :</p> <pre class="lang-py prettyprint-override"><code>from dumper import * #debugging helper for glm::(b|i|u|d)?vec[2-4] def qdump__glm__vec(d, value): dim = value.type.templateArgument(0) d.putNumChild(dim) keys = ["x", "y", "z", "w"][0:dim] d.putValue("[" + ", ".join([str(value[key].value()) for key in keys]) + "]") if d.isExpanded(): with Children(d): for key in keys: d.putSubItem(key, value[key]) </code></pre> <p>This yields to the same result as before.</p> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/34354573/how-to-write-a-debugging-helper-for-qtcreator</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/c-0" hreflang="zh-hans">c++</a></div> <div class="field--item"><a href="/tag/debugging" hreflang="zh-hans">debugging</a></div> <div class="field--item"><a href="/tag/gdb" hreflang="zh-hans">gdb</a></div> <div class="field--item"><a href="/tag/qt-creator" hreflang="zh-hans">qt-creator</a></div> <div class="field--item"><a href="/tag/glm-math" hreflang="zh-hans">glm-math</a></div> </div> </div> Sun, 23 Aug 2020 00:02:06 +0000 China☆狼群 3782357 at http://www.e-learn.cn