1 //
2 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // Based on MultiTexture.c from
8 // Book: OpenGL(R) ES 2.0 Programming Guide
9 // Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
10 // ISBN-10: 0321502795
11 // ISBN-13: 9780321502797
12 // Publisher: Addison-Wesley Professional
13 // URLs: http://safari.informit.com/9780321563835
14 // http://www.opengles-book.com
15
16 #include "SampleApplication.h"
17
18 #include "tga_utils.h"
19 #include "util/shader_utils.h"
20 #include "util/test_utils.h"
21
22 class MultiTextureSample : public SampleApplication
23 {
24 public:
MultiTextureSample(int argc,char ** argv)25 MultiTextureSample(int argc, char **argv) : SampleApplication("MultiTexture", argc, argv) {}
26
loadTexture(const std::string & path)27 GLuint loadTexture(const std::string &path)
28 {
29 TGAImage img;
30 if (!LoadTGAImageFromFile(path, &img))
31 {
32 return 0;
33 }
34
35 return LoadTextureFromTGAImage(img);
36 }
37
initialize()38 bool initialize() override
39 {
40 constexpr char kVS[] = R"(attribute vec4 a_position;
41 attribute vec2 a_texCoord;
42 varying vec2 v_texCoord;
43 void main()
44 {
45 gl_Position = a_position;
46 v_texCoord = a_texCoord;
47 })";
48
49 constexpr char kFS[] = R"(precision mediump float;
50 varying vec2 v_texCoord;
51 uniform sampler2D s_baseMap;
52 uniform sampler2D s_lightMap;
53 void main()
54 {
55 vec4 baseColor;
56 vec4 lightColor;
57
58 baseColor = texture2D(s_baseMap, v_texCoord);
59 lightColor = texture2D(s_lightMap, v_texCoord);
60 gl_FragColor = baseColor * (lightColor + 0.25);
61 })";
62
63 mProgram = CompileProgram(kVS, kFS);
64 if (!mProgram)
65 {
66 return false;
67 }
68
69 // Get the attribute locations
70 mPositionLoc = glGetAttribLocation(mProgram, "a_position");
71 mTexCoordLoc = glGetAttribLocation(mProgram, "a_texCoord");
72
73 // Get the sampler location
74 mBaseMapLoc = glGetUniformLocation(mProgram, "s_baseMap");
75 mLightMapLoc = glGetUniformLocation(mProgram, "s_lightMap");
76
77 // Load the textures
78 std::stringstream baseStr;
79 baseStr << angle::GetExecutableDirectory() << "/basemap.tga";
80
81 std::stringstream lightStr;
82 lightStr << angle::GetExecutableDirectory() << "/lightmap.tga";
83
84 mBaseMapTexID = loadTexture(baseStr.str());
85 mLightMapTexID = loadTexture(lightStr.str());
86 if (mBaseMapTexID == 0 || mLightMapTexID == 0)
87 {
88 return false;
89 }
90
91 return true;
92 }
93
destroy()94 void destroy() override
95 {
96 glDeleteProgram(mProgram);
97 glDeleteTextures(1, &mBaseMapTexID);
98 glDeleteTextures(1, &mLightMapTexID);
99 }
100
draw()101 void draw() override
102 {
103 GLfloat vertices[] = {
104 -0.5f, 0.5f, 0.0f, // Position 0
105 0.0f, 0.0f, // TexCoord 0
106 -0.5f, -0.5f, 0.0f, // Position 1
107 0.0f, 1.0f, // TexCoord 1
108 0.5f, -0.5f, 0.0f, // Position 2
109 1.0f, 1.0f, // TexCoord 2
110 0.5f, 0.5f, 0.0f, // Position 3
111 1.0f, 0.0f // TexCoord 3
112 };
113 GLushort indices[] = {0, 1, 2, 0, 2, 3};
114
115 // Set the viewport
116 glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
117
118 // Clear the color buffer
119 glClear(GL_COLOR_BUFFER_BIT);
120
121 // Use the program object
122 glUseProgram(mProgram);
123
124 // Load the vertex position
125 glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), vertices);
126 // Load the texture coordinate
127 glVertexAttribPointer(mTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat),
128 vertices + 3);
129
130 glEnableVertexAttribArray(mPositionLoc);
131 glEnableVertexAttribArray(mTexCoordLoc);
132
133 // Bind the base map
134 glActiveTexture(GL_TEXTURE0);
135 glBindTexture(GL_TEXTURE_2D, mBaseMapTexID);
136
137 // Set the base map sampler to texture unit to 0
138 glUniform1i(mBaseMapLoc, 0);
139
140 // Bind the light map
141 glActiveTexture(GL_TEXTURE1);
142 glBindTexture(GL_TEXTURE_2D, mLightMapTexID);
143
144 // Set the light map sampler to texture unit 1
145 glUniform1i(mLightMapLoc, 1);
146
147 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
148 }
149
150 private:
151 // Handle to a program object
152 GLuint mProgram;
153
154 // Attribute locations
155 GLint mPositionLoc;
156 GLint mTexCoordLoc;
157
158 // Sampler locations
159 GLint mBaseMapLoc;
160 GLint mLightMapLoc;
161
162 // Texture handle
163 GLuint mBaseMapTexID;
164 GLuint mLightMapTexID;
165 };
166
main(int argc,char ** argv)167 int main(int argc, char **argv)
168 {
169 MultiTextureSample app(argc, argv);
170 return app.run();
171 }
172