행렬을 사용하여 OpenGL 4로 삼각형을 회전하려고하는데 삼각형이 중간에 있으면 반대 방향으로 보입니다. 분명히 회전 방향이 아니므로 어딘가에 깊이 버퍼가 잘못되어 있어야합니다. 이 문제를 해결하려고 시도했지만 OpenGL 4에서 회전의 예를 찾지 못했으며 감가 상각 된 기능을 사용하는 경우 만 있습니다. 내 코드는 다음과 같습니다.
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <stdio.h>
#include <math.h>
#include <iostream>
#include "maths_funcs.h"
#include "maths_funcs.cpp"
const char* vertex_shader =
"#version 400\n"
"layout(location = 0) in vec3 vertex_position;"
"layout(location = 1) in vec3 vertex_colour;"
"uniform mat4 pmatrix;"
"uniform mat4 rmatrix;"
"uniform mat4 smatrix;"
"out vec3 colour;"
"void main () {"
" colour = vertex_colour;"
" gl_Position = smatrix * rmatrix * vec4 (vertex_position, 1.0);"
"}";
const char* fragment_shader =
"#version 400\n"
"in vec3 colour;"
"out vec4 frag_colour;"
"void main () {"
" frag_colour = vec4 (colour, 1.0);"
"}";
float angle = 0.0f;
int main () {
// start GL context and O/S window using the GLFW helper library
if (!glfwInit ()) {
fprintf (stderr, "ERROR: could not start GLFW3\n");
return 1;
}
GLFWwindow* window = glfwCreateWindow (640, 480, "Triangle Rotation test", NULL, NULL);
if (!window) {
fprintf (stderr, "ERROR: could not open window with GLFW3\n");
glfwTerminate();
return 1;
}
glfwMakeContextCurrent (window);
// start GLEW extension handler
glewExperimental = GL_TRUE;
glewInit ();
// get version info
const GLubyte* renderer = glGetString (GL_RENDERER); // get renderer string
const GLubyte* version = glGetString (GL_VERSION); // version as a string
printf ("Renderer: %s\n", renderer);
printf ("OpenGL version supported %s\n", version);
// tell GL to only draw onto a pixel if the shape is closer to the viewer
glEnable (GL_DEPTH_TEST); // enable depth-testing
glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer"
float points[] = {
0.0f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f
};
float colours[] = {
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f
};
float pmatrix[] = {
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
};
float rmatrix[] = {
cos(10), 0.0f, sin(10), 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
-sin(10), 0.0f, cos(10), 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
};
float smatrix[] = {
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, cos(10), sin(10), 0.0f,
0.0f, -sin(10), cos(10), 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
};
GLuint vbo = 0;
glGenBuffers (1, &vbo);
glBindBuffer (GL_ARRAY_BUFFER, vbo);
glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (float), points, GL_STATIC_DRAW);
unsigned int colours_vbo = 0;
glGenBuffers (1, &colours_vbo);
glBindBuffer (GL_ARRAY_BUFFER, colours_vbo);
glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (float), colours, GL_STATIC_DRAW);
GLuint vao = 0;
glGenVertexArrays (1, &vao);
glBindVertexArray (vao);
glEnableVertexAttribArray (0);
glBindBuffer (GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer (GL_ARRAY_BUFFER, colours_vbo);
glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
GLuint vs = glCreateShader (GL_VERTEX_SHADER);
glShaderSource (vs, 1, &vertex_shader, NULL);
glCompileShader (vs);
GLuint fs = glCreateShader (GL_FRAGMENT_SHADER);
glShaderSource (fs, 1, &fragment_shader, NULL);
glCompileShader (fs);
GLuint shader_programme = glCreateProgram ();
glAttachShader (shader_programme, fs);
glAttachShader (shader_programme, vs);
glLinkProgram (shader_programme);
int pmatrix_location = glGetUniformLocation (shader_programme, "pmatrix");
int rmatrix_location = glGetUniformLocation (shader_programme, "rmatrix");
int smatrix_location = glGetUniformLocation (shader_programme, "smatrix");
while (!glfwWindowShouldClose (window)) {
// wipe the drawing surface clear
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram (shader_programme);
rmatrix[0] = cos(angle);
rmatrix[2] = sin(angle);
rmatrix[8] = -sin(angle);
rmatrix[10] = cos(angle);
smatrix[5] = cos(angle);
smatrix[6] = sin(angle);
smatrix[9] = -sin(angle);
smatrix[10] = cos(angle);
glUniformMatrix4fv (pmatrix_location, 1, GL_FALSE, pmatrix);
glUniformMatrix4fv (rmatrix_location, 1, GL_FALSE, rmatrix);
glUniformMatrix4fv (smatrix_location, 1, GL_FALSE, smatrix);
glBindVertexArray (vao);
// draw points 0-3 from the currently bound VAO with current in-use shader
glDrawArrays (GL_TRIANGLES, 0, 3);
// update other events like input handling
glfwPollEvents ();
// put the stuff we've been drawing onto the display
glfwSwapBuffers (window);
angle+=0.01f;
if (angle >= 3.14f) {
angle = -3.14f;
}
}
// close GL context and any other GLFW resources
glfwTerminate();
return 0;
}
투영 행렬을 사용하지 않기 때문에 정점 셰이더에서 z 좌표를 반전해야합니다. 이 줄을 변경하십시오.
gl_Position = smatrix * rmatrix * vec4 (vertex_position, 1.0);
다음과 같이 :
vec4 eyePos = smatrix * rmatrix * vec4 (vertex_position, 1.0);
gl_Position = vec4(eyePos.xy, -eyePos.z, eyePos.w);
gl_Position
값에 의한 분할 후 클립 좌표이다 w
NDC 결과 (디바이스 좌표를 규격화). 세계 좌표계는 일반적으로, Z가 축 화면 지적으로 오른손 좌표계에서 규정하고 있지만, NDC가있다 왼손잡이 좌표계의 z는 축 가리키는, 로 화면.
일반적인 투영 변환은 화면 밖에서 화면으로 z 좌표를 뒤집는 작업을 처리합니다. 그러나 투영 변환을 사용하지 않는 경우 z 좌표를 직접 뒤집어 야합니다.
또한 실제로 깊이 버퍼가 있는지 다시 확인하고 싶을 수 있습니다. 아마 전에 이것을 추가하십시오 glfwCreateWindow()
:
glfwWindowHint(GLFW_DEPTH_BITS, 24);
GLFW 문서에서 찾을 수있는 내용에 따르면 이것이 아마도 기본값 일 것입니다. 그러나 그것을 명시 적으로 지정하는 것은 나쁠 수 없습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다