Open tomlikesnakes opened 4 days ago
Okay it's due to the flag FULL_ES from emscripten
We got these warning when removed the -s FULL_ES2=1 (or FULL_ES3=1) that transform themselves to errors
128WebGL: INVALID_VALUE: vertexAttribPointer: index out of range 128WebGL: INVALID_VALUE: enableVertexAttribArray: index out of range index.js:5086 WebGL: too many errors, no more errors will be reported to the console for this context.
this works :
#include <raylib.h>
#include <emscripten.h>
#include <GLES3/gl3.h>
const int screen_width = 800;
const int screen_height = 450;
GLuint shader_program;
GLint pos_attrib;
GLuint vbo, vao;
// Vertex data for a simple triangle
float vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
void draw(void) {
BeginDrawing();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shader_program);
TraceLog(LOG_INFO, "Using shader program %d", shader_program);
glBindVertexArray(vao);
TraceLog(LOG_INFO, "Bound VAO %d", vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
TraceLog(LOG_INFO, "DrawArrays executed");
EndDrawing();
}
void setup_shaders() {
// Vertex shader that uses the 'position' attribute
const char* vertex_shader_source = "#version 300 es\n"
"precision mediump float;\n"
"layout(location = 0) in vec3 position;\n"
"void main() {\n"
" // Use each component of position and assign it to gl_Position\n"
" gl_Position = vec4(position.x, position.y, position.z, 1.0);\n"
"}\n";
// Fragment shader that uses frag_color
const char* fragment_shader_source = "#version 300 es\n"
"precision mediump float;\n"
"out vec4 frag_color;\n"
"void main() {\n"
" // Output a constant red color\n"
" frag_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n";
GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL);
glCompileShader(vertex_shader);
GLint vertex_compile_status;
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &vertex_compile_status);
if (!vertex_compile_status) {
char info_log[512];
glGetShaderInfoLog(vertex_shader, 512, NULL, info_log);
TraceLog(LOG_ERROR, "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n%s", info_log);
}
GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL);
glCompileShader(fragment_shader);
GLint fragment_compile_status;
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &fragment_compile_status);
if (!fragment_compile_status) {
char info_log[512];
glGetShaderInfoLog(fragment_shader, 512, NULL, info_log);
TraceLog(LOG_ERROR, "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n%s", info_log);
}
// Create shader program and link shaders
shader_program = glCreateProgram();
glAttachShader(shader_program, vertex_shader);
glAttachShader(shader_program, fragment_shader);
glLinkProgram(shader_program);
// Validate shader program
GLint is_linked;
glGetProgramiv(shader_program, GL_LINK_STATUS, &is_linked);
if (!is_linked) {
char info_log[512];
glGetProgramInfoLog(shader_program, 512, NULL, info_log);
TraceLog(LOG_ERROR, "ERROR::SHADER::PROGRAM::LINKING_FAILED\n%s", info_log);
}
// Use the shader program
glUseProgram(shader_program);
// Get attribute location
pos_attrib = glGetAttribLocation(shader_program, "position");
TraceLog(LOG_INFO, "Attribute 'position' location (queried in setup): %d", pos_attrib);
// Create VAO and VBO for triangle
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// Enable the attribute array and set up pointer
if (pos_attrib >= 0) {
glEnableVertexAttribArray(pos_attrib);
glVertexAttribPointer(pos_attrib, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
TraceLog(LOG_INFO, "VertexAttribPointer set for location %d", pos_attrib);
} else {
TraceLog(LOG_ERROR, "Invalid attribute location for 'position'");
}
// Unbind VAO (optional)
glBindVertexArray(0);
}
int main() {
InitWindow(screen_width, screen_height, "raylib with Emscripten - Proper Shaders");
// Setup the shaders and VBO/VAO
setup_shaders();
SetTargetFPS(60);
// Emscripten loop
emscripten_set_main_loop(draw, 0, 1);
CloseWindow();
return 0;
}
this not (cause of previous warning from enableVertexAtribArray and so) :
#include <raylib.h>
#include <emscripten.h>
#include <rlgl.h>
#include <GLES3/gl3.h>
const int screen_width = 800;
const int screen_height = 450;
Shader custom_shader;
unsigned int vbo, vao;
int position_loc;
void draw(void) {
BeginDrawing();
ClearBackground(RAYWHITE);
rlEnableShader(custom_shader.id);
// Bind the VAO (which contains the VBO with our vertex data)
glBindVertexArray(vao); // Use OpenGL to bind the VAO
// Draw the triangle using the bound VAO
glDrawArrays(GL_TRIANGLES, 0, 3); // Draw 3 vertices (1 triangle)
// Unbind the VAO after drawing
glBindVertexArray(0); // Unbind VAO to avoid issues later
// End custom shader mode
rlDisableShader();
// Render some debug text
DrawText("Triangle rendered using OpenGL and rlgl!", 210, 400, 20, BLACK);
EndDrawing();
}
void setup_gl_buffers() {
// Define the vertex data for a simple triangle (position only)
float vertices[] = {
// Positions
-0.5f, -0.5f, 0.0f, // Bottom-left
0.5f, -0.5f, 0.0f, // Bottom-right
0.0f, 0.5f, 0.0f // Top-center
};
// Generate and bind a VAO
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Generate and bind a VBO
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
// Upload the vertex data to the VBO
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// Use the location retrieved from `rlgl` instead of hardcoding 0
glEnableVertexAttribArray(position_loc); // Use attribute location from `rlgl`
glVertexAttribPointer(position_loc, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
// Unbind the VBO and VAO to avoid accidental modification
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void setup_rlgl_shader() {
// Vertex shader with a 'position' attribute
const char* vertex_shader_code = "#version 300 es\n"
"precision mediump float;\n"
"layout(location = 0) in vec3 position;\n" // 'position' attribute
"void main() {\n"
" gl_Position = vec4(position.x, position.y, position.z, 1.0);\n" // Use each component of position
"}\n";
// Fragment shader outputting a red color
const char* fragment_shader_code = "#version 300 es\n"
"precision mediump float;\n"
"out vec4 frag_color;\n"
"void main() {\n"
" frag_color = vec4(1.0, 0.0, 0.0, 1.0);\n" // Output red color
"}\n";
// Load custom shader from code
custom_shader = LoadShaderFromMemory(vertex_shader_code, fragment_shader_code);
// Check for any shader compilation/linking errors
if (custom_shader.id == 0) {
TraceLog(LOG_ERROR, "Shader program failed to load.");
return;
}
// Get the location of the 'position' attribute from the custom shader
position_loc = GetShaderLocationAttrib(custom_shader, "position");
TraceLog(LOG_INFO, "Shader position attribute location: %d", position_loc);
if (position_loc == -1) {
TraceLog(LOG_ERROR, "Failed to get position attribute location");
return;
}
}
int main() {
InitWindow(screen_width, screen_height, "raylib with Emscripten - OpenGL + rlgl");
// Setup the OpenGL buffers (VBO/VAO)
setup_gl_buffers();
// Setup the custom shader
setup_rlgl_shader();
SetTargetFPS(60);
// Emscripten loop
emscripten_set_main_loop(draw, 0, 1);
// Cleanup
UnloadShader(custom_shader); // Unload the shader when done
glDeleteBuffers(1, &vbo); // Delete the VBO
glDeleteVertexArrays(1, &vao); // Delete the VAO
CloseWindow(); // Close the window and OpenGL context
return 0;
}
-> the way rlgl manage shaders is not consistent that's why for the second example I also tried to use opengl with rlgl (also tried only rlgl but got same warnings) -> From what I see for opengl 300es webgl2 you always need shaders and you always need to really have all in/out var clearly pass and defined (like each components of pos) and manually create vao/vbo with vertex data
for now I'm going to use pure opengl cause I really need the opengl 300es, If someone can have a look and correct what I found or anything I'm here
@tomlikesnakes Thanks for reporting! Actually, OpenGL ES 3.0 has been added recently as a backend GL option to raylib and it has not been widely tested.
Hello,
There is an error when targetting webgl2 and using whatever Draw function you want (like DrawRectangle/cube/text etc)
I did a very minimal example here :
compilation flag :
I tried with only full_es2, with different things for memory and so.
For this kind of things it is not really problematic but for my other project I need to create vertex buffer and go with opengl (not rlgl) and use shaders for a cube, and i need the webgl2/opengl300es for my futures things on the project