절차 적으로 생성 된 메쉬를 렌더링 할 때 몇 가지 문제가 있습니다. 높은 폴리 카운트 메쉬를 렌더링 할 때 (실제로는 그렇게 많지는 않음) 일부 실제적으로 이상한 아티팩트가 있습니다. 문제를 격리 할 수 있었지만 왜 이런 일이 일어나는지 알 수 없습니다. 낮은 폴리 메쉬를 생성 할 때 문제가 발생하지 않습니다.OpenGL을 사용하여 고 폴리 프로 시저 메쉬를 렌더링하는 아티클
작은 데모를 만들었으므로 소스를 다운로드 할 수 있습니다. (아래 참조)
이러한 아티팩트는 대략 90 개의 삼각형 (120 개의 꼭지점과 270 개의 인덱스)이 나타날 때부터 시작됩니다. 데모에 나타나는 것을 보려면 initMesh를 150 개의 링과 150 개의 섹터로 설정하십시오.
일주일 내내이 일을하고 있으며 왜 이런 일이 일어나고 있는지 이유는 없습니다. 그것은 무엇 일 수 있는가? 여기
bool createGLWindow()
{
_window = SDL_CreateWindow(
"TestMesh",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
1024,
768,
SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
if(_window == NULL)
{
LOG("Window could not be created! SDL_Error: " << SDL_GetError());
return false;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
_glContext = SDL_GL_CreateContext(_window);
if (!_glContext)
{
LOG("Could not create context:" << SDL_GetError());
return false;
}
glewExperimental = GL_TRUE;
GLenum glewInitStatus = glewInit();
if(glewInitStatus != GLEW_OK)
{
LOG("Error" << glewGetErrorString(glewInitStatus))
return false;
}
return true;
}
렌더링 : OpenGL을 초기화하는 코드 여기
void initMesh(float radius, int rings, int sectors)
{
float piOver2 = M_PI * 0.5f;
vector<Vertex> vertices;
vector<unsigned int> indices;
float const R = 1.0f/(float)(rings);
float const S = 1.0f/(float)(sectors);
unsigned int r, s;
for(r = 0; r < rings + 1; r++)
{
for(s = 0; s < sectors + 1; s++)
{
float y = sin(piOver2 * r * R);
float x = cos(2.0 * M_PI * s * S) * sin(piOver2 + piOver2 * r * R);
float z = sin(2.0 * M_PI * s * S) * sin(piOver2 + piOver2 * r * R);
vec3 position = vec3(x, y, z) * radius;
vec3 normal = normalize(vec3(x, y, z)) * radius;
vec2 texCoord = vec2(s * R, r * R) * radius;
vertices.push_back(Vertex(position, texCoord, normal));
}
}
for(r = 0; r < rings; r++)
{
for(s = 0; s < sectors; s++)
{
int a = r * (sectors + 1) + s;
int b = (r + 1) * (sectors + 1) + s;
int c = (r + 1) * (sectors + 1) + (s + 1);
int d = r * (sectors + 1) + (s + 1);
indices.push_back(a);
indices.push_back(b);
indices.push_back(c);
indices.push_back(c);
indices.push_back(d);
indices.push_back(a);
}
}
_mesh = Mesh::New(vertices, indices);
}
됩니다 : 여기
#include "Mesh.h"
Mesh::Mesh()
{
_vao = 0;
_verticesVbo = 0;
_texCoordsVbo = 0;
_normalsVbo = 0;
_indicesVbo = 0;
}
Mesh::~Mesh()
{
glDeleteBuffers(1, &_verticesVbo);
glDeleteBuffers(1, &_texCoordsVbo);
glDeleteBuffers(1, &_normalsVbo);
glDeleteBuffers(1, &_indicesVbo);
glDeleteVertexArrays(1, &_vao);
}
Mesh* Mesh::New(vector<Vertex> &vertices, vector<GLuint> &indices)
{
Mesh* mesh = new Mesh();
mesh->AddVertices(vertices, indices);
return mesh;
}
void Mesh::AddVertices(vector<Vertex> &vertices, vector<GLuint> &indices)
{
_vertices = vertices;
_indices = indices;
GLuint verticesSize = vertices.size() * 3 * sizeof(GLfloat);
GLuint texCoordsSize = vertices.size() * 2 * sizeof(GLfloat);
GLuint normalsSize = vertices.size() * 3 * sizeof(GLfloat);
_indicesSize = indices.size() * sizeof(GLuint);
GLfloat* vertexBuffer = new GLfloat[vertices.size() * 3];
GLfloat* texCoordBuffer = new GLfloat[vertices.size() * 2];
GLfloat* normalBuffer = new GLfloat[vertices.size() * 3];
CreateBuffers(vertices, vertexBuffer, texCoordBuffer, normalBuffer);
glGenVertexArrays(1, &_vao);
glBindVertexArray(_vao);
glGenBuffers(1, &_verticesVbo);
glBindBuffer(GL_ARRAY_BUFFER, _verticesVbo);
glBufferData(GL_ARRAY_BUFFER, verticesSize, vertexBuffer, GL_STATIC_DRAW);
glGenBuffers(1, &_texCoordsVbo);
glBindBuffer(GL_ARRAY_BUFFER, _texCoordsVbo);
glBufferData(GL_ARRAY_BUFFER, texCoordsSize, texCoordBuffer, GL_STATIC_DRAW);
glGenBuffers(1, &_normalsVbo);
glBindBuffer(GL_ARRAY_BUFFER, _normalsVbo);
glBufferData(GL_ARRAY_BUFFER, normalsSize, normalBuffer, GL_STATIC_DRAW);
glGenBuffers(1, &_indicesVbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indicesVbo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, _indicesSize, &indices[0], GL_STATIC_DRAW);
delete[] vertexBuffer;
delete[] texCoordBuffer;
delete[] normalBuffer;
}
void Mesh::CreateBuffers(vector<Vertex> &vertices,
GLfloat* &vertexBuffer,
GLfloat* &texCoordBuffer,
GLfloat* &normalBuffer)
{
vector<Vertex>::iterator i;
unsigned int vIndex = 0;
unsigned int tIndex = 0;
unsigned int nIndex = 0;
for (i = vertices.begin(); i != vertices.end(); ++i)
{
Vertex vertex = *i;
GLfloat x = vertex.GetPosition().x;
GLfloat y = vertex.GetPosition().y;
GLfloat z = vertex.GetPosition().z;
GLfloat u = vertex.GetTexCoord().x;
GLfloat v = vertex.GetTexCoord().y;
GLfloat r0 = vertex.GetNormal().x;
GLfloat s0 = vertex.GetNormal().y;
GLfloat t0 = vertex.GetNormal().z;
vertexBuffer[vIndex++] = x;
vertexBuffer[vIndex++] = y;
vertexBuffer[vIndex++] = z;
texCoordBuffer[tIndex++] = u;
texCoordBuffer[tIndex++] = v;
normalBuffer[nIndex++] = r0;
normalBuffer[nIndex++] = s0;
normalBuffer[nIndex++] = t0;
}
}
void Mesh::Render()
{
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, _verticesVbo);
glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, _texCoordsVbo);
glVertexAttribPointer((GLuint)1, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, _normalsVbo);
glVertexAttribPointer((GLuint)2, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indicesVbo);
glDrawElements(GL_TRIANGLES, _indicesSize, GL_UNSIGNED_INT, 0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
}
메쉬를 생성하는 코드 : 여기
내 메쉬 클래스 기능 : ,831,526,623,210그리고 이러한 버텍스 셰이더를
#version 330
in vec3 inPosition;
in vec2 inTexCoord;
in vec3 inNormal;
uniform mat4 mvp;
out vec3 fragPosition;
out vec2 fragTexCoord;
out vec3 fragNormal;
void main()
{
gl_Position = mvp * vec4(inPosition, 1.0);
fragTexCoord = inTexCoord;
fragPosition = inPosition;
fragNormal = inNormal;
}
와 단편 쉐이더 같습니다
#version 330
uniform vec4 color;
in vec3 fragPosition;
in vec2 fragTexCoord;
in vec3 fragNormal;
out vec4 fragColor;
void main(void)
{
vec3 lightPos = vec3(1.0, 1.0, 1.0);
fragColor = max(dot(lightPos, fragNormal), 0.0) * 0.8 * color + color * 0.1;
}
낮은 폴리 렌더링 결과, 렌더링시
결과를 하이 폴리 :
그리고 여기 데모의 소스를 다운로드 할 수 있습니다 : 인덱스 버퍼 크기에 사용되는 단위의 불일치가있다