Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/test/browser/gl_textures.c
7085 views
1
// Copyright 2014 The Emscripten Authors. All rights reserved.
2
// Emscripten is available under two separate licenses, the MIT license and the
3
// University of Illinois/NCSA Open Source License. Both these licenses can be
4
// found in the LICENSE file.
5
6
#include <stdio.h>
7
#include <emscripten.h>
8
#include <string.h>
9
#include <emscripten/html5.h>
10
#include <GLES2/gl2.h>
11
#include <math.h>
12
#include <assert.h>
13
#include <stdlib.h>
14
15
GLuint program;
16
17
#define PIX_C(x, y) ((x)/256.0f + (y)/256.0f)
18
#define CLAMP(c) ((c) < 0.f ? 0.f : ((c) > 1.f ? 1.f : (c)))
19
#define PIX(x, y) CLAMP(PIX_C(x, y))
20
21
void draw()
22
{
23
int w, h;
24
emscripten_get_canvas_element_size("#canvas", &w, &h);
25
float xs = (float)h / w;
26
float ys = 1.0f;
27
float mat[] = { xs, 0, 0, 0, 0, ys, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
28
glUniformMatrix4fv(glGetUniformLocation(program, "mat"), 1, 0, mat);
29
glClearColor(0,0,1,1);
30
glClear(GL_COLOR_BUFFER_BIT);
31
glDrawArrays(GL_TRIANGLES, 0, 6);
32
33
unsigned char* imageData = (unsigned char*)malloc(256*256*4*sizeof(unsigned char));
34
glReadPixels(0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
35
for(int y = 0; y < 256; ++y)
36
for(int x = 0; x < 256; ++x)
37
{
38
unsigned char red = imageData[(y*256+x)*4];
39
float expectedRed = PIX(x, y);
40
unsigned char eRed = (unsigned char)(expectedRed * 255.0f);
41
assert(abs((int)eRed - red) <= 2);
42
}
43
emscripten_cancel_main_loop();
44
printf("Test successful!\n");
45
#if _REENTRANT
46
// In PROXY_TO_PTHREAD mode its currently not enough to cancel the main
47
// loop and have the application exit:
48
// https://github.com/emscripten-core/emscripten/issues/18773
49
exit(0);
50
#endif
51
}
52
53
int main()
54
{
55
emscripten_set_canvas_element_size("#canvas", 256, 256);
56
EmscriptenWebGLContextAttributes attr;
57
emscripten_webgl_init_context_attributes(&attr);
58
attr.alpha = attr.depth = attr.stencil = attr.antialias = attr.preserveDrawingBuffer = attr.failIfMajorPerformanceCaveat = 0;
59
attr.enableExtensionsByDefault = 1;
60
attr.premultipliedAlpha = 0;
61
attr.majorVersion = 1;
62
attr.minorVersion = 0;
63
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context("#canvas", &attr);
64
emscripten_webgl_make_context_current(ctx);
65
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
66
assert(vs);
67
const char *vss = "attribute vec4 vPosition; uniform mat4 mat; varying vec2 texCoord; void main() { gl_Position = vPosition; texCoord = (vPosition.xy + vec2(1.0)) * vec2(0.5); }";
68
glShaderSource(vs, 1, &vss, 0);
69
glCompileShader(vs);
70
GLint isCompiled = 0;
71
glGetShaderiv(vs, GL_COMPILE_STATUS, &isCompiled);
72
if (!isCompiled)
73
{
74
GLint maxLength = 0;
75
glGetShaderiv(vs, GL_INFO_LOG_LENGTH, &maxLength);
76
char *buf = malloc(maxLength);
77
glGetShaderInfoLog(vs, maxLength, &maxLength, buf);
78
printf("%s\n", buf);
79
return 1;
80
}
81
82
GLuint ps = glCreateShader(GL_FRAGMENT_SHADER);
83
const char *pss = "precision lowp float; varying vec2 texCoord; uniform vec3 colors[3]; uniform sampler2D tex; void main() { gl_FragColor = texture2D(tex, texCoord); }";
84
glShaderSource(ps, 1, &pss, 0);
85
glCompileShader(ps);
86
glGetShaderiv(ps, GL_COMPILE_STATUS, &isCompiled);
87
if (!isCompiled)
88
{
89
GLint maxLength = 0;
90
glGetShaderiv(ps, GL_INFO_LOG_LENGTH, &maxLength);
91
char *buf = malloc(maxLength);
92
glGetShaderInfoLog(ps, maxLength, &maxLength, buf);
93
printf("%s\n", buf);
94
return 1;
95
}
96
97
program = glCreateProgram();
98
assert(program);
99
glAttachShader(program, vs);
100
glAttachShader(program, ps);
101
glBindAttribLocation(program, 0, "vPosition");
102
glLinkProgram(program);
103
glGetProgramiv(program, GL_LINK_STATUS, &isCompiled);
104
if (!isCompiled)
105
{
106
GLint maxLength = 0;
107
glGetShaderiv(program, GL_INFO_LOG_LENGTH, &maxLength);
108
char *buf = malloc(maxLength);
109
glGetProgramInfoLog(program, maxLength, &maxLength, buf);
110
printf("%s\n", buf);
111
return 1;
112
}
113
114
glUseProgram(program);
115
116
GLuint vbo;
117
glGenBuffers(1, &vbo);
118
assert(vbo);
119
glBindBuffer(GL_ARRAY_BUFFER, vbo);
120
121
float verts[] = { -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1 };
122
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
123
glVertexAttribPointer(0, 2, GL_FLOAT, 0, sizeof(float)*2, 0);
124
glEnableVertexAttribArray(0);
125
GLuint tex;
126
glGenTextures(1, &tex);
127
glBindTexture(GL_TEXTURE_2D, tex);
128
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
129
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
130
float* texData = (float*)malloc(256*256*sizeof(float));
131
for(int y = 0; y < 256; ++y)
132
for(int x = 0; x < 256; ++x)
133
{
134
texData[y*256+x] = PIX(x, y);
135
}
136
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 256, 256, 0, GL_LUMINANCE, GL_FLOAT, texData);
137
emscripten_set_main_loop(draw, 0, 0);
138
return 0;
139
}
140
141