I am dealing with geometry shaders following OpenGL - Geometry shaders. My OPENGL version is 2.1, GLSL version is 1.20, OS X. When vertex shader and frag shader are attached to my program, it works and four red points is displayed. When the geometry shader is attached, the program is compiled successfully. However, no point is displayed. The following are my code:
vertex shader:
#version 120
#extension GL_EXT_geometry_shader4 : enable
attribute vec2 position;
void main()
{
gl_Position = vec4(position, 0.0, 1.0);
}
frag shader:
#version 120
#extension GL_EXT_geometry_shader4 : enable
void main()
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
geom shader:
#version 120
#extension GL_EXT_geometry_shader4 : enable
void main()
{
for(int i = 0; i < gl_VerticesIn; i++)
{
gl_Position = gl_PositionIn[i] + vec4(-0.1, 0.0, 0.0, 0.0);
EmitVertex();
}
EndPrimitive();
}
main.cpp
#include <GL/glew.h>
#include “textfile.h”
#include <glut/glut.h>
#include <iostream>
using namespace std;
GLuint vShader,fShader, gShader;//顶点着色器对象
//顶点位置数组
float positionData[] = {
// Coordinates Color Sides
-0.45f, 0.45f, 1.0f, 0.0f, 0.0f, 4.0f,
0.45f, 0.45f, 0.0f, 1.0f, 0.0f, 8.0f,
0.45f, -0.45f, 0.0f, 0.0f, 1.0f, 16.0f,
-0.45f, -0.45f, 1.0f, 1.0f, 0.0f, 32.0f};
GLubyte elements[] = {0, 1, 1, 2, 2, 3, 3, 0};
GLuint vaoHandle;//vertex array object
GLuint programHandle;
void initShader(const char *VShaderFile,const char *FShaderFile, const char *GShaerFile) {
//1、查看GLSL和OpenGL的版本
const GLubyte *renderer = glGetString( GL_RENDERER );
const GLubyte *vendor = glGetString( GL_VENDOR );
const GLubyte *version = glGetString( GL_VERSION );
const GLubyte *glslVersion =
glGetString( GL_SHADING_LANGUAGE_VERSION );
GLint major, minor;
glGetIntegerv(GL_MAJOR_VERSION, &major);
glGetIntegerv(GL_MINOR_VERSION, &minor);
cout << “GL Vendor :” << vendor << endl;
cout << "GL Renderer : " << renderer << endl;
cout << "GL Version (string) : " << version << endl;
cout << "GL Version (integer) : " << major << “.” << minor << endl;
cout << "GLSL Version : " << glslVersion << endl;
//2、编译着色器
//创建着色器对象:顶点着色器
vShader = glCreateShader(GL_VERTEX_SHADER);
//错误检测
if (0 == vShader) {
cerr << “ERROR : Create vertex shader failed” << endl;
exit(1);
}
//把着色器源代码和着色器对象相关联
const GLchar *vShaderCode = textFileRead(VShaderFile);
const GLchar *vCodeArray[1] = {vShaderCode};
glShaderSource(vShader,1,vCodeArray,NULL);
//编译着色器对象
glCompileShader(vShader);
//检查编译是否成功
GLint compileResult;
glGetShaderiv(vShader,GL_COMPILE_STATUS,&compileResult);
if (GL_FALSE == compileResult) {
GLint logLen;
//得到编译日志长度
glGetShaderiv(vShader,GL_INFO_LOG_LENGTH,&logLen);
if (logLen > 0) {
char *log = (char *)malloc(logLen);
GLsizei written;
//得到日志信息并输出
glGetShaderInfoLog(vShader,logLen,&written,log);
cerr << "vertex shader compile log : " << endl;
cerr << log << endl;
free(log);//释放空间
}
}
//创建着色器对象:几何着色器
gShader = glCreateShader(GL_GEOMETRY_SHADER);
//错误检测
if (0 == gShader) {
cerr << “ERROR : Create geometry shader failed” << endl;
exit(1);
}
//把着色器源代码和着色器对象相关联
const GLchar *gShaderCode = textFileRead(GShaerFile);
const GLchar *gCodeArray[1] = {gShaderCode};
glShaderSource(gShader,1,gCodeArray,NULL);
//编译着色器对象
glCompileShader(gShader);
//检查编译是否成功
glGetShaderiv(gShader,GL_COMPILE_STATUS,&compileResult);
if (GL_FALSE == compileResult) {
GLint logLen;
//得到编译日志长度
glGetShaderiv(gShader,GL_INFO_LOG_LENGTH,&logLen);
if (logLen > 0) {
char *log = (char *)malloc(logLen);
GLsizei written;
//得到日志信息并输出
glGetShaderInfoLog(gShader,logLen,&written,log);
cerr << "geometry shader compile log : " << endl;
cerr << log << endl;
free(log);//释放空间
}
}
//创建着色器对象:片断着色器
fShader = glCreateShader(GL_FRAGMENT_SHADER);
//错误检测
if (0 == fShader) {
cerr << “ERROR : Create fragment shader failed” << endl;
exit(1);
}
//把着色器源代码和着色器对象相关联
const GLchar *fShaderCode = textFileRead(FShaderFile);
const GLchar *fCodeArray[1] = {fShaderCode};
glShaderSource(fShader,1,fCodeArray,NULL);
//编译着色器对象
glCompileShader(fShader);
//检查编译是否成功
glGetShaderiv(fShader,GL_COMPILE_STATUS,&compileResult);
if (GL_FALSE == compileResult) {
GLint logLen;
//得到编译日志长度
glGetShaderiv(fShader,GL_INFO_LOG_LENGTH,&logLen);
if (logLen > 0) {
char *log = (char *)malloc(logLen);
GLsizei written;
//得到日志信息并输出
glGetShaderInfoLog(fShader,logLen,&written,log);
cerr << "fragment shader compile log : " << endl;
cerr << log << endl;
free(log);//释放空间
}
}
//3、链接着色器对象
//创建着色器程序
programHandle = glCreateProgram();
if (!programHandle) {
cerr << “ERROR : create program failed” << endl;
exit(1);
}
//glProgramParameteriEXT(programHandle, GL_GEOMETRY_VERTICES_OUT, GL_POINTS);
glProgramParameteriEXT(programHandle, GL_GEOMETRY_INPUT_TYPE, GL_POINTS);
glProgramParameteriEXT(programHandle, GL_GEOMETRY_OUTPUT_TYPE, GL_LINE_STRIP);
glProgramParameteriEXT(programHandle, GL_GEOMETRY_VERTICES_OUT_EXT, 2);
//将着色器程序链接到所创建的程序中
glAttachShader(programHandle,vShader);
glAttachShader(programHandle,gShader);
glAttachShader(programHandle,fShader);
//将这些对象链接成一个可执行程序
glLinkProgram(programHandle);
//查询链接的结果
GLint linkStatus;
glGetProgramiv(programHandle,GL_LINK_STATUS,&linkStatus);
if (GL_FALSE == linkStatus) {
cerr << “ERROR : link shader program failed” << endl;
GLint logLen;
glGetProgramiv(programHandle, GL_INFO_LOG_LENGTH, &logLen);
if (logLen > 0) {
char *log = (char *)malloc(logLen);
GLsizei written;
glGetProgramInfoLog(programHandle, logLen, &written,log);
cerr << "Program log : " << endl;
cerr << log << endl;
}
}
else {//链接成功,在OpenGL管线中使用渲染程序
glUseProgram(programHandle);
}
}
void initVBO() {
// Create and populate the buffer objects
GLuint vboHandles;
glGenBuffers(1, &vboHandles);
//绑定VBO以供使用
glBindBuffer(GL_ARRAY_BUFFER, vboHandles);
//加载数据到VBO
glBufferData(GL_ARRAY_BUFFER, sizeof(positionData), positionData, GL_STATIC_DRAW);
glGenVertexArraysAPPLE(1, &vaoHandle);
glBindVertexArrayAPPLE(vaoHandle);
GLuint locAttrib = glGetAttribLocation(programHandle, “position”);
glEnableVertexAttribArray(locAttrib);//顶点坐标
glVertexAttribPointer(locAttrib, 2, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), 0);
GLuint colAttrib = glGetAttribLocation(programHandle, “color”);
glEnableVertexAttribArray(colAttrib);//顶点颜色
glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(2 * sizeof(float)));
GLuint sidesAttrib = glGetAttribLocation(programHandle, “sides”);
glEnableVertexAttribArray(sidesAttrib);//顶点颜色
glVertexAttribPointer(sidesAttrib, 1, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(5 * sizeof(float)));
}
void init() {
//初始化glew扩展库
GLenum err = glewInit();
if( GLEW_OK != err )
{
cout <<"Error initializing GLEW: " << glewGetErrorString(err) << endl;
}
initShader(“basic.vert”,“basic.frag”, “basic.geom”);
initVBO();
glClearColor(0.0, 0.0, 0.0, 0.0);
//glShadeModel(GL_SMOOTH);
}
void display() {
glClear(GL_COLOR_BUFFER_BIT);
//使用VAO、VBO绘制
//glBindVertexArrayAPPLE(vaoHandle);
//glDrawArrays(GL_TRIANGLES, 0, 6);
glDrawArrays(GL_POINTS, 0, 4);
glBindVertexArrayAPPLE(0);
glutSwapBuffers();
}
void keyboard(unsigned char key,int x,int y) {
switch(key) {
case 27:
glDeleteShader(vShader);
glUseProgram(0);
break;
}
}
int main(int argc,char** argv) {
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(600,600);
glutInitWindowPosition(100,100);
glutCreateWindow(“GLSL Test : Draw a triangle”);
init();
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}