Jump to content
  • Advertisement
Sign in to follow this  
Zomgbie

OpenGL OpenGLBook.com sample - I'm not getting it to work!

This topic is 2471 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello fellows!

So, i've been updating my OpenGL knowledge and managed to get stuck. I've followed the guides over at OpenGLBook.com and all was going well, untill i hit Chapter 4.
The code i've written is next to identical to their sample code, yet their code works and mine doesn't. I have even copy pasted my code into theirs, replacing every function with mine, and that still works. But my code alone is not up to the task sadly. There must be something i'm missing. Please, help me out!

My code


/*
* Free Glut test.
*/
#include "utils.h"

/* === DEFINITIONS === */
#define WINDOW_TITLE "Chapter 4: 3D"
#define SHADER_PROGRAM 0
#define SHADER_FRAGMENT 1
#define SHADER_VERTEX 2
#define BUFFER_VAO 0
#define BUFFER_VBO 1
#define BUFFER_IBO 2

/* === GLOBAL VARIABLES === */
GLuint projMatUniLoc, viewMatUniLoc, modelMatUniLoc;
GLuint bufferIds[3] = {0}, shaderIds[3] = {0};
int windowWidth, windowHeight, windowHandle;
float cubeRotation;
clock_t lastTime;
unsigned frames;

/* === MATRIXES === */
Matrix projectionMatrix, viewMatrix, modelMatrix;

/* === FUNCTION PROTOTYPES === */
void init(int, char **);
void initWindow(int, char **);
void resize(int, int);
void render(void);
void timer(int);
void idle(void);
void createCube(void);
void destroyCube(void);
void drawCube(void);

/*
* main():
* Main entry point of the application.
*/
int main(int argc, char **argv) {
/* Initialize everything we need */
init(argc, argv);

/* Start the glut loop */
glutMainLoop();

exit(EXIT_SUCCESS);
}

/*
* init(argc, argv):
* Initializes everything we need to start running.
*/
void init(int argc, char **argv) {
GLenum ret;
/* Create our openGL window */
windowWidth = 1024;
windowHeight = 768;
initWindow(argc, argv);

/* Initialize glew */
ret = glewInit();
if (GLEW_OK != ret) {
fprintf(stderr, "ERROR: %s\n", glewGetErrorString(ret));
exit(EXIT_FAILURE);
}

/* Get the running openGL version */
fprintf(stdout, "INFO: OpenGL Version: %s\n", glGetString(GL_VERSION));

/* Empty potential errors */
glGetError();

/* Clear the screen */
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

/* Enable depth test */
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
ExitOnGLError("ERROR: Could not set OpenGL depth testing");

/* Enable culling of faces */
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
ExitOnGLError("Error: Could not set OpenGL culling");

/* Setup out default matrices */
modelMatrix = IDENTITY_MATRIX;
projectionMatrix = IDENTITY_MATRIX;
viewMatrix = IDENTITY_MATRIX;
TranslateMatrix(&viewMatrix, 0, 0, -2);

/* Create our initial cube */
createCube();
}

/*
* initWindow(argc, argv):
* Create the openGL window for us.
*/
void initWindow(int argc, char **argv) {
/* Initialize glut */
glutInit(&argc, argv);
glutInitContextVersion(4, 0);
glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
glutInitWindowSize(windowWidth, windowHeight);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);

/* Create the window */
windowHandle = glutCreateWindow(WINDOW_TITLE);
if (windowHandle < 1) {
fprintf(stderr, "ERROR: Could not create window.\n");
exit(EXIT_FAILURE);
}

/* Set glut callback functions */
glutReshapeFunc(resize);
glutDisplayFunc(render);
glutIdleFunc(idle);
glutTimerFunc(0, timer, 0);
glutCloseFunc(destroyCube);
}

/*
* rezie(width, height):
* Resize the openGL window.
*/
void resize(int width, int height) {
/* Save dimensions */
windowWidth = width;
windowHeight = height;

/* Set viewport */
glViewport(0, 0, width, height);

/* Change our projection matrix */
projectionMatrix = CreateProjectionMatrix(60,
(float)windowWidth / windowHeight, 1.0f, 100.0f);
glUseProgram(shaderIds[0]);
glUniformMatrix4fv(projMatUniLoc, 1, GL_FALSE, projectionMatrix.m);
glUseProgram(0);
}

/*
* render()
* Render our openGL scene.
*/
void render(void) {
++frames;

/* Clear screen */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

/* Draw our cube */
drawCube();

/* Swap buffers and update display */
glutSwapBuffers();
glutPostRedisplay();
}

/*
* idle():
* Logic function.
*/
void idle(void) {
glutPostRedisplay();
}

/*
* timer(val):
* Timer to count FPS.
*/
void timer(int val) {
char fpsString[512];

if (val != 0) {
/* Allocate memory and copy string */
sprintf(fpsString, "%s: %d FPS @ %d x %d", WINDOW_TITLE,
frames * 4, windowWidth, windowHeight);

/* Set it as title */
glutSetWindowTitle(fpsString);
}

frames = 0;
glutTimerFunc(250, timer, 1);
}

/*
* createCube():
* Setup the cube.
*/
void createCube(void) {
const Vertex vertices[8] = {
{{-0.5f, -0.5f, 0.5f, 1}, {0, 0, 1, 1}},
{{-0.5f, 0.5f, 0.5f, 1}, {1, 0, 0, 1}},
{{0.5f, 0.5f, 0.5f, 1}, {0, 1, 0, 1}},
{{0.5f, -0.5f, 0.5f, 1}, {1, 1, 0, 1}},
{{-0.5f, -0.5f, -0.5f, 1}, {1, 1, 1, 1}},
{{-0.5f, 0.5f, -0.5f, 1}, {1, 0, 0, 1}},
{{0.5f, 0.5f, -0.5f, 1}, {1, 0, 1, 1}},
{{0.5f, -0.5f, -0.5f, 1}, {0, 0, 1, 1}}
};
const GLuint indices[36] = {
0, 2, 1, 0, 3, 2, 4, 3, 0, 4, 7, 3,
4, 1, 5, 4, 0, 1, 3, 6, 2, 3, 7, 6,
1, 6, 5, 1, 2, 6, 7, 5, 6, 7, 4, 5
};

/* Generate the shader program */
shaderIds[SHADER_PROGRAM] = glCreateProgram();
ExitOnGLError("ERROR: Could not create shader program");

/* Load and attach shaders */
shaderIds[SHADER_FRAGMENT] = LoadShader("fragment.glsl", GL_FRAGMENT_SHADER);
shaderIds[SHADER_VERTEX] = LoadShader("vertex.glsl", GL_VERTEX_SHADER);
glAttachShader(shaderIds[SHADER_PROGRAM], shaderIds[SHADER_FRAGMENT]);
glAttachShader(shaderIds[SHADER_PROGRAM], shaderIds[SHADER_VERTEX]);

/* Link shader program */
glLinkProgram(shaderIds[SHADER_PROGRAM]);
ExitOnGLError("ERROR: Could not link shader program");

/* Retrive shader uniforms */
modelMatUniLoc = glGetUniformLocation(shaderIds[SHADER_PROGRAM], "modelMatrix");
viewMatUniLoc = glGetUniformLocation(shaderIds[SHADER_PROGRAM], "viewMatrix");
projMatUniLoc = glGetUniformLocation(shaderIds[SHADER_PROGRAM], "projectionMatrix");
ExitOnGLError("ERROR: Could not get shader uniform locations");

/* Generate and bind our vertex array object */
glGenVertexArrays(1, &bufferIds[BUFFER_VAO]);
ExitOnGLError("ERROR: Could not generate VAO");
glBindVertexArray(bufferIds[BUFFER_VAO]);
ExitOnGLError("ERROR: Could not bind VAO");
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
ExitOnGLError("ERROR: Could not enable vertex attributes");

/* Bind VBO and send data */
glGenBuffers(2, &bufferIds[BUFFER_VBO]);
glBindBuffer(GL_ARRAY_BUFFER, bufferIds[BUFFER_VBO]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
ExitOnGLError("ERROR: Could not bind VBO to VAO");

/* Set the attributes for our VAO */
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(vertices[0]), (GLvoid *)0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(vertices[0]),
(GLvoid *)sizeof(vertices[0].Position));
ExitOnGLError("ERROR: Could not set VAO attributes");

/* Bind IBO and send data */
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferIds[BUFFER_IBO]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
ExitOnGLError("ERROR: Could not bind IBO to VAO");
glBindVertexArray(0);
}

/*
* destroyCube():
* Destroy out little cubie.
*/
void destroyCube(void) {
/* Detach and delete shaders */
glDetachShader(shaderIds[SHADER_PROGRAM], shaderIds[SHADER_FRAGMENT]);
glDetachShader(shaderIds[SHADER_PROGRAM], shaderIds[SHADER_VERTEX]);
glDeleteShader(shaderIds[SHADER_FRAGMENT]);
glDeleteShader(shaderIds[SHADER_VERTEX]);
glDeleteProgram(shaderIds[SHADER_PROGRAM]);
ExitOnGLError("ERROR: Could not destroy shaders");

/* Delete and destroy buffers */
glDeleteBuffers(2, &bufferIds[BUFFER_VBO]);
glDeleteVertexArrays(1, &bufferIds[BUFFER_VAO]);
ExitOnGLError("ERROR: Could not destroy buffer objects");
}

/*
* drawCube():
* Draw the cube.
*/
void drawCube(void) {
float cubeAngle;
clock_t now;

/* Current time */
now = clock();
if (lastTime == 0)
lastTime = now;

/* Adjust rotation */
cubeRotation += 45.0f * ((float)(now - lastTime) / CLOCKS_PER_SEC);
cubeAngle = DegreesToRadians(cubeRotation);
lastTime = now;

/* Rotate the matrix */
modelMatrix = IDENTITY_MATRIX;
RotateAboutY(&modelMatrix, cubeAngle);
RotateAboutX(&modelMatrix, cubeAngle);

/* Use the shader program so we can manipluate */
glUseProgram(shaderIds[SHADER_PROGRAM]);

/* Adjust matrix uniform locations */
glUniformMatrix4fv(modelMatUniLoc, 1, GL_FALSE, modelMatrix.m);
glUniformMatrix4fv(viewMatUniLoc, 1, GL_FALSE, viewMatrix.m);
ExitOnGLError("ERROR: Could not set the shader uniforms");

/* Bind and draw the VAO */
glBindVertexArray(bufferIds[BUFFER_VAO]);
ExitOnGLError("ERROR: Could not bind VAO for drawing");
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (GLvoid *)0);
ExitOnGLError("ERROR: Could not draw the cube");

/* Done manipulating */
glBindVertexArray(0);
glUseProgram(0);
}




Their code


/* Copyright (C) 2011 by Eddy Luten

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "Utils.h"
#define WINDOW_TITLE_PREFIX "Chapter 4"

int CurrentWidth = 800,
CurrentHeight = 600,
WindowHandle = 0;

unsigned FrameCount = 0;

GLuint
ProjectionMatrixUniformLocation,
ViewMatrixUniformLocation,
ModelMatrixUniformLocation,
BufferIds[3] = { 0 },
ShaderIds[3] = { 0 };

Matrix
ProjectionMatrix,
ViewMatrix,
ModelMatrix;

float CubeRotation = 0;
clock_t LastTime = 0;

void Initialize(int, char*[]);
void InitWindow(int, char*[]);
void ResizeFunction(int, int);
void RenderFunction(void);
void TimerFunction(int);
void IdleFunction(void);
void CreateCube(void);
void DestroyCube(void);
void DrawCube(void);

int main(int argc, char* argv[])
{
Initialize(argc, argv);

glutMainLoop();

exit(EXIT_SUCCESS);
}

void Initialize(int argc, char* argv[])
{
GLenum GlewInitResult;

InitWindow(argc, argv);

glewExperimental = GL_TRUE;
GlewInitResult = glewInit();

if (GLEW_OK != GlewInitResult) {
fprintf(
stderr,
"ERROR: %s\n",
glewGetErrorString(GlewInitResult)
);
exit(EXIT_FAILURE);
}

fprintf(
stdout,
"INFO: OpenGL Version: %s\n",
glGetString(GL_VERSION)
);

glGetError();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
ExitOnGLError("ERROR: Could not set OpenGL depth testing options");

glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
ExitOnGLError("ERROR: Could not set OpenGL culling options");

ModelMatrix = IDENTITY_MATRIX;
ProjectionMatrix = IDENTITY_MATRIX;
ViewMatrix = IDENTITY_MATRIX;
TranslateMatrix(&ViewMatrix, 0, 0, -2);

CreateCube();
}

void InitWindow(int argc, char* argv[])
{
glutInit(&argc, argv);

glutInitContextVersion(4, 0);
glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
glutInitContextProfile(GLUT_CORE_PROFILE);

glutSetOption(
GLUT_ACTION_ON_WINDOW_CLOSE,
GLUT_ACTION_GLUTMAINLOOP_RETURNS
);

glutInitWindowSize(CurrentWidth, CurrentHeight);

glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);

WindowHandle = glutCreateWindow(WINDOW_TITLE_PREFIX);

if(WindowHandle < 1) {
fprintf(
stderr,
"ERROR: Could not create a new rendering window.\n"
);
exit(EXIT_FAILURE);
}

glutReshapeFunc(ResizeFunction);
glutDisplayFunc(RenderFunction);
glutIdleFunc(IdleFunction);
glutTimerFunc(0, TimerFunction, 0);
glutCloseFunc(DestroyCube);
}

void ResizeFunction(int Width, int Height)
{
CurrentWidth = Width;
CurrentHeight = Height;
glViewport(0, 0, CurrentWidth, CurrentHeight);
ProjectionMatrix =
CreateProjectionMatrix(
60,
(float)CurrentWidth / CurrentHeight,
1.0f,
100.0f
);

glUseProgram(ShaderIds[0]);
glUniformMatrix4fv(ProjectionMatrixUniformLocation, 1, GL_FALSE, ProjectionMatrix.m);
glUseProgram(0);
}

void RenderFunction(void)
{
++FrameCount;

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

DrawCube();

glutSwapBuffers();
glutPostRedisplay();
}

void IdleFunction(void)
{
glutPostRedisplay();
}

void TimerFunction(int Value)
{
if (0 != Value) {
char* TempString = (char*)
malloc(512 + strlen(WINDOW_TITLE_PREFIX));

sprintf(
TempString,
"%s: %d Frames Per Second @ %d x %d",
WINDOW_TITLE_PREFIX,
FrameCount * 4,
CurrentWidth,
CurrentHeight
);

glutSetWindowTitle(TempString);
free(TempString);
}

FrameCount = 0;
glutTimerFunc(250, TimerFunction, 1);
}

void CreateCube()
{
const Vertex VERTICES[8] =
{
{ { -.5f, -.5f, .5f, 1 }, { 0, 0, 1, 1 } },
{ { -.5f, .5f, .5f, 1 }, { 1, 0, 0, 1 } },
{ { .5f, .5f, .5f, 1 }, { 0, 1, 0, 1 } },
{ { .5f, -.5f, .5f, 1 }, { 1, 1, 0, 1 } },
{ { -.5f, -.5f, -.5f, 1 }, { 1, 1, 1, 1 } },
{ { -.5f, .5f, -.5f, 1 }, { 1, 0, 0, 1 } },
{ { .5f, .5f, -.5f, 1 }, { 1, 0, 1, 1 } },
{ { .5f, -.5f, -.5f, 1 }, { 0, 0, 1, 1 } }
};

const GLuint INDICES[36] =
{
0,2,1, 0,3,2,
4,3,0, 4,7,3,
4,1,5, 4,0,1,
3,6,2, 3,7,6,
1,6,5, 1,2,6,
7,5,6, 7,4,5
};

ShaderIds[0] = glCreateProgram();
ExitOnGLError("ERROR: Could not create the shader program");
{
ShaderIds[1] = LoadShader("SimpleShader.fragment.glsl", GL_FRAGMENT_SHADER);
ShaderIds[2] = LoadShader("SimpleShader.vertex.glsl", GL_VERTEX_SHADER);
glAttachShader(ShaderIds[0], ShaderIds[1]);
glAttachShader(ShaderIds[0], ShaderIds[2]);
}
glLinkProgram(ShaderIds[0]);
ExitOnGLError("ERROR: Could not link the shader program");

ModelMatrixUniformLocation = glGetUniformLocation(ShaderIds[0], "ModelMatrix");
ViewMatrixUniformLocation = glGetUniformLocation(ShaderIds[0], "ViewMatrix");
ProjectionMatrixUniformLocation = glGetUniformLocation(ShaderIds[0], "ProjectionMatrix");
ExitOnGLError("ERROR: Could not get shader uniform locations");

glGenVertexArrays(1, &BufferIds[0]);
ExitOnGLError("ERROR: Could not generate the VAO");
glBindVertexArray(BufferIds[0]);
ExitOnGLError("ERROR: Could not bind the VAO");

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
ExitOnGLError("ERROR: Could not enable vertex attributes");

glGenBuffers(2, &BufferIds[1]);
ExitOnGLError("ERROR: Could not generate the buffer objects");

glBindBuffer(GL_ARRAY_BUFFER, BufferIds[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(VERTICES), VERTICES, GL_STATIC_DRAW);
ExitOnGLError("ERROR: Could not bind the VBO to the VAO");

glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(VERTICES[0]), (GLvoid*)0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(VERTICES[0]), (GLvoid*)sizeof(VERTICES[0].Position));
ExitOnGLError("ERROR: Could not set VAO attributes");

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, BufferIds[2]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(INDICES), INDICES, GL_STATIC_DRAW);
ExitOnGLError("ERROR: Could not bind the IBO to the VAO");

glBindVertexArray(0);
}

void DestroyCube()
{
glDetachShader(ShaderIds[0], ShaderIds[1]);
glDetachShader(ShaderIds[0], ShaderIds[2]);
glDeleteShader(ShaderIds[1]);
glDeleteShader(ShaderIds[2]);
glDeleteProgram(ShaderIds[0]);
ExitOnGLError("ERROR: Could not destroy the shaders");

glDeleteBuffers(2, &BufferIds[1]);
glDeleteVertexArrays(1, &BufferIds[0]);
ExitOnGLError("ERROR: Could not destroy the buffer objects");
}

void DrawCube(void)
{
float CubeAngle;
clock_t Now = clock();

if (LastTime == 0)
LastTime = Now;

CubeRotation += 45.0f * ((float)(Now - LastTime) / CLOCKS_PER_SEC);
CubeAngle = DegreesToRadians(CubeRotation);
LastTime = Now;

ModelMatrix = IDENTITY_MATRIX;
RotateAboutY(&ModelMatrix, CubeAngle);
RotateAboutX(&ModelMatrix, CubeAngle);

glUseProgram(ShaderIds[0]);
ExitOnGLError("ERROR: Could not use the shader program");

glUniformMatrix4fv(ModelMatrixUniformLocation, 1, GL_FALSE, ModelMatrix.m);
glUniformMatrix4fv(ViewMatrixUniformLocation, 1, GL_FALSE, ViewMatrix.m);
ExitOnGLError("ERROR: Could not set the shader uniforms");

glBindVertexArray(BufferIds[0]);
ExitOnGLError("ERROR: Could not bind the VAO for drawing purposes");

glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (GLvoid*)0);
ExitOnGLError("ERROR: Could not draw the cube");

glBindVertexArray(0);
glUseProgram(0);
}

Share this post


Link to post
Share on other sites
Advertisement
What is happening? What "won't work"? Compile error? Crash? Black Screen? Any debug info?

Share this post


Link to post
Share on other sites
Hi Zomgbie,

What exactly doesn't work? You could provide some more specific information besides simply pasting the code from the samples:

Do you get any errors, black screens, can you tell me anything about the output? What platform are you on? What hardware are you using? Are you checking glGetError along the way?



The more info you can provide, the better.


Eddy


Hello fellows!

So, i've been updating my OpenGL knowledge and managed to get stuck. I've followed the guides over at OpenGLBook.com and all was going well, untill i hit Chapter 4.
The code i've written is next to identical to their sample code, yet their code works and mine doesn't. I have even copy pasted my code into theirs, replacing every function with mine, and that still works. But my code alone is not up to the task sadly. There must be something i'm missing. Please, help me out!

My code


/*
* Free Glut test.
*/
#include "utils.h"

/* === DEFINITIONS === */
#define WINDOW_TITLE "Chapter 4: 3D"
#define SHADER_PROGRAM 0
#define SHADER_FRAGMENT 1
#define SHADER_VERTEX 2
#define BUFFER_VAO 0
#define BUFFER_VBO 1
#define BUFFER_IBO 2

/* === GLOBAL VARIABLES === */
GLuint projMatUniLoc, viewMatUniLoc, modelMatUniLoc;
GLuint bufferIds[3] = {0}, shaderIds[3] = {0};
int windowWidth, windowHeight, windowHandle;
float cubeRotation;
clock_t lastTime;
unsigned frames;

/* === MATRIXES === */
Matrix projectionMatrix, viewMatrix, modelMatrix;

/* === FUNCTION PROTOTYPES === */
void init(int, char **);
void initWindow(int, char **);
void resize(int, int);
void render(void);
void timer(int);
void idle(void);
void createCube(void);
void destroyCube(void);
void drawCube(void);

/*
* main():
* Main entry point of the application.
*/
int main(int argc, char **argv) {
/* Initialize everything we need */
init(argc, argv);

/* Start the glut loop */
glutMainLoop();

exit(EXIT_SUCCESS);
}

/*
* init(argc, argv):
* Initializes everything we need to start running.
*/
void init(int argc, char **argv) {
GLenum ret;
/* Create our openGL window */
windowWidth = 1024;
windowHeight = 768;
initWindow(argc, argv);

/* Initialize glew */
ret = glewInit();
if (GLEW_OK != ret) {
fprintf(stderr, "ERROR: %s\n", glewGetErrorString(ret));
exit(EXIT_FAILURE);
}

/* Get the running openGL version */
fprintf(stdout, "INFO: OpenGL Version: %s\n", glGetString(GL_VERSION));

/* Empty potential errors */
glGetError();

/* Clear the screen */
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

/* Enable depth test */
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
ExitOnGLError("ERROR: Could not set OpenGL depth testing");

/* Enable culling of faces */
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
ExitOnGLError("Error: Could not set OpenGL culling");

/* Setup out default matrices */
modelMatrix = IDENTITY_MATRIX;
projectionMatrix = IDENTITY_MATRIX;
viewMatrix = IDENTITY_MATRIX;
TranslateMatrix(&viewMatrix, 0, 0, -2);

/* Create our initial cube */
createCube();
}

/*
* initWindow(argc, argv):
* Create the openGL window for us.
*/
void initWindow(int argc, char **argv) {
/* Initialize glut */
glutInit(&argc, argv);
glutInitContextVersion(4, 0);
glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
glutInitWindowSize(windowWidth, windowHeight);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);

/* Create the window */
windowHandle = glutCreateWindow(WINDOW_TITLE);
if (windowHandle < 1) {
fprintf(stderr, "ERROR: Could not create window.\n");
exit(EXIT_FAILURE);
}

/* Set glut callback functions */
glutReshapeFunc(resize);
glutDisplayFunc(render);
glutIdleFunc(idle);
glutTimerFunc(0, timer, 0);
glutCloseFunc(destroyCube);
}

/*
* rezie(width, height):
* Resize the openGL window.
*/
void resize(int width, int height) {
/* Save dimensions */
windowWidth = width;
windowHeight = height;

/* Set viewport */
glViewport(0, 0, width, height);

/* Change our projection matrix */
projectionMatrix = CreateProjectionMatrix(60,
(float)windowWidth / windowHeight, 1.0f, 100.0f);
glUseProgram(shaderIds[0]);
glUniformMatrix4fv(projMatUniLoc, 1, GL_FALSE, projectionMatrix.m);
glUseProgram(0);
}

/*
* render()
* Render our openGL scene.
*/
void render(void) {
++frames;

/* Clear screen */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

/* Draw our cube */
drawCube();

/* Swap buffers and update display */
glutSwapBuffers();
glutPostRedisplay();
}

/*
* idle():
* Logic function.
*/
void idle(void) {
glutPostRedisplay();
}

/*
* timer(val):
* Timer to count FPS.
*/
void timer(int val) {
char fpsString[512];

if (val != 0) {
/* Allocate memory and copy string */
sprintf(fpsString, "%s: %d FPS @ %d x %d", WINDOW_TITLE,
frames * 4, windowWidth, windowHeight);

/* Set it as title */
glutSetWindowTitle(fpsString);
}

frames = 0;
glutTimerFunc(250, timer, 1);
}

/*
* createCube():
* Setup the cube.
*/
void createCube(void) {
const Vertex vertices[8] = {
{{-0.5f, -0.5f, 0.5f, 1}, {0, 0, 1, 1}},
{{-0.5f, 0.5f, 0.5f, 1}, {1, 0, 0, 1}},
{{0.5f, 0.5f, 0.5f, 1}, {0, 1, 0, 1}},
{{0.5f, -0.5f, 0.5f, 1}, {1, 1, 0, 1}},
{{-0.5f, -0.5f, -0.5f, 1}, {1, 1, 1, 1}},
{{-0.5f, 0.5f, -0.5f, 1}, {1, 0, 0, 1}},
{{0.5f, 0.5f, -0.5f, 1}, {1, 0, 1, 1}},
{{0.5f, -0.5f, -0.5f, 1}, {0, 0, 1, 1}}
};
const GLuint indices[36] = {
0, 2, 1, 0, 3, 2, 4, 3, 0, 4, 7, 3,
4, 1, 5, 4, 0, 1, 3, 6, 2, 3, 7, 6,
1, 6, 5, 1, 2, 6, 7, 5, 6, 7, 4, 5
};

/* Generate the shader program */
shaderIds[SHADER_PROGRAM] = glCreateProgram();
ExitOnGLError("ERROR: Could not create shader program");

/* Load and attach shaders */
shaderIds[SHADER_FRAGMENT] = LoadShader("fragment.glsl", GL_FRAGMENT_SHADER);
shaderIds[SHADER_VERTEX] = LoadShader("vertex.glsl", GL_VERTEX_SHADER);
glAttachShader(shaderIds[SHADER_PROGRAM], shaderIds[SHADER_FRAGMENT]);
glAttachShader(shaderIds[SHADER_PROGRAM], shaderIds[SHADER_VERTEX]);

/* Link shader program */
glLinkProgram(shaderIds[SHADER_PROGRAM]);
ExitOnGLError("ERROR: Could not link shader program");

/* Retrive shader uniforms */
modelMatUniLoc = glGetUniformLocation(shaderIds[SHADER_PROGRAM], "modelMatrix");
viewMatUniLoc = glGetUniformLocation(shaderIds[SHADER_PROGRAM], "viewMatrix");
projMatUniLoc = glGetUniformLocation(shaderIds[SHADER_PROGRAM], "projectionMatrix");
ExitOnGLError("ERROR: Could not get shader uniform locations");

/* Generate and bind our vertex array object */
glGenVertexArrays(1, &bufferIds[BUFFER_VAO]);
ExitOnGLError("ERROR: Could not generate VAO");
glBindVertexArray(bufferIds[BUFFER_VAO]);
ExitOnGLError("ERROR: Could not bind VAO");
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
ExitOnGLError("ERROR: Could not enable vertex attributes");

/* Bind VBO and send data */
glGenBuffers(2, &bufferIds[BUFFER_VBO]);
glBindBuffer(GL_ARRAY_BUFFER, bufferIds[BUFFER_VBO]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
ExitOnGLError("ERROR: Could not bind VBO to VAO");

/* Set the attributes for our VAO */
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(vertices[0]), (GLvoid *)0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(vertices[0]),
(GLvoid *)sizeof(vertices[0].Position));
ExitOnGLError("ERROR: Could not set VAO attributes");

/* Bind IBO and send data */
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferIds[BUFFER_IBO]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
ExitOnGLError("ERROR: Could not bind IBO to VAO");
glBindVertexArray(0);
}

/*
* destroyCube():
* Destroy out little cubie.
*/
void destroyCube(void) {
/* Detach and delete shaders */
glDetachShader(shaderIds[SHADER_PROGRAM], shaderIds[SHADER_FRAGMENT]);
glDetachShader(shaderIds[SHADER_PROGRAM], shaderIds[SHADER_VERTEX]);
glDeleteShader(shaderIds[SHADER_FRAGMENT]);
glDeleteShader(shaderIds[SHADER_VERTEX]);
glDeleteProgram(shaderIds[SHADER_PROGRAM]);
ExitOnGLError("ERROR: Could not destroy shaders");

/* Delete and destroy buffers */
glDeleteBuffers(2, &bufferIds[BUFFER_VBO]);
glDeleteVertexArrays(1, &bufferIds[BUFFER_VAO]);
ExitOnGLError("ERROR: Could not destroy buffer objects");
}

/*
* drawCube():
* Draw the cube.
*/
void drawCube(void) {
float cubeAngle;
clock_t now;

/* Current time */
now = clock();
if (lastTime == 0)
lastTime = now;

/* Adjust rotation */
cubeRotation += 45.0f * ((float)(now - lastTime) / CLOCKS_PER_SEC);
cubeAngle = DegreesToRadians(cubeRotation);
lastTime = now;

/* Rotate the matrix */
modelMatrix = IDENTITY_MATRIX;
RotateAboutY(&modelMatrix, cubeAngle);
RotateAboutX(&modelMatrix, cubeAngle);

/* Use the shader program so we can manipluate */
glUseProgram(shaderIds[SHADER_PROGRAM]);

/* Adjust matrix uniform locations */
glUniformMatrix4fv(modelMatUniLoc, 1, GL_FALSE, modelMatrix.m);
glUniformMatrix4fv(viewMatUniLoc, 1, GL_FALSE, viewMatrix.m);
ExitOnGLError("ERROR: Could not set the shader uniforms");

/* Bind and draw the VAO */
glBindVertexArray(bufferIds[BUFFER_VAO]);
ExitOnGLError("ERROR: Could not bind VAO for drawing");
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (GLvoid *)0);
ExitOnGLError("ERROR: Could not draw the cube");

/* Done manipulating */
glBindVertexArray(0);
glUseProgram(0);
}




Their code


/* Copyright (C) 2011 by Eddy Luten

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "Utils.h"
#define WINDOW_TITLE_PREFIX "Chapter 4"

int CurrentWidth = 800,
CurrentHeight = 600,
WindowHandle = 0;

unsigned FrameCount = 0;

GLuint
ProjectionMatrixUniformLocation,
ViewMatrixUniformLocation,
ModelMatrixUniformLocation,
BufferIds[3] = { 0 },
ShaderIds[3] = { 0 };

Matrix
ProjectionMatrix,
ViewMatrix,
ModelMatrix;

float CubeRotation = 0;
clock_t LastTime = 0;

void Initialize(int, char*[]);
void InitWindow(int, char*[]);
void ResizeFunction(int, int);
void RenderFunction(void);
void TimerFunction(int);
void IdleFunction(void);
void CreateCube(void);
void DestroyCube(void);
void DrawCube(void);

int main(int argc, char* argv[])
{
Initialize(argc, argv);

glutMainLoop();

exit(EXIT_SUCCESS);
}

void Initialize(int argc, char* argv[])
{
GLenum GlewInitResult;

InitWindow(argc, argv);

glewExperimental = GL_TRUE;
GlewInitResult = glewInit();

if (GLEW_OK != GlewInitResult) {
fprintf(
stderr,
"ERROR: %s\n",
glewGetErrorString(GlewInitResult)
);
exit(EXIT_FAILURE);
}

fprintf(
stdout,
"INFO: OpenGL Version: %s\n",
glGetString(GL_VERSION)
);

glGetError();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
ExitOnGLError("ERROR: Could not set OpenGL depth testing options");

glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
ExitOnGLError("ERROR: Could not set OpenGL culling options");

ModelMatrix = IDENTITY_MATRIX;
ProjectionMatrix = IDENTITY_MATRIX;
ViewMatrix = IDENTITY_MATRIX;
TranslateMatrix(&ViewMatrix, 0, 0, -2);

CreateCube();
}

void InitWindow(int argc, char* argv[])
{
glutInit(&argc, argv);

glutInitContextVersion(4, 0);
glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
glutInitContextProfile(GLUT_CORE_PROFILE);

glutSetOption(
GLUT_ACTION_ON_WINDOW_CLOSE,
GLUT_ACTION_GLUTMAINLOOP_RETURNS
);

glutInitWindowSize(CurrentWidth, CurrentHeight);

glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);

WindowHandle = glutCreateWindow(WINDOW_TITLE_PREFIX);

if(WindowHandle < 1) {
fprintf(
stderr,
"ERROR: Could not create a new rendering window.\n"
);
exit(EXIT_FAILURE);
}

glutReshapeFunc(ResizeFunction);
glutDisplayFunc(RenderFunction);
glutIdleFunc(IdleFunction);
glutTimerFunc(0, TimerFunction, 0);
glutCloseFunc(DestroyCube);
}

void ResizeFunction(int Width, int Height)
{
CurrentWidth = Width;
CurrentHeight = Height;
glViewport(0, 0, CurrentWidth, CurrentHeight);
ProjectionMatrix =
CreateProjectionMatrix(
60,
(float)CurrentWidth / CurrentHeight,
1.0f,
100.0f
);

glUseProgram(ShaderIds[0]);
glUniformMatrix4fv(ProjectionMatrixUniformLocation, 1, GL_FALSE, ProjectionMatrix.m);
glUseProgram(0);
}

void RenderFunction(void)
{
++FrameCount;

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

DrawCube();

glutSwapBuffers();
glutPostRedisplay();
}

void IdleFunction(void)
{
glutPostRedisplay();
}

void TimerFunction(int Value)
{
if (0 != Value) {
char* TempString = (char*)
malloc(512 + strlen(WINDOW_TITLE_PREFIX));

sprintf(
TempString,
"%s: %d Frames Per Second @ %d x %d",
WINDOW_TITLE_PREFIX,
FrameCount * 4,
CurrentWidth,
CurrentHeight
);

glutSetWindowTitle(TempString);
free(TempString);
}

FrameCount = 0;
glutTimerFunc(250, TimerFunction, 1);
}

void CreateCube()
{
const Vertex VERTICES[8] =
{
{ { -.5f, -.5f, .5f, 1 }, { 0, 0, 1, 1 } },
{ { -.5f, .5f, .5f, 1 }, { 1, 0, 0, 1 } },
{ { .5f, .5f, .5f, 1 }, { 0, 1, 0, 1 } },
{ { .5f, -.5f, .5f, 1 }, { 1, 1, 0, 1 } },
{ { -.5f, -.5f, -.5f, 1 }, { 1, 1, 1, 1 } },
{ { -.5f, .5f, -.5f, 1 }, { 1, 0, 0, 1 } },
{ { .5f, .5f, -.5f, 1 }, { 1, 0, 1, 1 } },
{ { .5f, -.5f, -.5f, 1 }, { 0, 0, 1, 1 } }
};

const GLuint INDICES[36] =
{
0,2,1, 0,3,2,
4,3,0, 4,7,3,
4,1,5, 4,0,1,
3,6,2, 3,7,6,
1,6,5, 1,2,6,
7,5,6, 7,4,5
};

ShaderIds[0] = glCreateProgram();
ExitOnGLError("ERROR: Could not create the shader program");
{
ShaderIds[1] = LoadShader("SimpleShader.fragment.glsl", GL_FRAGMENT_SHADER);
ShaderIds[2] = LoadShader("SimpleShader.vertex.glsl", GL_VERTEX_SHADER);
glAttachShader(ShaderIds[0], ShaderIds[1]);
glAttachShader(ShaderIds[0], ShaderIds[2]);
}
glLinkProgram(ShaderIds[0]);
ExitOnGLError("ERROR: Could not link the shader program");

ModelMatrixUniformLocation = glGetUniformLocation(ShaderIds[0], "ModelMatrix");
ViewMatrixUniformLocation = glGetUniformLocation(ShaderIds[0], "ViewMatrix");
ProjectionMatrixUniformLocation = glGetUniformLocation(ShaderIds[0], "ProjectionMatrix");
ExitOnGLError("ERROR: Could not get shader uniform locations");

glGenVertexArrays(1, &BufferIds[0]);
ExitOnGLError("ERROR: Could not generate the VAO");
glBindVertexArray(BufferIds[0]);
ExitOnGLError("ERROR: Could not bind the VAO");

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
ExitOnGLError("ERROR: Could not enable vertex attributes");

glGenBuffers(2, &BufferIds[1]);
ExitOnGLError("ERROR: Could not generate the buffer objects");

glBindBuffer(GL_ARRAY_BUFFER, BufferIds[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(VERTICES), VERTICES, GL_STATIC_DRAW);
ExitOnGLError("ERROR: Could not bind the VBO to the VAO");

glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(VERTICES[0]), (GLvoid*)0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(VERTICES[0]), (GLvoid*)sizeof(VERTICES[0].Position));
ExitOnGLError("ERROR: Could not set VAO attributes");

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, BufferIds[2]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(INDICES), INDICES, GL_STATIC_DRAW);
ExitOnGLError("ERROR: Could not bind the IBO to the VAO");

glBindVertexArray(0);
}

void DestroyCube()
{
glDetachShader(ShaderIds[0], ShaderIds[1]);
glDetachShader(ShaderIds[0], ShaderIds[2]);
glDeleteShader(ShaderIds[1]);
glDeleteShader(ShaderIds[2]);
glDeleteProgram(ShaderIds[0]);
ExitOnGLError("ERROR: Could not destroy the shaders");

glDeleteBuffers(2, &BufferIds[1]);
glDeleteVertexArrays(1, &BufferIds[0]);
ExitOnGLError("ERROR: Could not destroy the buffer objects");
}

void DrawCube(void)
{
float CubeAngle;
clock_t Now = clock();

if (LastTime == 0)
LastTime = Now;

CubeRotation += 45.0f * ((float)(Now - LastTime) / CLOCKS_PER_SEC);
CubeAngle = DegreesToRadians(CubeRotation);
LastTime = Now;

ModelMatrix = IDENTITY_MATRIX;
RotateAboutY(&ModelMatrix, CubeAngle);
RotateAboutX(&ModelMatrix, CubeAngle);

glUseProgram(ShaderIds[0]);
ExitOnGLError("ERROR: Could not use the shader program");

glUniformMatrix4fv(ModelMatrixUniformLocation, 1, GL_FALSE, ModelMatrix.m);
glUniformMatrix4fv(ViewMatrixUniformLocation, 1, GL_FALSE, ViewMatrix.m);
ExitOnGLError("ERROR: Could not set the shader uniforms");

glBindVertexArray(BufferIds[0]);
ExitOnGLError("ERROR: Could not bind the VAO for drawing purposes");

glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (GLvoid*)0);
ExitOnGLError("ERROR: Could not draw the cube");

glBindVertexArray(0);
glUseProgram(0);
}

Share this post


Link to post
Share on other sites
Hello again folks, thank you for the fast answers!

I'm not getting any error outputs at all. The thing that "doesn't work" is that the screen is entierly black. The nice little cube is missing.

Share this post


Link to post
Share on other sites
Can you post your shaders as well? For one thing its not good to use hardcoded indexes (0/1) for your attribs. You should query the attribute indexes for your shader inputs via glGetAttribLocation, then use the returned value to index it.

I'm not sure you can just assume you can always assign 0 to vertex position unless you're using deprecated shader builtin variables, which I don't know if you are or not.

Share this post


Link to post
Share on other sites
I'm using the same shaders as the example that works:

Vertex:


#version 400

layout(location=0) in vec4 in_Position;
layout(location=1) in vec4 in_Color;
out vec4 ex_Color;

uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix;

void main(void)
{
gl_Position = (ProjectionMatrix * ViewMatrix * ModelMatrix) * in_Position;
ex_Color = in_Color;
}


Fragment:


#version 400

in vec4 ex_Color;
out vec4 out_Color;

void main(void)
{
out_Color = ex_Color;
}

Share this post


Link to post
Share on other sites
You changed the casing in your call to glGetUniformLocation to lower camel case ([color=#660066][font=CourierNew, monospace][size=2]modelMatrix[/font]), while the names of the uniforms in the shaders remain upper camel case ([color=#660066][font=CourierNew, monospace][size=2]ModelMatrix[/font]), that may be why it's not working. Let me know.

Share this post


Link to post
Share on other sites
Thank you, that was the problem!

I'd also like to thank you for those awesome guides. They are very helpfull and well written <3

Share this post


Link to post
Share on other sites
I even didn't know that such website exists.
Will there be more than 4 chapters?

Or that's all?
Big .com website for only 4 chapters is pretty expensive.


But if you're going to expand it, then it's good.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
  • Advertisement
  • Popular Tags

  • Popular Now

  • Advertisement
  • Similar Content

    • By LukasBanana
      Hi all,
       
      I'm trying to generate MIP-maps of a 2D-array texture, but only a limited amount of array layers and MIP-levels.
      For instance, to generate only the first 3 MIP-maps of a single array layer of a large 2D-array.
       
      After experimenting with glBlitFramebuffer to generate the MIP-maps manually but still with some sort of hardware acceleration,
      I ended up with glTextureView which already works with the limited amount of array layers (I can also verify the result in RenderDoc).
      However, glGenerateMipmap (or glGenerateTextureMipmap) always generates the entire MIP-chain for the specified array layer.
       
      Thus, the <numlevels> parameter of glTextureView seems to be ignored in the MIP-map generation process.
      I also tried to use glTexParameteri(..., GL_TEXTURE_MAX_LEVEL, 3), but this has the same result.
      Can anyone explain me how to solve this?
       
      Here is an example code, how I do it:
      void GenerateSubMips( GLuint texID, GLenum texTarget, GLenum internalFormat, GLuint baseMipLevel, GLuint numMipLevels, GLuint baseArrayLayer, GLuint numArrayLayers) { GLuint texViewID = 0; glGenTextures(1, &texViewID); glTextureView( texViewID, texTarget, texID, internalFormat, baseMipLevel, numMipLevels, baseArrayLayer, numArrayLayers ); glGenerateTextureMipmap(texViewID); glDeleteTextures(1, &texViewID); } GenerateSubMips( myTex, GL_TEXTURE_2D_ARRAY, GL_RGBA8, 0, 3, // only the first 3 MIP-maps 4, 1 // only one array layer with index 4 );  
      Thanks and kind regards,
      Lukas
    • By mmmax3d
      Hi everyone,
      I would need some assistance from anyone who has a similar experience
      or a nice idea!
      I have created a skybox (as cube) and now I need to add a floor/ground.
      The skybox is created from cubemap and initially it was infinite.
      Now it is finite with a specific size. The floor is a quad in the middle
      of the skybox, like a horizon.
      I have two problems:
      When moving the skybox upwards or downwards, I need to
      sample from points even above the horizon while sampling
      from the botton at the same time.  I am trying to create a seamless blending of the texture
      at the points of the horizon, when the quad is connected
      to the skybox. However, I get skew effects. Does anybody has done sth similar?
      Is there any good practice?
      Thanks everyone!
    • By mmmax3d
      Hi everyone,
      I would need some assistance from anyone who has a similar experience
      or a nice idea!
      I have created a skybox (as cube) and now I need to add a floor/ground.
      The skybox is created from cubemap and initially it was infinite.
      Now it is finite with a specific size. The floor is a quad in the middle
      of the skybox, like a horizon.
      I have two problems:
      When moving the skybox upwards or downwards, I need to
      sample from points even above the horizon while sampling
      from the botton at the same time.  I am trying to create a seamless blending of the texture
      at the points of the horizon, when the quad is connected
      to the skybox. However, I get skew effects. Does anybody has done sth similar?
      Is there any good practice?
      Thanks everyone!
    • By iArtist93
      I'm trying to implement PBR into my simple OpenGL renderer and trying to use multiple lighting passes, I'm using one pass per light for rendering as follow:
      1- First pass = depth
      2- Second pass = ambient
      3- [3 .. n] for all the lights in the scene.
      I'm using the blending function glBlendFunc(GL_ONE, GL_ONE) for passes [3..n], and i'm doing a Gamma Correction at the end of each fragment shader.
      But i still have a problem with the output image it just looks noisy specially when i'm using texture maps.
      Is there anything wrong with those steps or is there any improvement to this process?
    • By babaliaris
      Hello Everyone!
      I'm learning openGL, and currently i'm making a simple 2D game engine to test what I've learn so far.  In order to not say to much, i made a video in which i'm showing you the behavior of the rendering.
      Video: 
       
      What i was expecting to happen, was the player moving around. When i render only the player, he moves as i would expect. When i add a second Sprite object, instead of the Player, this new sprite object is moving and finally if i add a third Sprite object the third one is moving. And the weird think is that i'm transforming the Vertices of the Player so why the transformation is being applied somewhere else?
       
      Take a look at my code:
      Sprite Class
      (You mostly need to see the Constructor, the Render Method and the Move Method)
      #include "Brain.h" #include <glm/gtc/matrix_transform.hpp> #include <vector> struct Sprite::Implementation { //Position. struct pos pos; //Tag. std::string tag; //Texture. Texture *texture; //Model matrix. glm::mat4 model; //Vertex Array Object. VertexArray *vao; //Vertex Buffer Object. VertexBuffer *vbo; //Layout. VertexBufferLayout *layout; //Index Buffer Object. IndexBuffer *ibo; //Shader. Shader *program; //Brains. std::vector<Brain *> brains; //Deconstructor. ~Implementation(); }; Sprite::Sprite(std::string image_path, std::string tag, float x, float y) { //Create Pointer To Implementaion. m_Impl = new Implementation(); //Set the Position of the Sprite object. m_Impl->pos.x = x; m_Impl->pos.y = y; //Set the tag. m_Impl->tag = tag; //Create The Texture. m_Impl->texture = new Texture(image_path); //Initialize the model Matrix. m_Impl->model = glm::mat4(1.0f); //Get the Width and the Height of the Texture. int width = m_Impl->texture->GetWidth(); int height = m_Impl->texture->GetHeight(); //Create the Verticies. float verticies[] = { //Positions //Texture Coordinates. x, y, 0.0f, 0.0f, x + width, y, 1.0f, 0.0f, x + width, y + height, 1.0f, 1.0f, x, y + height, 0.0f, 1.0f }; //Create the Indicies. unsigned int indicies[] = { 0, 1, 2, 2, 3, 0 }; //Create Vertex Array. m_Impl->vao = new VertexArray(); //Create the Vertex Buffer. m_Impl->vbo = new VertexBuffer((void *)verticies, sizeof(verticies)); //Create The Layout. m_Impl->layout = new VertexBufferLayout(); m_Impl->layout->PushFloat(2); m_Impl->layout->PushFloat(2); m_Impl->vao->AddBuffer(m_Impl->vbo, m_Impl->layout); //Create the Index Buffer. m_Impl->ibo = new IndexBuffer(indicies, 6); //Create the new shader. m_Impl->program = new Shader("Shaders/SpriteShader.shader"); } //Render. void Sprite::Render(Window * window) { //Create the projection Matrix based on the current window width and height. glm::mat4 proj = glm::ortho(0.0f, (float)window->GetWidth(), 0.0f, (float)window->GetHeight(), -1.0f, 1.0f); //Set the MVP Uniform. m_Impl->program->setUniformMat4f("u_MVP", proj * m_Impl->model); //Run All The Brains (Scripts) of this game object (sprite). for (unsigned int i = 0; i < m_Impl->brains.size(); i++) { //Get Current Brain. Brain *brain = m_Impl->brains[i]; //Call the start function only once! if (brain->GetStart()) { brain->SetStart(false); brain->Start(); } //Call the update function every frame. brain->Update(); } //Render. window->GetRenderer()->Draw(m_Impl->vao, m_Impl->ibo, m_Impl->texture, m_Impl->program); } void Sprite::Move(float speed, bool left, bool right, bool up, bool down) { if (left) { m_Impl->pos.x -= speed; m_Impl->model = glm::translate(m_Impl->model, glm::vec3(-speed, 0, 0)); } if (right) { m_Impl->pos.x += speed; m_Impl->model = glm::translate(m_Impl->model, glm::vec3(speed, 0, 0)); } if (up) { m_Impl->pos.y += speed; m_Impl->model = glm::translate(m_Impl->model, glm::vec3(0, speed, 0)); } if (down) { m_Impl->pos.y -= speed; m_Impl->model = glm::translate(m_Impl->model, glm::vec3(0, -speed, 0)); } } void Sprite::AddBrain(Brain * brain) { //Push back the brain object. m_Impl->brains.push_back(brain); } pos *Sprite::GetPos() { return &m_Impl->pos; } std::string Sprite::GetTag() { return m_Impl->tag; } int Sprite::GetWidth() { return m_Impl->texture->GetWidth(); } int Sprite::GetHeight() { return m_Impl->texture->GetHeight(); } Sprite::~Sprite() { delete m_Impl; } //Implementation Deconstructor. Sprite::Implementation::~Implementation() { delete texture; delete vao; delete vbo; delete layout; delete ibo; delete program; }  
      Renderer Class
      #include "Renderer.h" #include "Error.h" Renderer::Renderer() { } Renderer::~Renderer() { } void Renderer::Draw(VertexArray * vao, IndexBuffer * ibo, Texture *texture, Shader * program) { vao->Bind(); ibo->Bind(); program->Bind(); if (texture != NULL) texture->Bind(); GLCall(glDrawElements(GL_TRIANGLES, ibo->GetCount(), GL_UNSIGNED_INT, NULL)); } void Renderer::Clear(float r, float g, float b) { GLCall(glClearColor(r, g, b, 1.0)); GLCall(glClear(GL_COLOR_BUFFER_BIT)); } void Renderer::Update(GLFWwindow *window) { /* Swap front and back buffers */ glfwSwapBuffers(window); /* Poll for and process events */ glfwPollEvents(); }  
      Shader Code
      #shader vertex #version 330 core layout(location = 0) in vec4 aPos; layout(location = 1) in vec2 aTexCoord; out vec2 t_TexCoord; uniform mat4 u_MVP; void main() { gl_Position = u_MVP * aPos; t_TexCoord = aTexCoord; } #shader fragment #version 330 core out vec4 aColor; in vec2 t_TexCoord; uniform sampler2D u_Texture; void main() { aColor = texture(u_Texture, t_TexCoord); } Also i'm pretty sure that every time i'm hitting the up, down, left and right arrows on the keyboard, i'm changing the model Matrix of the Player and not the others.
       
      Window Class:
      #include "Window.h" #include <GL/glew.h> #include <GLFW/glfw3.h> #include "Error.h" #include "Renderer.h" #include "Scene.h" #include "Input.h" //Global Variables. int screen_width, screen_height; //On Window Resize. void OnWindowResize(GLFWwindow *window, int width, int height); //Implementation Structure. struct Window::Implementation { //GLFW Window. GLFWwindow *GLFW_window; //Renderer. Renderer *renderer; //Delta Time. double delta_time; //Frames Per Second. int fps; //Scene. Scene *scnene; //Input. Input *input; //Deconstructor. ~Implementation(); }; //Window Constructor. Window::Window(std::string title, int width, int height) { //Initializing width and height. screen_width = width; screen_height = height; //Create Pointer To Implementation. m_Impl = new Implementation(); //Try initializing GLFW. if (!glfwInit()) { std::cout << "GLFW could not be initialized!" << std::endl; std::cout << "Press ENTER to exit..." << std::endl; std::cin.get(); exit(-1); } //Setting up OpenGL Version 3.3 Core Profile. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); /* Create a windowed mode window and its OpenGL context */ m_Impl->GLFW_window = glfwCreateWindow(width, height, title.c_str(), NULL, NULL); if (!m_Impl->GLFW_window) { std::cout << "GLFW could not create a window!" << std::endl; std::cout << "Press ENTER to exit..." << std::endl; std::cin.get(); glfwTerminate(); exit(-1); } /* Make the window's context current */ glfwMakeContextCurrent(m_Impl->GLFW_window); //Initialize GLEW. if(glewInit() != GLEW_OK) { std::cout << "GLEW could not be initialized!" << std::endl; std::cout << "Press ENTER to exit..." << std::endl; std::cin.get(); glfwTerminate(); exit(-1); } //Enabling Blending. GLCall(glEnable(GL_BLEND)); GLCall(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); //Setting the ViewPort. GLCall(glViewport(0, 0, width, height)); //**********Initializing Implementation**********// m_Impl->renderer = new Renderer(); m_Impl->delta_time = 0.0; m_Impl->fps = 0; m_Impl->input = new Input(this); //**********Initializing Implementation**********// //Set Frame Buffer Size Callback. glfwSetFramebufferSizeCallback(m_Impl->GLFW_window, OnWindowResize); } //Window Deconstructor. Window::~Window() { delete m_Impl; } //Window Main Loop. void Window::MainLoop() { //Time Variables. double start_time = 0, end_time = 0, old_time = 0, total_time = 0; //Frames Counter. int frames = 0; /* Loop until the user closes the window */ while (!glfwWindowShouldClose(m_Impl->GLFW_window)) { old_time = start_time; //Total time of previous frame. start_time = glfwGetTime(); //Current frame start time. //Calculate the Delta Time. m_Impl->delta_time = start_time - old_time; //Get Frames Per Second. if (total_time >= 1) { m_Impl->fps = frames; total_time = 0; frames = 0; } //Clearing The Screen. m_Impl->renderer->Clear(0, 0, 0); //Render The Scene. if (m_Impl->scnene != NULL) m_Impl->scnene->Render(this); //Updating the Screen. m_Impl->renderer->Update(m_Impl->GLFW_window); //Increasing frames counter. frames++; //End Time. end_time = glfwGetTime(); //Total time after the frame completed. total_time += end_time - start_time; } //Terminate GLFW. glfwTerminate(); } //Load Scene. void Window::LoadScene(Scene * scene) { //Set the scene. m_Impl->scnene = scene; } //Get Delta Time. double Window::GetDeltaTime() { return m_Impl->delta_time; } //Get FPS. int Window::GetFPS() { return m_Impl->fps; } //Get Width. int Window::GetWidth() { return screen_width; } //Get Height. int Window::GetHeight() { return screen_height; } //Get Input. Input * Window::GetInput() { return m_Impl->input; } Renderer * Window::GetRenderer() { return m_Impl->renderer; } GLFWwindow * Window::GetGLFWindow() { return m_Impl->GLFW_window; } //Implementation Deconstructor. Window::Implementation::~Implementation() { delete renderer; delete input; } //OnWindowResize void OnWindowResize(GLFWwindow *window, int width, int height) { screen_width = width; screen_height = height; //Updating the ViewPort. GLCall(glViewport(0, 0, width, height)); }  
      Brain Class
      #include "Brain.h" #include "Sprite.h" #include "Window.h" struct Brain::Implementation { //Just A Flag. bool started; //Window Pointer. Window *window; //Sprite Pointer. Sprite *sprite; }; Brain::Brain(Window *window, Sprite *sprite) { //Create Pointer To Implementation. m_Impl = new Implementation(); //Initialize Implementation. m_Impl->started = true; m_Impl->window = window; m_Impl->sprite = sprite; } Brain::~Brain() { //Delete Pointer To Implementation. delete m_Impl; } void Brain::Start() { } void Brain::Update() { } Window * Brain::GetWindow() { return m_Impl->window; } Sprite * Brain::GetSprite() { return m_Impl->sprite; } bool Brain::GetStart() { return m_Impl->started; } void Brain::SetStart(bool value) { m_Impl->started = value; } Script Class (Its a Brain Subclass!!!)
      #include "Script.h" Script::Script(Window *window, Sprite *sprite) : Brain(window, sprite) { } Script::~Script() { } void Script::Start() { std::cout << "Game Started!" << std::endl; } void Script::Update() { Input *input = this->GetWindow()->GetInput(); Sprite *sp = this->GetSprite(); //Move this sprite. this->GetSprite()->Move(200 * this->GetWindow()->GetDeltaTime(), input->GetKeyDown("left"), input->GetKeyDown("right"), input->GetKeyDown("up"), input->GetKeyDown("down")); std::cout << sp->GetTag().c_str() << ".x = " << sp->GetPos()->x << ", " << sp->GetTag().c_str() << ".y = " << sp->GetPos()->y << std::endl; }  
      Main:
      #include "SpaceShooterEngine.h" #include "Script.h" int main() { Window w("title", 600,600); Scene *scene = new Scene(); Sprite *player = new Sprite("Resources/Images/player.png", "Player", 100,100); Sprite *other = new Sprite("Resources/Images/cherno.png", "Other", 400, 100); Sprite *other2 = new Sprite("Resources/Images/cherno.png", "Other", 300, 400); Brain *brain = new Script(&w, player); player->AddBrain(brain); scene->AddSprite(player); scene->AddSprite(other); scene->AddSprite(other2); w.LoadScene(scene); w.MainLoop(); return 0; }  
       
      I literally can't find what is wrong. If you need more code, ask me to post it. I will also attach all the source files.
      Brain.cpp
      Error.cpp
      IndexBuffer.cpp
      Input.cpp
      Renderer.cpp
      Scene.cpp
      Shader.cpp
      Sprite.cpp
      Texture.cpp
      VertexArray.cpp
      VertexBuffer.cpp
      VertexBufferLayout.cpp
      Window.cpp
      Brain.h
      Error.h
      IndexBuffer.h
      Input.h
      Renderer.h
      Scene.h
      Shader.h
      SpaceShooterEngine.h
      Sprite.h
      Texture.h
      VertexArray.h
      VertexBuffer.h
      VertexBufferLayout.h
      Window.h
    • By Cristian Decu
      Hello fellow programmers,
      For a couple of days now i've decided to build my own planet renderer just to see how floating point precision issues
      can be tackled. As you probably imagine, i've quickly faced FPP issues when trying to render absurdly large planets.
       
      I have used the classical quadtree LOD approach;
      I've generated my grids with 33 vertices, (x: -1 to 1, y: -1 to 1, z = 0).
      Each grid is managed by a TerrainNode class that, depending on the side it represents (top, bottom, left right, front, back),
      creates a special rotation-translation matrix that moves and rotates the grid away from the origin so that when i finally
      normalize all the vertices on my vertex shader i can get a perfect sphere.
      T = glm::translate(glm::dmat4(1.0), glm::dvec3(0.0, 0.0, 1.0)); R = glm::rotate(glm::dmat4(1.0), glm::radians(180.0), glm::dvec3(1.0, 0.0, 0.0)); sides[0] = new TerrainNode(1.0, radius, T * R, glm::dvec2(0.0, 0.0), new TerrainTile(1.0, SIDE_FRONT)); T = glm::translate(glm::dmat4(1.0), glm::dvec3(0.0, 0.0, -1.0)); R = glm::rotate(glm::dmat4(1.0), glm::radians(0.0), glm::dvec3(1.0, 0.0, 0.0)); sides[1] = new TerrainNode(1.0, radius, R * T, glm::dvec2(0.0, 0.0), new TerrainTile(1.0, SIDE_BACK)); // So on and so forth for the rest of the sides As you can see, for the front side grid, i rotate it 180 degrees to make it face the camera and push it towards the eye;
      the back side is handled almost the same way only that i don't need to rotate it but simply push it away from the eye.
      The same technique is applied for the rest of the faces (obviously, with the proper rotations / translations).
      The matrix that result from the multiplication of R and T (in that particular order) is send to my vertex shader as `r_Grid'.
      // spherify vec3 V = normalize((r_Grid * vec4(r_Vertex, 1.0)).xyz); gl_Position = r_ModelViewProjection * vec4(V, 1.0); The `r_ModelViewProjection' matrix is generated on the CPU in this manner.
      // No the most efficient way, but it works. glm::dmat4 Camera::getMatrix() { // Create the view matrix // Roll, Yaw and Pitch are all quaternions. glm::dmat4 View = glm::toMat4(Roll) * glm::toMat4(Pitch) * glm::toMat4(Yaw); // The model matrix is generated by translating in the oposite direction of the camera. glm::dmat4 Model = glm::translate(glm::dmat4(1.0), -Position); // Projection = glm::perspective(fovY, aspect, zNear, zFar); // zNear = 0.1, zFar = 1.0995116e12 return Projection * View * Model; } I managed to get rid of z-fighting by using a technique called Logarithmic Depth Buffer described in this article; it works amazingly well, no z-fighting at all, at least not visible.
      Each frame i'm rendering each node by sending the generated matrices this way.
      // set the r_ModelViewProjection uniform // Sneak in the mRadiusMatrix which is a matrix that contains the radius of my planet. Shader::setUniform(0, Camera::getInstance()->getMatrix() * mRadiusMatrix); // set the r_Grid matrix uniform i created earlier. Shader::setUniform(1, r_Grid); grid->render(); My planet's radius is around 6400000.0 units, absurdly large, but that's what i really want to achieve;
      Everything works well, the node's split and merge as you'd expect, however whenever i get close to the surface
      of the planet the rounding errors start to kick in giving me that lovely stairs effect.
      I've read that if i could render each grid relative to the camera i could get better precision on the surface, effectively
      getting rid of those rounding errors.
       
      My question is how can i achieve this relative to camera rendering in my scenario here?
      I know that i have to do most of the work on the CPU with double, and that's exactly what i'm doing.
      I only use double on the CPU side where i also do most of the matrix multiplications.
      As you can see from my vertex shader i only do the usual r_ModelViewProjection * (some vertex coords).
       
      Thank you for your suggestions!
       
    • By mike44
      HI
      I've a ok framebuffer looking from above. Now how to turn it 90' to look at it from the front?
      It looks almost right but the upper colors look like you're right in it. Those should be blue like sky.
      I draw GL_TRIANGLE_STRIP colored depending on a height value.
      Any ideas also on the logic? Thanks
    • By DelicateTreeFrog
      I have a 9-slice shader working mostly nicely:

          
      Here, both the sprites are separate images, so the shader code works well:
      varying vec4 color; varying vec2 texCoord; uniform sampler2D tex; uniform vec2 u_dimensions; uniform vec2 u_border; float map(float value, float originalMin, float originalMax, float newMin, float newMax) { return (value - originalMin) / (originalMax - originalMin) * (newMax - newMin) + newMin; } // Helper function, because WET code is bad code // Takes in the coordinate on the current axis and the borders float processAxis(float coord, float textureBorder, float windowBorder) { if (coord < windowBorder) return map(coord, 0, windowBorder, 0, textureBorder) ; if (coord < 1 - windowBorder) return map(coord, windowBorder, 1 - windowBorder, textureBorder, 1 - textureBorder); return map(coord, 1 - windowBorder, 1, 1 - textureBorder, 1); } void main(void) { vec2 newUV = vec2( processAxis(texCoord.x, u_border.x, u_dimensions.x), processAxis(texCoord.y, u_border.y, u_dimensions.y) ); // Output the color gl_FragColor = texture2D(tex, newUV); } External from the shader, I upload vec2(slice/box.w, slice/box.h) into the u_dimensions variable, and vec2(slice/clip.w, slice/clip.h) into u_border. In this scenario, box represents the box dimensions, and clip represents dimensions of the 24x24 image to be 9-sliced, and slice is 8 (the size of each slice in pixels).
      This is great and all, but it's very disagreeable if I decide I'm going to organize the various 9-slice images into a single image sprite sheet.

      Because OpenGL works between 0.0 and 1.0 instead of true pixel coordinates, and processes the full images rather than just the contents of the clipping rectangles, I'm kind of stumped about how to tell the shader to do what I need it to do. Anyone have pro advice on how to get it to be more sprite-sheet-friendly? Thank you!
    • By hellgasm
      Hello,
      I have a question about premultiplied alpha images, texture atlas and texture filter (minification with bilinear filter).
      (I use correct blending function for PMA and all my images are in premultiplied alpha format.)
      Suppose that there are 3 different versions of a plain square image:
      1. In a separate file, by itself. No padding (padding means alpha 0 pixels in my case).
      2. In an atlas in which the subtexture's top left corner(0, 0) is positioned on top left corner(0, 0) of atlas. There are padding on right and bottom but not on left and top.
      3. In an atlas, in which there are padding in each of the 4 directions of the subtexture.
      Do these 3 give the same result when texture is minified using Bilinear filter? If not I assume this means premultiplied alpha distorts images since alpha 0 pixels are included in interpolation. If so why do we use something that distorts our images? 
      And even if we don't use premultiplied alpha and use "normal" blending, alpha 0 pixels are still used in interpolation. We add bleeding to overcome problems caused by this (don't know if it causes exact true pixel rendering though). So the question is: Does every texture atlas cause distortion in contained images even if we use bilinear (without mipmaps)? If so why does everyone use atlas if it's something that's so bad?
      I tried to test this with a simple scenario but don't know if my test method is right.
      I made a yellow square image with red border. The entire square (border included) is 116x116 px. The entire image is 128x128. 
      I made two versions of this image. Both images are in premultiplied alpha format.
      1st version: square starts at 0, 0 and there are 12 pixels padding on bottom and right.
      2nd version: square is centered both horizontally and vertically so there are 6px padding on top, left, bottom and right.
      I scaled them to 32x32 (scaled entire image without removing padding) using Bilinear filter. And when rendered, they both give very very different results. One is exact while the other one is blurry. I need to know if this is caused by the problem I mentioned in the question.
      Here are the images I used in this test:
      Image (topleft):


      Image (mid):


      Render result:

      I try to use x, y and width, height values for sprite which match integers so subpixel rendering is not intended.
    • By KKTHXBYE
      So, algorithm looks like this:
      Use fbo
      Clear depth and color buffers
      Write depth
      Stretch fbo depth texture to screen size and compare that with final scene
       
      GLSL algo looks like this:
      Project light position and vertex position to screen space coords then move them to 0..1 space
      Compute projected vertex to light vector
      Then by defined number of samples go from projected vertex position to projected light position:
      - Get the depth from depth texture
      - unproject this given texture coord and depth value * 2.0 - 1.0 using inverse of (model*view)*projection matrix
      Find closest point on line (world_vertex_pos, wirld light pos) to unprojected point, if its less than 0.0001 then i say the ray hit something and original fragment is in shadow
       
      Now i forgot few things, so i'll have to ask:
      In vertex shader i do something like this
      vertexClip.x = dp43(MVP1, Vpos); vertexClip.y = dp43(MVP2, Vpos); vertexClip.z = dp43(MVP3, Vpos); vertexClip.w = dp43(MVP4, Vpos); scrcoord = vec3(vertexClip.x, vertexClip.y, vertexClip.z); Where float dp43(vec4 matrow, vec3 p) { return ( (matrow.x*p.x) + (matrow.y*p.y) + (matrow.z*p.z) + matrow.w ); } It looks like i dont have to divide scrcoord by vertexClip.w component when i do something like this at the end of shader
      gl_Position = vertexClip; and fragments are located where they should be...
      I pass scrcoord to fragment shader, then do 0.5 + 0.5 to know from which position of the depth tex i start to unproject values.
      So scrcoord should be in -1..1 space right?
      Another thing is with unprojecting a screen coord to 3d position:
      So far i use this formula:
      Get texel depth, do *2.0-1.0 for all xyz components
      Then multiple it by inverse of (model*view)*projection matrix like that:
      Not quite sure if this isneven correct:
      vec3 unproject(vec3 op) { vec3 outpos; outpos.x = dp43(imvp1, op); outpos.y = dp43(imvp2, op); outpos.z = dp43(imvp3, op); return outpos; }  
      And last question is about ray sampling i'm pretty sure it will skip some pixels making shadowed fragments unshadowed.... Need somehow to fix that too, but for now i have no clue...

      vec3 act_tex_pos = fcoord + projected_ldir * sample_step * float ( i );
       
       
      I checked depth tex for values and theyre right.

      Vert shader


  • Forum Statistics

    • Total Topics
      631073
    • Total Posts
      2997754
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!