source: trunk/src/shader.cpp @ 735

Last change on this file since 735 was 735, checked in by sam, 10 years ago

core: get rid of now useless <cstdio> includes.

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
17#ifdef WIN32
18#   define WIN32_LEAN_AND_MEAN
19#   include <windows.h>
20#endif
21
22#include "core.h"
23#include "lolgl.h"
24
25namespace lol
26{
27
28/*
29 * Shader implementation class
30 */
31
32class ShaderData
33{
34    friend class Shader;
35
36private:
37#if defined HAVE_GL_2X || defined HAVE_GLES_2X
38    GLuint prog_id, vert_id, frag_id;
39#endif
40    uint32_t vert_crc, frag_crc;
41
42    /* Global shader cache */
43    static Shader *shaders[];
44    static int nshaders;
45};
46
47Shader *ShaderData::shaders[256];
48int ShaderData::nshaders = 0;
49
50/*
51 * Public Shader class
52 */
53
54Shader *Shader::Create(char const *vert, char const *frag)
55{
56    uint32_t new_vert_crc = Hash::Crc32(vert);
57    uint32_t new_frag_crc = Hash::Crc32(frag);
58
59    for (int n = 0; n < ShaderData::nshaders; n++)
60    {
61        if (ShaderData::shaders[n]->data->vert_crc == new_vert_crc
62             && ShaderData::shaders[n]->data->frag_crc == new_frag_crc)
63            return ShaderData::shaders[n];
64    }
65
66    Shader *ret = new Shader(vert, frag);
67    ShaderData::shaders[ShaderData::nshaders] = ret;
68    ShaderData::nshaders++;
69    return ret;
70}
71
72void Shader::Destroy(Shader *shader)
73{
74    /* XXX: do nothing! the shader should remain in cache */
75    (void)shader;
76}
77
78Shader::Shader(char const *vert, char const *frag)
79  : data(new ShaderData())
80{
81#if defined HAVE_GL_2X || defined HAVE_GLES_2X
82    char buf[4096];
83    GLsizei len;
84#endif
85
86    data->vert_crc = Hash::Crc32(vert);
87#if defined HAVE_GL_2X || defined HAVE_GLES_2X
88    data->vert_id = glCreateShader(GL_VERTEX_SHADER);
89    glShaderSource(data->vert_id, 1, &vert, NULL);
90    glCompileShader(data->vert_id);
91
92    glGetShaderInfoLog(data->vert_id, sizeof(buf), &len, buf);
93    if (len > 0)
94        Log::Error("failed to compile vertex shader: %s", buf);
95#endif
96
97    data->frag_crc = Hash::Crc32(frag);
98#if defined HAVE_GL_2X || defined HAVE_GLES_2X
99    data->frag_id = glCreateShader(GL_FRAGMENT_SHADER);
100    glShaderSource(data->frag_id, 1, &frag, NULL);
101    glCompileShader(data->frag_id);
102
103    glGetShaderInfoLog(data->frag_id, sizeof(buf), &len, buf);
104    if (len > 0)
105        Log::Error("failed to compile fragment shader: %s", buf);
106
107    data->prog_id = glCreateProgram();
108    glAttachShader(data->prog_id, data->vert_id);
109    glAttachShader(data->prog_id, data->frag_id);
110
111    glLinkProgram(data->prog_id);
112    glValidateProgram(data->prog_id);
113#endif
114}
115
116int Shader::GetAttribLocation(char const *attr) const
117{
118#if defined HAVE_GL_2X || defined HAVE_GLES_2X
119    return glGetAttribLocation(data->prog_id, attr);
120#else
121    (void)attr;
122    return -1;
123#endif
124}
125
126int Shader::GetUniformLocation(char const *uni) const
127{
128#if defined HAVE_GL_2X || defined HAVE_GLES_2X
129    return glGetUniformLocation(data->prog_id, uni);
130#else
131    (void)uni;
132    return -1;
133#endif
134}
135
136void Shader::Bind() const
137{
138#if defined HAVE_GL_2X || defined HAVE_GLES_2X
139    glUseProgram(data->prog_id);
140#endif
141}
142
143Shader::~Shader()
144{
145#if defined HAVE_GL_2X || defined HAVE_GLES_2X
146    glDetachShader(data->prog_id, data->vert_id);
147    glDetachShader(data->prog_id, data->frag_id);
148    glDeleteShader(data->vert_id);
149    glDeleteShader(data->frag_id);
150    glDeleteProgram(data->prog_id);
151#endif
152    delete data;
153}
154
155} /* namespace lol */
156
Note: See TracBrowser for help on using the repository browser.