关闭

GLSL的简单范例

530人阅读 评论(0) 收藏 举报
这个例子在 windows下 采用 VC6.0 开发

首先确定你已经安装并可以正常使用 glew 和 glut 扩展库

第一步,创建顶点着色器和片元着色器文件 “minimal.vert” 和 “minimal.frag” 并导入到项目中。

//minimal.vert文件源码如下:

// 顶点着色器

void main()
{   // 下列三行运行结果一样

    gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;
//  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
//  gl_Position = ftransform();

}

这个顶点着色器非常简单,就是将顶点坐标做模型视点变换和投影变化,得到裁剪坐标。
//minimal.frag文件源码如下:

// 片元着色器

void main()
{
    gl_FragColor = vec4(0.4,0.4,0.8,1.0);
}

这个片元着色器更加简单,输出一个固定的颜色

我们知道着色器的源代码是由OpenGl驱动程序进行编译和链接的,OpenGl驱动程序大部分是由显卡厂商提供的并作为显卡驱动的一部分,因此VC并不能编译和链接GLSL的源代码。VC要做的事是读取这个以文本形式存在的源代码,并将这些代码以字符形式存下来,提交给OpenGl驱动程序。所以我们的例子中需要文件操作方面的代码。

第二步,创建OpenGL程序

//ogl.cpp程序源码如下:

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include <GL/glew.h>
#include <GL/glut.h>


GLuint v,f,f2,p;
float lpos[4] = {1,0.5,1,0};

char *textFileRead(char *fn) {

FILE *fp;
char *content = NULL;

int count=0;

if (fn != NULL) {
fp = fopen(fn,"r");

if (fp != NULL) {
      
      fseek(fp, 0, SEEK_END);
      count = ftell(fp);
      rewind(fp);

if (count > 0) {
content = (char *)malloc(sizeof(char) * (count+1));
count = fread(content,sizeof(char),count,fp);
content[count] = '\0';
}
fclose(fp);
}
}
return content;
}

int textFileWrite(char *fn, char *s) {

FILE *fp;
int status = 0;

if (fn != NULL) {
fp = fopen(fn,"w");

if (fp != NULL) {

if (fwrite(s,sizeof(char),strlen(s),fp) == strlen(s))
status = 1;
fclose(fp);
}
}
return(status);
}


void changeSize(int w, int h) {

// Prevent a divide by zero, when window is too short
// (you cant make a window of zero width).
if(h == 0)
h = 1;

float ratio = 1.0* w / h;

// Reset the coordinate system before modifying
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

// Set the viewport to be the entire window
    glViewport(0, 0, w, h);

// Set the correct perspective.
gluPerspective(45,ratio,1,1000);
glMatrixMode(GL_MODELVIEW);

}


float a = 0;

void renderScene(void) {

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();
gluLookAt(0.0,0.0,5.0, 
     0.0,0.0,-1.0,
 0.0f,1.0f,0.0f);

glLightfv(GL_LIGHT0, GL_POSITION, lpos);
glRotatef(a,0,1,1);
glutSolidTeapot(1);
a+=0.1;

glutSwapBuffers();
}

void processNormalKeys(unsigned char key, int x, int y) {

if (key == 27) 
exit(0);
}

#define printOpenGLError() printOglError(__FILE__, __LINE__)

int printOglError(char *file, int line)
{
    //
    // Returns 1 if an OpenGL error occurred, 0 otherwise.
    //
    GLenum glErr;
    int    retCode = 0;

    glErr = glGetError();
    while (glErr != GL_NO_ERROR)
    {
        printf("glError in file %s @ line %d: %s\n", file, line, gluErrorString(glErr));
        retCode = 1;
        glErr = glGetError();
    }
    return retCode;
}

void printShaderInfoLog(GLuint obj)
{
    int infologLength = 0;
    int charsWritten  = 0;
    char *infoLog;

glGetShaderiv(obj, GL_INFO_LOG_LENGTH,&infologLength);

    if (infologLength > 0)
    {
        infoLog = (char *)malloc(infologLength);
        glGetShaderInfoLog(obj, infologLength, &charsWritten, infoLog);
printf("%s\n",infoLog);
        free(infoLog);
    }
}

void printProgramInfoLog(GLuint obj)
{
    int infologLength = 0;
    int charsWritten  = 0;
    char *infoLog;

glGetProgramiv(obj, GL_INFO_LOG_LENGTH,&infologLength);


    if (infologLength > 0)
    {
        infoLog = (char *)malloc(infologLength);
        glGetProgramInfoLog(obj, infologLength, &charsWritten, infoLog);
printf("%s\n",infoLog);
        free(infoLog);
    }
}


void setShaders() {

char *vs = NULL,*fs = NULL,*fs2 = NULL;

v = glCreateShader(GL_VERTEX_SHADER);
f = glCreateShader(GL_FRAGMENT_SHADER);
f2 = glCreateShader(GL_FRAGMENT_SHADER);

vs = textFileRead("minimal.vert");
fs = textFileRead("minimal.frag");

const char * vv = vs;
const char * ff = fs;

glShaderSource(v, 1, &vv,NULL);
glShaderSource(f, 1, &ff,NULL);

free(vs);free(fs);

glCompileShader(v);
glCompileShader(f);

printShaderInfoLog(v);
printShaderInfoLog(f);
printShaderInfoLog(f2);//???

p = glCreateProgram();
glAttachShader(p,v);
glAttachShader(p,f);

glLinkProgram(p);
printProgramInfoLog(p);

glUseProgram(p);
}


int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(320,320);
glutCreateWindow("MM 2004-05");

glutDisplayFunc(renderScene);
glutIdleFunc(renderScene);
glutReshapeFunc(changeSize);
glutKeyboardFunc(processNormalKeys);

glEnable(GL_DEPTH_TEST);
glClearColor(1.0,1.0,1.0,1.0);
glEnable(GL_CULL_FACE);

glewInit();
if (glewIsSupported("GL_VERSION_2_0"))
printf("Ready for OpenGL 2.0\n");
else {
printf("OpenGL 2.0 not supported\n");
exit(1);
}

setShaders();

glutMainLoop();

return 0;
}





0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:18445次
    • 积分:236
    • 等级:
    • 排名:千里之外
    • 原创:1篇
    • 转载:20篇
    • 译文:0篇
    • 评论:0条
    文章分类