如何获得emscripten+ webGL呈现终止或所请求的输入
我正在尝试使用Emscripten编写一些旧的C ++代码,以汇编为WebAssembly和WebGL。我有一个非常简单的单文件C ++项目,该项目呈现Mandelbrot集,该集合使用G ++效果很好。我运行它,实际上它确实使Mandelbrot构建了越来越多的细节。
我已经获得了使用EMCC编译的代码,这需要大量阅读...但是它仍然无法按照我的意愿工作。由于某种原因,当我进入HTML页面时,直到代码终止或要求输入之前,什么都没有呈现。当时,正确的帧(Mandelbrot集)实际上是。
显然,我想要的是在帧速率计时器启动之前渲染的每个帧。但是,即使使用 glfinish()
调用,我也无法正常工作。
有人会看我的代码,看看我是否做错了什么?
谢谢:
// Charles Swanson, [email protected]
// Written 2019/11/30
// Compile using:
// g++ SmallestOpenGL.cpp -o SmallestOpenGL_Bin -lGL -lglfw
// emcc SmallestOpenGL.cpp -o ../IgnoreMe/SmallestOpenGL.html -s USE_GLFW=3 -s MIN_WEBGL_VERSION=2
// Copyright me, all rights reserved for now.
#define GLFW_INCLUDE_ES3
#include <GLFW/glfw3.h>
#include <iostream>
#include <time.h>
#include <thread>
const char* vertexShaderSource = "#version 300 es\n"
"layout (location = 0) in vec3 aPos;\n"
"out float u;\n"
"out float v;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
" u = aPos.x;\n"
" v = aPos.y;\n"
"}\0";
const char* fragmentShaderSource = "#version 300 es\n"
"precision mediump float;\n"
"uniform float maxiters;\n"
"in float u;\n"
"in float v;\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n"
" float scaledx = (u-0.5)*1.5f;\n"
" float scaledy = v*1.0f;\n"
" float currentx = scaledx;\n"
" float currenty = scaledy;\n"
" float currentx2 = 0.0f;\n"
" float currenty2 = 0.0f;\n"
" for (int loopind = 1;loopind<int(maxiters);loopind++)\n"
" {\n"
" currentx2 = scaledx + currentx*currentx - currenty*currenty;\n"
" currenty2 = scaledy + 2.0f*currentx*currenty;\n"
" currentx = clamp(currentx2,-10000.0f,10000.0f);\n"
" currenty = clamp(currenty2,-10000.0f,10000.0f);\n"
" }\n"
" float amplitude = currentx2*currentx + currenty2*currenty;\n"
" if (amplitude>4.0)\n"
" FragColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);\n"
"}\0";
int main(void)
{
glfwInit();
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,0);
GLFWwindow* window = glfwCreateWindow(400,300,"The Window Title",NULL,NULL);
glfwMakeContextCurrent(window);
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader,1,&vertexShaderSource,NULL);
glCompileShader(vertexShader);
GLchar infoLog[256];
glGetShaderInfoLog(vertexShader,256,NULL,infoLog);
std::cout<<"Vertex shader info log says: "<<infoLog<<std::endl;
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader,1,&fragmentShaderSource,NULL);
glCompileShader(fragmentShader);
glGetShaderInfoLog(fragmentShader,256,NULL,infoLog);
std::cout<<"Fragment shader info log says: "<<infoLog<<std::endl;
GLuint program = glCreateProgram();
glAttachShader(program,vertexShader);
glAttachShader(program,fragmentShader);
glLinkProgram(program);
glGetProgramInfoLog(program,256,NULL,infoLog);
std::cout<<"Progam info log says: "<<infoLog<<std::endl;
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
float vertices[] = {
-1.0f, -1.0f, 0.0f, // bottom left
-1.0f, 1.0f, 0.0f, // top left
1.0f, -1.0f, 0.0f, // bottom right
-1.0f, 1.0f, 0.0f, // top left
1.0f, -1.0f, 0.0f, // bottom right
1.0f, 1.0f, 0.0f, // top right
};
GLuint VAO;
glGenVertexArrays(1,&VAO);
glBindVertexArray(VAO);
glEnableVertexAttribArray(0);
GLuint VBO;
glGenBuffers(1,&VBO);
glBindBuffer(GL_ARRAY_BUFFER,VBO);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);
glVertexAttribPointer(0,3,GL_FLOAT,GL_TRUE,3*sizeof(float),0);
glUseProgram(program);
GLuint maxitersLocation = glGetUniformLocation(program,"maxiters");
GLuint xsizeLocation = glGetUniformLocation(program,"xsize");
GLuint ysizeLocation = glGetUniformLocation(program,"ysize");
std::cout<<"Maxiters location is "<<maxitersLocation<<std::endl;
int xsize;
int ysize;
glfwGetWindowSize(window,&xsize,&ysize);
std::cout<<"Window size is "<<xsize<<" x "<<ysize<<std::endl;
glUniform1f(maxitersLocation,10);
float iters = 0;
while (iters<10)
{
iters = iters+0.1;
if (iters>10)
iters = 10;
glUniform1f(maxitersLocation,iters);
glClearColor(1,0.5,0,1);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES,0,6);
glfwSwapBuffers(window);
glfwPollEvents();
glFinish();
std::this_thread::sleep_for(std::chrono::milliseconds(long(30)));
}
char in;
std::cin>>in;
glfwTerminate();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好的,我发现了。许多网络示例实现了解决方案;我想我掩盖了他们。这里有几个:
https://github.com/github.com/pcbaecker/pcbaecker/pcbaecker/example-example-example--emspample--emspample-webgl
“
https://github.com /qafoolabs/emscripten-opengl-example“ rel =“ nofollow noreferrer”> https://github.com/qafoolabs/emscripten-opengl-example
关键是使用在
emscripten.h.h.h.h.h.h.h.h.h
称为emscripten_set_main_loop
。将该功能传递给您的渲染功能,并呈现每个帧。出色的!Ok, I figured it out. Many web examples implement the solution; I guess I glossed over them. Here are a few:
https://github.com/pcbaecker/example-emscripten-webgl
https://gist.github.com/mortennobel/0e9e90c9bbc61cc99d5c3e9c038d8115
https://gist.github.com/ousttrue/0f3a11d5d28e365b129fe08f18f4e141
https://github.com/QafooLabs/emscripten-opengl-example
The key is to use the function implemented in
Emscripten.h
calledemscripten_set_main_loop
. Pass that function a handle to your render function, and it renders every frame. Excellent!