source: trunk/src/shader.cpp @ 673

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

Put the OpenGL header handling in <lolgl.h> for more convenience.

File size: 3.0 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    GLuint prog_id, vert_id, frag_id;
36    uint32_t vert_crc, frag_crc;
37
38    /* Global shader cache */
39    static Shader *shaders[];
40    static int nshaders;
41};
42
43Shader *ShaderData::shaders[256];
44int ShaderData::nshaders = 0;
45
46/*
47 * Public Shader class
48 */
49
50Shader *Shader::Create(char const *vert, char const *frag)
51{
52    uint32_t new_vert_crc = Hash::Crc32(vert);
53    uint32_t new_frag_crc = Hash::Crc32(frag);
54
55    for (int n = 0; n < ShaderData::nshaders; n++)
56    {
57        if (ShaderData::shaders[n]->data->vert_crc == new_vert_crc
58             && ShaderData::shaders[n]->data->frag_crc == new_frag_crc)
59            return ShaderData::shaders[n];
60    }
61
62    Shader *ret = new Shader(vert, frag);
63    ShaderData::shaders[ShaderData::nshaders] = ret;
64    ShaderData::nshaders++;
65    return ret;
66}
67
68void Shader::Destroy(Shader *shader)
69{
70    /* XXX: do nothing! the shader should remain in cache */
71    (void)shader;
72}
73
74Shader::Shader(char const *vert, char const *frag)
75  : data(new ShaderData())
76{
77    char buf[4096];
78    GLsizei len;
79
80    data->vert_crc = Hash::Crc32(vert);
81    data->vert_id = glCreateShader(GL_VERTEX_SHADER);
82    glShaderSource(data->vert_id, 1, &vert, NULL);
83    glCompileShader(data->vert_id);
84
85    glGetShaderInfoLog(data->vert_id, sizeof(buf), &len, buf);
86    if (len > 0)
87        fprintf(stderr, "ERROR: failed to compile vertex shader: %s", buf);
88
89    data->frag_crc = Hash::Crc32(frag);
90    data->frag_id = glCreateShader(GL_FRAGMENT_SHADER);
91    glShaderSource(data->frag_id, 1, &frag, NULL);
92    glCompileShader(data->frag_id);
93
94    glGetShaderInfoLog(data->frag_id, sizeof(buf), &len, buf);
95    if (len > 0)
96        fprintf(stderr, "ERROR: failed to compile fragment shader: %s", buf);
97
98    data->prog_id = glCreateProgram();
99    glAttachShader(data->prog_id, data->vert_id);
100    glAttachShader(data->prog_id, data->frag_id);
101
102    glLinkProgram(data->prog_id);
103    glValidateProgram(data->prog_id);
104}
105
106int Shader::GetAttribLocation(char const *attr) const
107{
108    return glGetAttribLocation(data->prog_id, attr);
109}
110
111int Shader::GetUniformLocation(char const *uni) const
112{
113    return glGetUniformLocation(data->prog_id, uni);
114}
115
116void Shader::Bind() const
117{
118    glUseProgram(data->prog_id);
119}
120
121Shader::~Shader()
122{
123    glDetachShader(data->prog_id, data->vert_id);
124    glDetachShader(data->prog_id, data->frag_id);
125    glDeleteShader(data->vert_id);
126    glDeleteShader(data->frag_id);
127    glDeleteProgram(data->prog_id);
128    delete data;
129}
130
Note: See TracBrowser for help on using the repository browser.