xref: /aosp_15_r20/external/angle/samples/multi_texture/MultiTexture.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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