I’m making a simple geometry program, which keep emitting triangles. I can get at most 42 triangles from a single Geometry Shader execution.
I understand that maximum vertices can be emitted is 256 and maximum components is 1024. I think the limitation in my case it probably the component. If 8 components are used for each vertex (4 for position and 4 for color), then I would only be able to get 1024/8 = 128 vertices, which is roughly 42 triangles.
However, is it possible to just use four components for a vertex? i.e a vertex will only have a position attribute but no color? I tried that in GS, I only set gl_Position varying variable. However, I still get 42 triangles.
So, does anyone know why, or does anyone know how to tell GS to only emit 4-component vertices not 8 component vertices
Here’s a screen shot
Here’s my shaders
Vertex
void main(){
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_FrontColor = vec4(1, 1, 0, 1); // change vertex color to yellow
}
Geometry
#version 120
#extension GL_EXT_geometry_shader4 : enable
void main(){
float centerX, centerY;
for(int x = 0; x < 10; x++){
for(int y = 0; y < 10; y++){
centerX = -0.9 + 0.2 * x;
centerY = 0.9 - 0.2 * y;
gl_Position = vec4(centerX - 0.1, centerY - 0.1, 0.0, 1);
EmitVertex();
gl_Position = vec4(centerX, centerY + 0.1, 0.0, 1);
EmitVertex();
gl_Position = vec4(centerX + 0.1, centerY - 0.1, 0.0, 1);
EmitVertex();
EndPrimitive();
}
}
}
Fragment
void main(){
gl_FragColor = vec4(1, 1, 0, 1);
}
OpenGL setup
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <GL/glut.h>
// Vertex and fragment shader handle
GLuint vs, gs, fs;
// GLSL program handle
GLuint program;
// read contents of a text file
char * readFile(const char * filePath){
char * text;
long chars;
FILE * fp = fopen(filePath, "r");
fseek(fp, 0L, SEEK_END); // Position to end of file
chars = ftell(fp);
rewind(fp);
text = (char*)calloc(chars, sizeof(char));
fread(text, sizeof(char), chars, fp);
fclose(fp);
printf("%s
", text);
return text;
}
// This function calculates FPS
void fps(){
static int fps = 0;
static float previousTime = 0.0f;
static char strFPS[20] = {0};
float currentTime = (glutGet(GLUT_ELAPSED_TIME) * 0.001f);
++fps; // Increment the FPS counter
if( currentTime - previousTime > 1.0f ){
previousTime = currentTime;
sprintf(strFPS, "FPS: %d", fps);
glutSetWindowTitle(strFPS);
fps = 0.0f;
}
}
// Initialise GLSL
void initGLSL(){
const char * src; // shader source code
char * glVersionString;
GLuint compileResult;
char infoLog[200];
glVersionString = (char *)glGetString(GL_VERSION);
printf("OpenGL Version: %s
", glVersionString);
glVersionString = (char *)glGetString(GL_SHADING_LANGUAGE_VERSION);
printf("GLSL Version: %s
", glVersionString);
vs = glCreateShader(GL_VERTEX_SHADER); // create vertex shader object
src = readFile("vertex.glsl"); // load src from a file
glShaderSource(vs, 1, &src, NULL); // attach source to vertex shader
free(src);
gs = glCreateShader(GL_GEOMETRY_SHADER_EXT); // create geometry shader object
src = readFile("geometry.glsl"); // load src from a file
glShaderSource(gs, 1, &src, NULL); // attach source to geometry shader
free(src);
fs = glCreateShader(GL_FRAGMENT_SHADER); // create fragment shader object
src = readFile("fragment.glsl"); // load src from a file
glShaderSource(fs, 1, &src, NULL); // attach source to fragment shader
free(src);
// After shaders are loaded, they have to be compiled
glCompileShader(vs); // compile vertex shader
// Check if there are any compile errors
glGetShaderiv(vs, GL_COMPILE_STATUS, &compileResult);
if(compileResult == GL_TRUE){
printf("vertex shader happy
");
}else{
glGetShaderInfoLog(vs, 200, NULL, infoLog);
printf("%s", infoLog);
}
glCompileShader(gs); // compile geometry shader
// Check if there are any compile errors
glGetShaderiv(gs, GL_COMPILE_STATUS, &compileResult);
if(compileResult == GL_TRUE){
printf("geometry shader happy
");
}else{
glGetShaderInfoLog(gs, 200, NULL, infoLog);
printf("%s", infoLog);
}
glCompileShader(fs); // compile fragment shader
glGetShaderiv(fs, GL_COMPILE_STATUS, &compileResult);
if(compileResult == GL_TRUE){
printf("fragment shader happy
");
}else{
glGetShaderInfoLog(fs, 200, NULL, infoLog);
printf("%s", infoLog);
}
program = glCreateProgram(); // Create GLSL program object
glAttachShader(program, vs); // Attach vertex shader
glAttachShader(program, gs); // Attach geometry shader
glAttachShader(program, fs); // Attach fragment shader
// Geometry Shader input and output type
glProgramParameteriEXT(program, GL_GEOMETRY_INPUT_TYPE_EXT, GL_TRIANGLES);
glProgramParameteriEXT(program, GL_GEOMETRY_OUTPUT_TYPE_EXT, GL_TRIANGLE_STRIP);
glProgramParameteriEXT(program, GL_GEOMETRY_VERTICES_OUT_EXT, 1024);
glLinkProgram(program); // program must be linked
glGetProgramiv(program, GL_LINK_STATUS, &compileResult);
if(compileResult == GL_TRUE){
printf("Program linking successful
");
}else{
printf("Program linking failed
");
}
glUseProgram(program); // finally, tell OpenGL to use this GLSL program
}
void display(){
float centerX, centerY;
int x, y;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glNormal3f(0, 0, 1);
// The color has been set to red, see vertex program, which changes the color to yellow
glColor3f(1, 0, 0);
glBegin(GL_TRIANGLES);
glVertex3f(1, 1, 1);
glVertex3f(1, 1, 1);
glVertex3f(1, 1, 1);
glEnd();
glutSwapBuffers();
fps();
}
void reshape(int w, int h) {
//Set up an orthographic view of the objects
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-15, 15, -15, 15, 1, 1);
glMatrixMode(GL_MODELVIEW);
}
// render as fast as possible
void idle(){
glutPostRedisplay();
}
int main(int argc, char **argv){
//glut initialisation
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glEnable(GL_DEPTH_TEST); // Enable hidden surface removal
// create window
glutInitWindowSize(500, 500);
glutInitWindowPosition(0, 0);
glutCreateWindow("Hello GLSL");
// Initialise GLUT
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
glewInit(); // must initialise GLEW context before creating shader
initGLSL(); //
//Background colour set to black
glClearColor(0.0, 0.0, 0.0, 1.0);
glutMainLoop();
// clean up, all shaders and GLSL program object must be manually deleted
glDeleteShader(vs);
glDeleteShader(fs);
glDeleteProgram(program);
}