PDA

View Full Version : Only 42 triangles can be emitted by Geometry Shader



Ren
10-12-2007, 11:23 PM
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
http://www.lhviolinist.com/images/42_tri.png

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\n", 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\n", glVersionString);

glVersionString = (char *)glGetString(GL_SHADING_LANGUAGE_VERSION);
printf("GLSL Version: %s\n", glVersionString);

vs = glCreateShader(GL_VERTEX_SHADER); // create vertex shader object

src = readFile("vertex.glsl"); // load src from a file

glShaderSource(vs, 1, &amp;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, &amp;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, &amp;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, &amp;compileResult);
if(compileResult == GL_TRUE){
printf("vertex shader happy\n");
}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, &amp;compileResult);
if(compileResult == GL_TRUE){
printf("geometry shader happy\n");
}else{
glGetShaderInfoLog(gs, 200, NULL, infoLog);
printf("%s", infoLog);
}

glCompileShader(fs); // compile fragment shader
glGetShaderiv(fs, GL_COMPILE_STATUS, &amp;compileResult);
if(compileResult == GL_TRUE){
printf("fragment shader happy\n");
}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, &amp;compileResult);
if(compileResult == GL_TRUE){
printf("Program linking successful\n");
}else{
printf("Program linking failed\n");
}

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(&amp;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);

}

RGHP
10-13-2007, 07:15 AM
Hello
The model of your target? maybe a bug in the Linu driver(you are using ubuntu right?).

RGHP
10-13-2007, 07:18 AM
By 'target' I mean your card. Sorry, but in spanish(my native language) card is 'tarjeta' :) .

Ren
10-13-2007, 08:42 PM
I've tried this on Windows Vista, still get only 42 triangles