OpengGL Superbible7, first example. Do not draw a point

Started by
7 comments, last by arka80 8 years, 6 months ago

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);

Advertisement

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.

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.

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(

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?

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.

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?

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.

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

This topic is closed to new replies.

Advertisement