Sign in to follow this  
Valera

OpengGL Superbible7, first example. Do not draw a point

Recommended Posts

Valera    106

It`s my two small class.

.h
class ShaderCompile
  {
  public:
    GLuint Compile();
  private:

    GLuint vertex_shader;
    GLuint fragment_shader;
    GLuint shader;

    const GLchar * vertex_shader_source
    {
      "#version 450 core                                  \n"
      "                                                   \n"
      "void main(void)                                    \n"
      "{                                                  \n"
      "    gl_Position = vec4(0.0, 0.0, 0.5, 1.0);        \n"
      "}                                                  \n"
    };

    const GLchar * fragment_shader_source
    {
      "#version 450 core                                  \n"
      "                                                   \n"
      "out vec4 color;                                    \n"
      "                                                   \n"
      "void main(void)                                    \n"
      "{                                                  \n"
      "    color = vec4(0.0, 0.8, 1.0, 1.0);              \n"
      "}                                                  \n"
    };

  };
.cpp
GLuint ShaderCompile::Compile()
{
  const GLchar * proxy_shader[1];

  proxy_shader[0] = vertex_shader_source;
  vertex_shader = glCreateShader(GL_VERTEX_SHADER);
  glShaderSource(vertex_shader, 1, proxy_shader, NULL);
  glCompileShader(vertex_shader);

  proxy_shader[0] = fragment_shader_source;
  fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
  glShaderSource(fragment_shader, 1, proxy_shader, NULL);
  glCompileShader(fragment_shader);

  shader = glCreateProgram();
  glAttachShader(shader, vertex_shader);
  glAttachShader(shader, fragment_shader);
  glLinkProgram(shader);

  glDeleteShader(vertex_shader);
  glDeleteShader(fragment_shader);

  auto status = GL_LINK_STATUS;
  auto error = glGetError();
  auto comp = GL_COMPILE_STATUS;

  GLint linked = 0;
  glGetProgramiv(shader, GL_LINK_STATUS, &linked);
  if (!linked) return 0;

  return shader;
}

and

.h
class Shaders
  {
  public:
    void Startup();
    void Shutdown();
    void Render();
  private:
    ShaderCompile * compiler;
    GLuint rendering_program;
    GLuint vertex_array_object;
  };
.cpp
void Shaders::Startup()
{
  compiler = new ShaderCompile();
  rendering_program = compiler->Compile();
  glCreateVertexArrays(1, &vertex_array_object);
  glBindVertexArray(vertex_array_object);
}

void Shaders::Shutdown()
{
  glDeleteVertexArrays(1, &vertex_array_object);
  glDeleteProgram(rendering_program);
  delete compiler;
}

void Shaders::Render() 
{
  const GLfloat color[] { 0.0, 0.8, 1.0, 1.0 };

  glClearBufferfv(GL_COLOR, 0, color);

  glUseProgram(rendering_program);

  glDrawArrays(GL_POINTS, 0, 1);

  glPointSize(100.0f);
}

I call this on click button event

void GLCore::ClickOk()
{
  sh = new Shaders();
  sh->Startup();
  sh->Render();
}

and SwapBuffers on paint form event

void GLCore::SwapBuffer()
{
  SwapBuffers(m_Hdc);
}

Why dont draw point?  glDrawArrays(GL_POINTS, 0, 1);

Share this post


Link to post
Share on other sites
arka80    1959

I can miss something, but I think you are actually not sending anything. Even if your vertex shader put a vertex, it needs at least one vertex in the gpu to be called, I suppose. You are missing the whole glBindBuffer/glBufferData/glVertexAttribArray family of calls. 

Edited by arka80

Share this post


Link to post
Share on other sites
Valera    106

You're setting the point size after the glDraw* call. You must set it before. Otherwise the point may be extremely small. There colud be other subtle differences.

See the reference implementation.

#pragma once
#include "GraphEngine.h"

class SinglePoint 

{
public:
	void startup()
	{
		static const char * vs_source[] =
		{
			"#version 420 core                             \n"
			"                                              \n"
			"void main(void)                               \n"
			"{                                             \n"
			"    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);   \n"
			"}                                             \n"
		};

		static const char * fs_source[] =
		{
			"#version 420 core                             \n"
			"                                              \n"
			"out vec4 color;                               \n"
			"                                              \n"
			"void main(void)                               \n"
			"{                                             \n"
			"    color = vec4(0.0, 0.8, 1.0, 1.0);         \n"
			"}                                             \n"
		};

		program = glCreateProgram();
		GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
		glShaderSource(fs, 1, fs_source, NULL);
		glCompileShader(fs);

		GLuint vs = glCreateShader(GL_VERTEX_SHADER);
		glShaderSource(vs, 1, vs_source, NULL);
		glCompileShader(vs);

		glAttachShader(program, vs);
		glAttachShader(program, fs);

		glLinkProgram(program);

		glGenVertexArrays(1, &vao);
		glBindVertexArray(vao);
	}

	void render(double currentTime)
	{
		static const GLfloat red[] = { 1.0f, 0.0f, 0.0f, 1.0f };
		glClearBufferfv(GL_COLOR, 0, red);

		glUseProgram(program);

		glPointSize(40.0f);

		glDrawArrays(GL_POINTS, 0, 1);
	}

	void shutdown()
	{
		glDeleteVertexArrays(1, &vao);
		glDeleteProgram(program);
	}

private:
	GLuint          program;
	GLuint          vao;
};

and

void GLCore::ClickOk()
{
	//sh = new Shaders();
	//sh->Startup();
	//sh->Render();
	auto v = new SinglePoint();
	v->startup();
	v->render(1.0);
	SwapBuffer();
}

Clear buffer is red color and not draw point(

Share this post


Link to post
Share on other sites
Valera    106

I can miss something, but I think you are actually not sending anything. Even if your vertex shader put a vertex, it needs at least one vertex in the gpu to be called, I suppose. You are missing the whole glBindBuffer/glBufferData/glVertexAttribArray family of calls. 

Why, then, in the example of the book about nothing written?

Share this post


Link to post
Share on other sites
arka80    1959

Because the sample doesn't need it (it is correct).
The vertex shader is not fetching data from the vertex buffer but rather sending a constant position.

Hence those calls are not needed.

 

but vertex shader is not called once per vertex? If there are 0 vertex, it never be called. Doesn't is the geometry shader the one who actually creates geometry?

Share this post


Link to post
Share on other sites
Xycaleth    2391

When you specify the vertex count (or index count) in glDrawArrays or glDrawElements, you're actually specifying the number of times the vertex shader should be run. Nothing else matters. Calling glVertexAttribPointer doesn't 'create vertices', it's setting up pointers from which the vertex shaders can fetch per-vertex attributes, but they aren't necessary.

Share this post


Link to post
Share on other sites
arka80    1959

Ok Valera, I understood... it's a bit silly and funny but... keep an eye on the color of your point in the fragment shader and the color of the glClear ph34r.png  

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this