source: trunk/src/shader.cpp @ 674

Last change on this file since 674 was 674, checked in by sam, 9 years ago

The engine now builds for GL and GL ES 1.x and 2.x, and runs for each
one except GL ES 2.x for now.

File size: 3.5 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
7//   Public License, Version 2, as published by Sam Hocevar. See
8//   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
9//
10
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#include <cmath>
16#include <cstdio>
17
18#ifdef WIN32
19#   define WIN32_LEAN_AND_MEAN
20#   include <windows.h>
21#endif
22
23#include "core.h"
24#include "lolgl.h"
25
26/*
27 * Shader implementation class
28 */
29
30class ShaderData
31{
32    friend class Shader;
33
34private:
35#if defined HAVE_GL_2X || defined HAVE_GLES_2X
36    GLuint prog_id, vert_id, frag_id;
37#endif
38    uint32_t vert_crc, frag_crc;
39
40    /* Global shader cache */
41    static Shader *shaders[];
42    static int nshaders;
43};
44
45Shader *ShaderData::shaders[256];
46int ShaderData::nshaders = 0;
47
48/*
49 * Public Shader class
50 */
51
52Shader *Shader::Create(char const *vert, char const *frag)
53{
54    uint32_t new_vert_crc = Hash::Crc32(vert);
55    uint32_t new_frag_crc = Hash::Crc32(frag);
56
57    for (int n = 0; n < ShaderData::nshaders; n++)
58    {
59        if (ShaderData::shaders[n]->data->vert_crc == new_vert_crc
60             && ShaderData::shaders[n]->data->frag_crc == new_frag_crc)
61            return ShaderData::shaders[n];
62    }
63
64    Shader *ret = new Shader(vert, frag);
65    ShaderData::shaders[ShaderData::nshaders] = ret;
66    ShaderData::nshaders++;
67    return ret;
68}
69
70void Shader::Destroy(Shader *shader)
71{
72    /* XXX: do nothing! the shader should remain in cache */
73    (void)shader;
74}
75
76Shader::Shader(char const *vert, char const *frag)
77  : data(new ShaderData())
78{
79#if defined HAVE_GL_2X || defined HAVE_GLES_2X
80    char buf[4096];
81    GLsizei len;
82#endif
83
84    data->vert_crc = Hash::Crc32(vert);
85#if defined HAVE_GL_2X || defined HAVE_GLES_2X
86    data->vert_id = glCreateShader(GL_VERTEX_SHADER);
87    glShaderSource(data->vert_id, 1, &vert, NULL);
88    glCompileShader(data->vert_id);
89
90    glGetShaderInfoLog(data->vert_id, sizeof(buf), &len, buf);
91    if (len > 0)
92        fprintf(stderr, "ERROR: failed to compile vertex shader: %s", buf);
93#endif
94
95    data->frag_crc = Hash::Crc32(frag);
96#if defined HAVE_GL_2X || defined HAVE_GLES_2X
97    data->frag_id = glCreateShader(GL_FRAGMENT_SHADER);
98    glShaderSource(data->frag_id, 1, &frag, NULL);
99    glCompileShader(data->frag_id);
100
101    glGetShaderInfoLog(data->frag_id, sizeof(buf), &len, buf);
102    if (len > 0)
103        fprintf(stderr, "ERROR: failed to compile fragment shader: %s", buf);
104
105    data->prog_id = glCreateProgram();
106    glAttachShader(data->prog_id, data->vert_id);
107    glAttachShader(data->prog_id, data->frag_id);
108
109    glLinkProgram(data->prog_id);
110    glValidateProgram(data->prog_id);
111#endif
112}
113
114int Shader::GetAttribLocation(char const *attr) const
115{
116#if defined HAVE_GL_2X || defined HAVE_GLES_2X
117    return glGetAttribLocation(data->prog_id, attr);
118#else
119    (void)attr;
120    return -1;
121#endif
122}
123
124int Shader::GetUniformLocation(char const *uni) const
125{
126#if defined HAVE_GL_2X || defined HAVE_GLES_2X
127    return glGetUniformLocation(data->prog_id, uni);
128#else
129    (void)uni;
130    return -1;
131#endif
132}
133
134void Shader::Bind() const
135{
136#if defined HAVE_GL_2X || defined HAVE_GLES_2X
137    glUseProgram(data->prog_id);
138#endif
139}
140
141Shader::~Shader()
142{
143#if defined HAVE_GL_2X || defined HAVE_GLES_2X
144    glDetachShader(data->prog_id, data->vert_id);
145    glDetachShader(data->prog_id, data->frag_id);
146    glDeleteShader(data->vert_id);
147    glDeleteShader(data->frag_id);
148    glDeleteProgram(data->prog_id);
149#endif
150    delete data;
151}
152
Note: See TracBrowser for help on using the repository browser.