J'essaye d'écrire un shader de géométrie qui prend une seule position vec4, et crée un triangle. Le programme lie correctement, mais quand l'appel de tirage arrive, rien n'est affiché sur l'écran. J'ai une version de travail où je donne les sommets à OpenGL après avoir moi-même calculé le triangle, mais j'espère que le shader fonctionnera pour que le triangle (et éventuellement d'autres formes) puisse être créé sur le gpu à la place. Voici mon code:OpenGL Geomentry Shader triangle ne dessine pas sans erreurs
void TriSprite::v_InitShader(void)
{
if(_shaderProgram != NULL) return;
//=====Vertex Shaders=====
//This is used when only colors, not textures are used to render
//a pirmitive
static const GLchar* _vertexShaderSource[] =
{
"#version 430 core \n"
" \n"
"layout (location = 0) in vec4 position; \n"
"layout (location = 1) in vec4 color; \n"
"layout (location = 2) in float width; \n"
"layout (location = 3) in float height; \n"
"uniform mat4 transform_mat; \n"
" \n"
"out vec4 vs_color; \n"
"out vec4 vs_dimnsions; \n"
" \n"
"void main(void) \n"
"{ \n"
//=====Top=====
" gl_Position = transform_mat * position; \n"
" vs_color = color; \n"
" vs_dimnsions = vec4(width, height, 0.0, 0.0); \n"
"} \n"
};
//=====Geomtry Shader=====
static const GLchar* _geometryShaderSource[] =
{
"#version 430 core \n"
" \n"
"layout(points) in; \n"
"layout(triangle_strip, max_vertices = 2) out; \n"
" \n"
"in vec4 vs_color[1]; \n"
"in vec4 vs_dimnsions[1]; \n"
" \n"
"out vec4 gs_color; \n"
" \n"
"void main() \n"
"{ \n"
//Bottom Right
" gl_Position = gl_in[0].gl_Position + vec4(vs_dimnsions[0].x, -vs_dimnsions[0].y, 0, 0); \n"
" EmitVertex(); \n"
//Top
" gl_Position = gl_in[0].gl_Position + vec4(0.0, vs_dimnsions[0].y, 0.0, 0.0); \n"
" EmitVertex(); \n"
//Bottom Left
" gl_Position = gl_in[0].gl_Position + vec4(-vs_dimnsions[0].x, -vs_dimnsions[0].y, 0.0, 0.0); \n"
" EmitVertex(); \n"
" \n"
" EndPrimitive(); \n"
" gs_color = vs_color[0]; \n"
"} \n"
};
//=====Fragment Shaders=====
//This is used when only colors, not textures are used to render
//a pirmitive
static const GLchar* _fragmentShaderSource[] =
{
"#version 430 core \n"
" \n"
"in vec4 gs_color; \n"
"out vec4 color; \n"
" \n"
"void main(void) \n"
"{ \n"
" color = gs_color; \n"
"} \n"
};
//=====Compile Shaders=====
GLuint vertextShaderProgram;
GLuint geometryShaderProgram;
GLuint fragmentShaderProgram;
vertextShaderProgram = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertextShaderProgram, 1, _vertexShaderSource, NULL);
glCompileShader(vertextShaderProgram);
geometryShaderProgram = glCreateShader(GL_GEOMETRY_SHADER);
glShaderSource(geometryShaderProgram, 1, _geometryShaderSource, NULL);
glCompileShader(geometryShaderProgram);
fragmentShaderProgram = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShaderProgram, 1, _fragmentShaderSource, NULL);
glCompileShader(fragmentShaderProgram);
_shaderProgram = glCreateProgram();
glAttachShader(_shaderProgram, vertextShaderProgram);
glAttachShader(_shaderProgram, geometryShaderProgram);
glAttachShader(_shaderProgram, fragmentShaderProgram);
glLinkProgram(_shaderProgram);
GLint isLinked = 0;
glGetProgramiv(_shaderProgram, GL_LINK_STATUS, &isLinked);
//=====Error Checking=====
if(isLinked == GL_FALSE)
{
GLint maxLength = 0;
glGetProgramiv(_shaderProgram, GL_INFO_LOG_LENGTH, &maxLength);
//The maxLength includes the NULL character
std::vector<GLchar> infoLog(maxLength);
glGetProgramInfoLog(_shaderProgram, maxLength, &maxLength, &infoLog[0]);
for(auto i = infoLog.begin(); i != infoLog.end(); ++i)
{
std::cout << *i ;
}
std::cout << "\n";
//The program is useless now. So delete it.
glDeleteProgram(_shaderProgram);
}
//=====Clean up=====
glDeleteShader(vertextShaderProgram);
glDeleteShader(geometryShaderProgram);
glDeleteShader(vertextShaderProgram);
}
Et le rendu appel:
void Renderer::AddToBatch(GLuint shader, Vec2& pos, U32 w, U32 h, Col& c)
{
if(_currentShader != shader)
{
Draw();
_currentShader = shader;
glUseProgram(_currentShader);
}
if(_currentBatchSize + 1 >= _maxBatchSize) { Draw(); }
_vertices.push_back(pos.GetX());
_vertices.push_back(pos.GetY());
_vertices.push_back(pos.GetZ());
_vertices.push_back(pos.GetW());
_xDimensions.push_back((F32)w);
_yDimensions.push_back((F32)h);
_colors.push_back(c.GetRed());
_colors.push_back(c.GetGreen());
_colors.push_back(c.GetBlue());
_colors.push_back(c.GetAlpha());
++_currentBatchSize;
}
void Renderer::Draw(void)
{
if(_currentBatchSize == 0) return;
GLuint buffers[4];
glGenBuffers(4, buffers);
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
glBufferData(GL_ARRAY_BUFFER, (sizeof(F32) * _vertices.size()), &_vertices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
glBufferData(GL_ARRAY_BUFFER, (sizeof(F32) * _colors.size()), &_colors[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER, buffers[2]);
glBufferData(GL_ARRAY_BUFFER, (sizeof(U32) * _xDimensions.size()), &_xDimensions[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER, buffers[3]);
glBufferData(GL_ARRAY_BUFFER, (sizeof(U32) * _yDimensions.size()), &_yDimensions[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, 0, NULL);
glDrawArrays(GL_TRIANGLES, 0, _currentBatchSize);
_currentBatchSize = 0;
}
Toute idée ou de l'aide sera grandement appréciée. Vous remarquerez que dans cet exemple, je charge directement le shader des sommets, et je les transforme simplement. Cette version fonctionne. Voici une version mise à jour basée sur les commentaires. Ce ne fonctionne toujours pas:
static const GLchar* _vertexShaderSource[] =
{
"#version 430 core \n"
" \n"
"layout (location = 0) in vec4 position; \n"
"layout (location = 1) in vec4 color; \n"
"layout (location = 2) in float width; \n"
"layout (location = 3) in float height; \n"
"uniform mat4 transform_mat; \n"
" \n"
"out vec4 vs_color; \n"
"out vec4 vs_dimensions; \n"
" \n"
"void main(void) \n"
"{ \n"
" gl_Position = transform_mat * position; \n"
" vs_color = color; \n"
" vs_dimensions = transform_mat * vec4(width, height, 0.0, 0.0); \n"
"} \n"
};
static const GLchar* _geometryShaderSource[] =
{
"#version 430 core \n"
" \n"
"layout(points) in; \n"
"layout(triangle_strip, max_vertices = 3) out; \n"
" \n"
"in vec4 vs_color[1]; \n"
"in vec4 vs_dimensions[1]; \n"
" \n"
"out vec4 gs_color; \n"
" \n"
"void main() \n"
"{ \n"
" gs_color = vs_color[0]; \n"
//Top
" gl_Position = gl_in[0].gl_Position + vec4(0.0, vs_dimensions[0].y, 0.0, 0.0); \n"
" EmitVertex(); \n"
//Bottom Right
" gl_Position = gl_in[0].gl_Position + vec4(vs_dimensions[0].x, -vs_dimensions[0].y, 0, 0); \n"
" EmitVertex(); \n"
//Bottom Left
" gl_Position = gl_in[0].gl_Position + vec4(-vs_dimensions[0].x, -vs_dimensions[0].y, 0.0, 0.0); \n"
" EmitVertex(); \n"
" \n"
" EndPrimitive(); \n"
"}
static const GLchar* _fragmentShaderSource[] =
{
"#version 430 core \n"
" \n"
"in vec4 gs_color; \n"
"out vec4 color; \n"
" \n"
"void main(void) \n"
"{ \n"
" color = gs_color; \n"
"} \n"
};
void Renderer::Draw(void)
{
if(_currentBatchSize == 0) return;
GLuint buffers[4];
glGenBuffers(4, buffers);
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
glBufferData(GL_ARRAY_BUFFER, (sizeof(F32) * _vertices.size()), &_vertices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
glBufferData(GL_ARRAY_BUFFER, (sizeof(F32) * _colors.size()), &_colors[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER, buffers[2]);
glBufferData(GL_ARRAY_BUFFER, (sizeof(U32) * _xDimensions.size()), &_xDimensions[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER, buffers[3]);
glBufferData(GL_ARRAY_BUFFER, (sizeof(U32) * _yDimensions.size()), &_yDimensions[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, 0, NULL);
glDrawArrays(GL_TRIANGLES, 0, _currentBatchSize);
_currentBatchSize = 0;
}
Quel type de matrice de transformation avez-vous? Est-ce une transformation de perspective? Êtes-vous sûr que la largeur et la hauteur sont passées correctement? –
Il s'agit d'une projection orthographique, et autant que je sache, ils sont passés. Les valeurs sont définies correctement dans l'appel AddToBatch. Pour ce test, w = 200 et h = 200. –