示例#1
0
文件: compute.hpp 项目: tim42/yaggler
 void dispatch_indirect(neam::yaggler::geometry::buffer<neam::yaggler::type::opengl, BufferTypes...> buffer, size_t offset = 0)
 {
   if (!mw.is_empty())
   {
     buffer.bind_to_target(GL_DISPATCH_INDIRECT_BUFFER);
     mw.use();
     glDispatchComputeIndirect(offset);
   }
 }
void Shader::dispatchComputeShaderIndirect(GLuint dispatchBuffer, GLuint offset) const
{
  glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, dispatchBuffer);
  glDispatchComputeIndirect(offset);
  glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, 0);
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL43_nglDispatchComputeIndirect(JNIEnv *__env, jclass clazz, jlong indirect, jlong __functionAddress) {
	glDispatchComputeIndirectPROC glDispatchComputeIndirect = (glDispatchComputeIndirectPROC)(intptr_t)__functionAddress;
	UNUSED_PARAMS(__env, clazz)
	glDispatchComputeIndirect((GLintptr)indirect);
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL43_nglDispatchComputeIndirect(JNIEnv *__env, jclass clazz, jlong indirect) {
    glDispatchComputeIndirectPROC glDispatchComputeIndirect = (glDispatchComputeIndirectPROC)tlsGetFunction(873);
    UNUSED_PARAM(clazz)
    glDispatchComputeIndirect((intptr_t)indirect);
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL43_nglDispatchComputeIndirect(JNIEnv *env, jclass clazz, jlong indirect, jlong function_pointer) {
	glDispatchComputeIndirectPROC glDispatchComputeIndirect = (glDispatchComputeIndirectPROC)((intptr_t)function_pointer);
	glDispatchComputeIndirect(indirect);
}
void openglCompute(){
	//Note: Compute shaders are only OpenGL 4.3+ so my laptop can't run this, since
	//it's on 4.0
	Window::init();
	Window window("OpenGL Compute - Nothing will be drawn");

	//This shader declares local group size to be 16x16 then does nothing
	const char *doNothingSrc = 
		"#version 430 core \n \
		//Input layout qualifier declaring a 16x16 local workgroup size \n \
		//It looks like a big bonus for Opencl is being able to set this at runtime \
		//Whereas in OpenGL compute shader it must be in the shader, although I suppose we could \
		//change that somehow? hm \
		layout (local_size_x = 16, local_size_y = 1) in; \n \
		void main() { }";

	std::string src = Util::readFile("../res/helloCompute.glsl");

	const char *shaderSrc = src.c_str();

	GLuint shader = glCreateShader(GL_COMPUTE_SHADER);
	glShaderSource(shader, 1, &shaderSrc, NULL);
	glCompileShader(shader);
	GLint status;
	glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
	if (status != GL_TRUE){
		std::cout << "Compile failed" << std::endl;
		//Get the log length and then get the log
        GLint logLength;
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
        std::vector<char> log(logLength);
        glGetShaderInfoLog(shader, logLength, NULL, &log[0]);

        //Construct and return log message
        std::string errorMsg(log.begin(), log.end());
        std::cout << errorMsg << std::endl;
	}

	GLuint program = glCreateProgram();
	glAttachShader(program, shader);
	glLinkProgram(program);
	glGetProgramiv(program, GL_LINK_STATUS, &status);
	if (status != GL_TRUE)
		std::cout << "Link failed" << std::endl;

	glDeleteShader(shader);
	glUseProgram(program);
	
	//Setup the data buffer
	GLuint dataBuf;
	glGenBuffers(1, &dataBuf);
	glBindBuffer(GL_SHADER_STORAGE_BUFFER, dataBuf);
	glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLuint) * 16, NULL, GL_DYNAMIC_COPY);
	//Bind it as the 0th shader storage buffer binding pt
	glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, dataBuf);

	GLuint globalDim[] = { 16, 1, 1 };
	GLuint dispatchBuf;
	glGenBuffers(1, &dispatchBuf);
	glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, dispatchBuf);
	glBufferData(GL_DISPATCH_INDIRECT_BUFFER, sizeof(globalDim), globalDim, GL_STATIC_DRAW);
	glDispatchComputeIndirect(0);

	Util::checkError("Dispatched compute");

	int *outData = (int*)glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY);
	std::cout << "Data read: ";
	for (int i = 0; i < 16; ++i)
		std::cout << outData[i] << ", ";
	std::cout << std::endl;
	glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
	outData = nullptr;

	//cleanup
	glDeleteBuffers(1, &dataBuf);
	glDeleteBuffers(1, &dispatchBuf);
	glDeleteProgram(program);
}