I created a small scene in C and OpenGL. It is a plane with a small tunnel over it. I'm trying to move the OpenGL "camera" inside this tunnel. However, I've been having some difficult to configure perspective and the objects disapear as I translate the object (my idea was to rotate and translate the scene to enter the tunnel).
I'm trying not to use additional lybraies, such as GLUT.
Can someone help?
#include <windows.h>
#include <gl/gl.h>
#define sizeX 0.05f
#define sizeY 0.75f
#define incr 0.1
double xyz[3] = {0,0,0};
int op = 0;
void incrAxis(int v){
if(v != 0)
xyz[op] += incr;
else
xyz[op] -= incr;
printf("%f %f %f\n",xyz[0],xyz[1],xyz[2]);
}
void changeAxis(int v){
op = op + v;
if(op == 3)
op = 0;
else
if(op < 0)
op = 2;
}
void draw(){
double alt = -0.1;
glBegin(GL_QUADS);
glColor3f(0.5f, 0.5f, 0.5f); // black plane
glVertex3f( 0.275, 0.275, alt);
glVertex3f( 0.275,-0.275, alt);
glVertex3f(-0.275,-0.275, alt);
glVertex3f(-0.275, 0.275, alt);
glEnd();
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f); // plane
glVertex3f( 0.75, 0.75, 0.0f);
glVertex3f( 0.75,-0.75, 0.0f);
glVertex3f(-0.75,-0.75, 0.0f);
glVertex3f(-0.75, 0.75, 0.0f);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f( sizeX, sizeY, -sizeX);
glVertex3f( sizeX,-sizeY, -sizeX);
glVertex3f(-sizeX,-sizeY, -sizeX);
glVertex3f(-sizeX, sizeY, -sizeX);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(-sizeX, -sizeY, 0.0f);
glVertex3f(-sizeX, -sizeY, -sizeX);
glVertex3f(-sizeX, sizeY, -sizeX);
glVertex3f(-sizeX, sizeY, 0.0f);
glEnd();
glBegin(GL_QUADS);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(sizeX, -sizeY, 0.0f);
glVertex3f(sizeX, -sizeY, -sizeX);
glVertex3f(sizeX, sizeY, -sizeX);
glVertex3f(sizeX, sizeY, 0.0f);
glEnd();
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f(-sizeX, sizeY, 0.0f);
glVertex3f(-sizeX, sizeY, -sizeX);
glVertex3f( sizeX, sizeY, -sizeX);
glVertex3f( sizeX, sizeY, 0.0f);
glEnd();
}
LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);
void EnableOpenGL(HWND hwnd, HDC*, HGLRC*);
void DisableOpenGL(HWND, HDC, HGLRC);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
WNDCLASSEX wcex;
HWND hwnd;
HDC hDC;
HGLRC hRC;
MSG msg;
BOOL bQuit = FALSE;
/* register window class */
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_OWNDC;
wcex.lpfnWndProc = WindowProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "GLSample";
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);;
if (!RegisterClassEx(&wcex))
return 0;
/* create main window */
hwnd = CreateWindowEx(0,
"GLSample",
"OpenGL Sample",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
512,
512,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd, nCmdShow);
/* enable OpenGL for the window */
EnableOpenGL(hwnd, &hDC, &hRC);
/* program main loop */
while (!bQuit)
{
/* check for messages */
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
/* handle or dispatch messages */
if (msg.message == WM_QUIT)
{
bQuit = TRUE;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
/* OpenGL animation code goes here */
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(xyz[0],xyz[1],xyz[2]);
glRotatef(89, 1.0f, 0.0f, 0.0f);
glRotatef(50, 0.0f, 1.0f, 0.0f);
//glRotatef(5, 0.0f, 0.0f, 1.0f);
draw();
glPopMatrix();
SwapBuffers(hDC);
Sleep (1);
}
}
/* shutdown OpenGL */
DisableOpenGL(hwnd, hDC, hRC);
/* destroy the window explicitly */
DestroyWindow(hwnd);
return msg.wParam;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CLOSE:
PostQuitMessage(0);
break;
case WM_DESTROY:
return 0;
case WM_KEYDOWN:
{
switch (wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
break;
case VK_RIGHT:
changeAxis(+1);
break;
case VK_DOWN:
incrAxis(0);
break;
case VK_LEFT:
changeAxis(-1);
break;
case VK_UP:
incrAxis(1);
break;
}
}
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC)
{
PIXELFORMATDESCRIPTOR pfd;
int iFormat;
/* get the device context (DC) */
*hDC = GetDC(hwnd);
/* set the pixel format for the DC */
ZeroMemory(&pfd, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
iFormat = ChoosePixelFormat(*hDC, &pfd);
SetPixelFormat(*hDC, iFormat, &pfd);
/* create and enable the render context (RC) */
*hRC = wglCreateContext(*hDC);
wglMakeCurrent(*hDC, *hRC);
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
glClearDepth(1.0); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);//Realy Nice perspective calculations
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glFrustum(-10, 10, -10, 10, -100, 100);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
}
void DisableOpenGL (HWND hwnd, HDC hDC, HGLRC hRC)
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hRC);
ReleaseDC(hwnd, hDC);
}
I already solved the problem.
I replaced
glFrustum(-10, 10, -10, 10, -100, 100);
for
gluPerspective(45.0,1.0,0.1,200.0);
It now works fine.
Related
I used matrices from cglm to modify the camera and what I should've seen on the screen is a small square, but nothing shows up. I have this code:
#define GLEW_STATIC
#define STB_IMAGE_IMPLEMENTATION
#include<stdio.h>
#include<stdlib.h>
#include<GL/glew.h>
#include<GLFW/glfw3.h>
#include<stdbool.h>
#include<string.h>
#include<stb/stb_image.h>
#include<cglm/cglm.h>
const unsigned int width = 1054;
const unsigned int height = 1057;
GLint uniColor;
GLint xploc;
GLint yploc;
void key_callback();
int main(){
if(!glfwInit()){
printf("Failed to initialize glfw!\n");
return 1;
}else{
printf("Successfully initialized glfw!\n");
}
//Set up GLFW
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(width, height, "Title", NULL, NULL);
glfwSetKeyCallback(window, key_callback);
if(!window){
printf("Window creation failed!\n");
return 1;
}else{
printf("Window created successfully!\n");
}
glfwMakeContextCurrent(window);
//Initialize GLEW
glewExperimental = GL_TRUE;
if(glewInit() != GLEW_OK){
printf("Failed to initialize glew!\n");
return 1;
}else{
printf("Successfully initialized glew!\n");
}
//Set the swap interval to 1 millisecond
glfwSwapInterval(1);
//Set the vertices of the square
float Vertices[] = {
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f
};
//Set indices to make the square work
GLuint indices[] = {
0, 2, 1,
0, 3, 2
};
//Ignore this - it was the original square, but then I realized how I actually needed to make it work
float VerticesSquare[] = {
-0.5f, 0.5f, 0.0f,
0.5f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f
};
printf("GLfloat variable called successfully\n");
//Create, compile and link the shaders to the shader program
GLuint ShaderProgram = glCreateProgram();
GLuint ShaderObjv = glCreateShader(GL_VERTEX_SHADER);
GLuint ShaderObjf = glCreateShader(GL_FRAGMENT_SHADER);
const GLchar* pvs[1];
const GLchar* pfs[1];
//Set the shader code
const char* pVertexShaderText = "#version 330 core\n"
"layout(location = 0) in vec3 Position;\n"
"layout(location = 1) in vec3 incolor;\n"
"layout(location = 2) in vec2 Tex;\n"
"out vec3 outcolor;\n"
"out vec2 texcoords;\n"
"uniform uint xp;\n"
"uniform uint yp;\n"
"uniform mat4 model;\n"
"uniform mat4 view;\n"
"uniform mat4 proj;\n"
"void main(){\n"
" gl_Position = proj * view * model * vec4(Position, 1.0f);\n"
"outcolor = incolor;\n"
"texcoords = Tex;\n"
"}";
const char* pFragmentShaderText = "#version 330 core\n"
"uniform vec3 color;\n"
"uniform sampler2D tex0;\n"
"in vec3 outcolor;\n"
"in vec2 texcoords;\n"
"out vec4 FragColor;\n"
"void main(){\n"
" FragColor = vec4(outcolor, 1.0f);\n"
"}";
pvs[0] = pVertexShaderText;
pfs[0] = pFragmentShaderText;
GLint LenghtsVertex[1];
GLint LenghtsFragment[1];
LenghtsVertex[0] = strlen(pVertexShaderText);
LenghtsFragment[0] = strlen(pFragmentShaderText);
glShaderSource(ShaderObjv, 1, pvs, LenghtsVertex);
glShaderSource(ShaderObjf, 1, pfs, LenghtsFragment);
glCompileShader(ShaderObjv);
glCompileShader(ShaderObjf);
//Shader error handling
GLint successvs;
glGetShaderiv(ShaderObjv, GL_COMPILE_STATUS, &successvs);
if(!successvs){
GLchar InfoLog1[1024];
glGetShaderInfoLog(ShaderObjv, sizeof(InfoLog1), NULL, InfoLog1);
fprintf(stderr, "Error compiling shader type %d: '%s'\n", GL_VERTEX_SHADER, InfoLog1);
return 1;
}
GLint successfs;
glGetShaderiv(ShaderObjf, GL_COMPILE_STATUS, &successfs);
if(!successfs){
GLchar InfoLog2[1024];
glGetShaderInfoLog(ShaderObjf, sizeof(InfoLog2), NULL, InfoLog2);
fprintf(stderr, "Error compiling shader type %d: '%s'\n", GL_FRAGMENT_SHADER, InfoLog2);
return 1;
}
glAttachShader(ShaderProgram, ShaderObjv);
glAttachShader(ShaderProgram, ShaderObjf);
glLinkProgram(ShaderProgram);
GLint success;
glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &success);
if(!success){
GLchar InfoLog3[1024];
glGetProgramInfoLog(ShaderProgram, sizeof(InfoLog3), NULL, InfoLog3);
fprintf(stderr, "Error linking shader program: '%s'\n", InfoLog3);
return 1;
}
glValidateProgram(ShaderProgram);
GLint successl;
glGetProgramiv(ShaderProgram, GL_VALIDATE_STATUS, &successl);
if(!successl){
GLchar InfoLog4[1024];
glGetProgramInfoLog(ShaderProgram, sizeof(InfoLog4), NULL, InfoLog4);
fprintf(stderr, "Error validating shader program: '%s'\n", InfoLog4);
return 1;
}
glUseProgram(ShaderProgram);
//Set the vectors for the camera location
vec3 camerapos = {0.0f, 0.0f, -4.0f};
vec3 center = {0.0f, 0.0f, 0.0f};
vec3 yup = {0.0f, 1.0f, 0.0f};
//Create the matrices and make them be identity matrices
mat4 model;
mat4 view;
mat4 proj;
glm_mat4_identity(model);
glm_mat4_identity(view);
glm_mat4_identity(proj);
//Create the camera
glm_lookat(camerapos, center, yup, view);
glm_perspective(glm_rad(45.0f), (float)(width/height), 0.1f, 100.0f, proj);
//Set the uniform locations
GLint uniColor = glGetUniformLocation(ShaderProgram, "color");
GLint tex0uni = glGetUniformLocation(ShaderProgram, "tex0");
GLint xploc = glGetUniformLocation(ShaderProgram, "xp");
GLint yploc = glGetUniformLocation(ShaderProgram, "yp");
GLint modelloc = glGetUniformLocation(ShaderProgram, "model");
GLint viewloc = glGetUniformLocation(ShaderProgram, "view");
GLint projloc = glGetUniformLocation(ShaderProgram, "proj");
//Set the uniforms
glUniform3f(uniColor, 1.0f, 0.0f, 0.0f);
glUniform1i(tex0uni, 0);
glUniform1ui(xploc, 1);
glUniform1ui(yploc, 1);
glUniformMatrix4fv(modelloc, 1, GL_FALSE, (float*)model);
glUniformMatrix4fv(viewloc, 1, GL_FALSE, (float*)view);
glUniformMatrix4fv(projloc, 1, GL_FALSE, (float*)proj);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
//Create the buffers
GLuint VBO;
GLuint VAO = 0;
GLuint EBO;
glGenBuffers(1, &VBO);
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &EBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
printf("Buffer created successfully\n");
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
printf("Buffer data set up successfully\n");
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
printf("Enabling buffer successfull\n");
//Set the texture (I won't be using it for now)
int texwidth, texheight, texnum;
stbi_set_flip_vertically_on_load(true);
unsigned char* bytes = stbi_load("image.png", &texwidth, &texheight, &texnum, 0);
GLuint texture;
glGenTextures(1, &texture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
float flatcolor[] = {1.0f, 1.0f, 1.0f, 1.0f};
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, flatcolor);
printf("Set parameters successfully\n");
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texwidth, texheight, 0, GL_RGB, GL_UNSIGNED_BYTE, bytes);
glGenerateMipmap(GL_TEXTURE_2D);
printf("Texture set successfully\n");
//Set the VertexAttribPointers at locations 0, 1 and 2
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
printf("First pointer succeeded\n");
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
printf("Second pointer succeeded\n");
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
printf("Third pointer succeeded\n");
printf("Setting up VectexAttribPointer successfull\n");
while(!glfwWindowShouldClose(window)){
glfwPollEvents();
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
//glDrawArrays(GL_TRIANGLES, 0, 3);
//Draw the elements
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
GLenum err;
if((err = glGetError()) != GL_NO_ERROR){
printf("OpenGL error: %d\n", err);
}
glfwSwapBuffers(window);
}
return 0;
}
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if(key == GLFW_KEY_R && action == GLFW_PRESS){
glUniform3f(uniColor, 1.0f, 0.0f, 0.0f);
}else if(key == GLFW_KEY_G && action == GLFW_PRESS){
glUniform3f(uniColor, 0.0f, 1.0f, 0.0f);
}else if(key == GLFW_KEY_B && action == GLFW_PRESS){
glUniform3f(uniColor, 0.0f, 0.0f, 1.0f);
}else if(key == GLFW_KEY_D && action == GLFW_PRESS){
glUniform1ui(xploc, 2);
}else if(key == GLFW_KEY_A && action == GLFW_PRESS){
glUniform1ui(xploc, 1);
}
}
I searched cglm's documentation, but didn't find a fix. There were some old stackoverflow questions on similar topics, but none actually solved my problem. I figured it has something to do with how I supply information to cglm's functions. I added comments, so it is easier to read.
As it turns out (float)(width/height) was supposed to be (float)width/(float)height as the first example was actually outputting 0 or 1, rather than 0.99716177861.
I'm trying to use GL_R8UI to pass unsigned, unnormalized data to a shader, but have found that on at least one GPU it doesn't work.
ie: this works:
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, 32, 32, 0, GL_RED, GL_UNSIGNED_BYTE, pData);
but this doesn't:
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8UI, 32, 32, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, pData);
I'm also changing the shader to use sampler2D vs usampler2D and updating the math in the shader appropriately, but finding it works on AMD/Radeon cards but fails on Intel and NVidia cards - the usampler2D always seems to return zero.
I've put together a minimal sample program here. The #define NORMALIZED switches between the two approaches.
So... my main question is: is this simply a driver problem or is there something else wrong in my code that's causing this?
To ask this question another way... what else needs to be changed to switch from GL_R8 normalized data to GL_R8UI unnormalized data, besides:
changing the call to glTextImage2D
changing from sampler2D to usampler2D in the shader
changing the shader to work with uint's instead of floats
changing the math in the shader to deal with normalized vs unnormalized data.
I've now logged an bug report with Intel: https://software.intel.com/en-us/forums/graphics-driver-bug-reporting/topic/748843
Since it was asked for here's the full example program source:
// ShaderTest.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "ShaderTest.h"
#include <stdlib.h>
#include <stdint.h>
#include <GL/gl3w.h>
#pragma comment(lib, "opengl32.lib")
#define NORMALIZED
const char* pszVertexShader = R"***(
#version 150
uniform mat4 transform;
attribute vec3 position;
varying vec2 vPosition;
void main()
{
gl_Position = transform * vec4(position,1.);
vPosition = position.xy;
}
)***";
#ifdef NORMALIZED
const char* pszFragmentShader = R"***(
#version 150
uniform sampler2D TextureData;
varying vec2 vPosition;
void main()
{
float red = texelFetch(TextureData, ivec2(0, 0), 0).r;
gl_FragColor = vec4(red , 0, 0, 1);
}
)***";
#else
const char* pszFragmentShader = R"***(
#version 150
uniform usampler2D TextureData;
varying vec2 vPosition;
void main()
{
// Original post had this wrong
// float red = float(texelFetch(TextureData, ivec2(0, 0), 0)).r/255.0;
// Fixed version - still fails on Intel GPUs though
float red = float(texelFetch(TextureData, ivec2(0, 0), 0).r)/255.0;
gl_FragColor = vec4(red, 0, 0, 1);
}
)***";
#endif
int CompileShader(GLenum type, const char* pszSource)
{
int iShader = glCreateShader(type);
glShaderSource(iShader, 1, &pszSource, NULL);
glCompileShader(iShader);
// Dump log
int length;
glGetShaderiv(iShader, GL_INFO_LOG_LENGTH, &length);
if (length != 0)
{
char* pszLog = (char*)_alloca((sizeof(char) + 10) * length);
GLsizei len;
glGetShaderInfoLog(iShader, length, &len, pszLog);
OutputDebugStringA(pszLog);
}
// Check for error
int status;
glGetShaderiv(iShader, GL_COMPILE_STATUS, &status);
if (status == 0)
{
// Clean up after failuer
glDeleteShader(iShader);
return 0;
}
// Success
return iShader;
}
// Globals
HINSTANCE hInst;
HGLRC g_hRC;
GLint g_iVertexShader = 0;
GLint g_iFragmentShader = 0;
GLint g_iShaderProgram = 0;
GLuint g_iTexture = 0;
GLuint g_iVertexBuffer = 0;
#define glCheck() assert(glGetError() == 0)
struct VERTEX
{
float x;
float y;
float z;
};
bool Setup()
{
// Compile shaders
g_iVertexShader = CompileShader(GL_VERTEX_SHADER, pszVertexShader);
g_iFragmentShader = CompileShader(GL_FRAGMENT_SHADER, pszFragmentShader);
// Link program
g_iShaderProgram = glCreateProgram();
glAttachShader(g_iShaderProgram, g_iVertexShader);
glAttachShader(g_iShaderProgram, g_iFragmentShader);
glLinkProgram(g_iShaderProgram);
// Dump log
int length;
glGetProgramiv(g_iShaderProgram, GL_INFO_LOG_LENGTH, &length);
if (length != 0)
{
char* pszLog = (char*)_alloca((sizeof(char) + 10) * length);
GLsizei len;
glGetProgramInfoLog(g_iShaderProgram, length, &len, pszLog);
OutputDebugStringA(pszLog);
}
// Check for error
int status;
glGetProgramiv(g_iShaderProgram, GL_LINK_STATUS, &status);
if (status == 0)
return false;
// Create texture
glGenTextures(1, &g_iTexture);
glBindTexture(GL_TEXTURE_2D, g_iTexture);
uint8_t* pData = (uint8_t*)_alloca(32 * 32 * sizeof(uint8_t));
memset(pData, 128, 32 * 32 * sizeof(uint8_t));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
#ifdef NORMALIZED
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, 32, 32, 0, GL_RED, GL_UNSIGNED_BYTE, pData);
#else
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8UI, 32, 32, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, pData);
#endif
glBindTexture(GL_TEXTURE_2D, 0);
// Create vertex buffer
glGenBuffers(1, &g_iVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, g_iVertexBuffer);
VERTEX v[] = {
{ 10, 10, 0, },
{ 10, 230, 0, },
{ 310, 10, 0, },
{ 310, 230, 0, },
};
glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
// Done
return true;
}
void Cleanup()
{
if (g_iVertexBuffer)
glDeleteBuffers(1, &g_iVertexBuffer);
if (g_iTexture)
glDeleteTextures(1, &g_iTexture);
if (g_iShaderProgram)
glDeleteProgram(g_iShaderProgram);
if (g_iVertexShader)
glDeleteShader(g_iVertexShader);
if (g_iFragmentShader)
glDeleteShader(g_iFragmentShader);
}
void Display(RECT* prc)
{
// Setup viewport
glViewport(0, 0, prc->right, prc->bottom);
// Clear background
glClearColor(0, 0, 0.5f, 1);
glClear(GL_COLOR_BUFFER_BIT);
// Setup program
glUseProgram(g_iShaderProgram);
// Bind vertex buffer
glBindBuffer(GL_ARRAY_BUFFER, g_iVertexBuffer);
// Setup vertex buffer
int aPosition = glGetAttribLocation(g_iShaderProgram, "position");
glEnableVertexAttribArray(aPosition);
glVertexAttribPointer(aPosition, 3, GL_FLOAT, false, sizeof(VERTEX), 0);
// Setup texture
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(GL_TEXTURE_2D, g_iTexture);
int uTextureData = glGetUniformLocation(g_iShaderProgram, "TextureData");
glUniform1i(uTextureData, 0);
// Setup ortho projection
float left = 0;
float right = 320;
float top = 0;
float bottom = 240;
float fnear = -1;
float ffar = 1;
float proj[] = {
(float)(2.0 / (right - left)), 0.0f, 0.0f, 0.0f,
0.0f, (float)(2.0 / (top - bottom)), 0.0f, 0.0f,
0.0f, 0.0f, (float)(-2.0 / (ffar - fnear)), 0.0f,
(float)(-(right + left) / (right - left)), (float)(-(top + bottom) / (top - bottom)), (float)(-(ffar + fnear) / (ffar - fnear)), 1.0f
};
int uTransform = glGetUniformLocation(g_iShaderProgram, "transform");
glUniformMatrix4fv(uTransform, 1, false, proj);
// Draw
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glFlush();
}
bool InitOpenGLContext(HWND hWnd)
{
// Setup pixel format
HDC hDC = GetDC(hWnd);
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
int pf = ChoosePixelFormat(hDC, &pfd);
if (pf == 0 || !SetPixelFormat(hDC, pf, &pfd))
return false;
DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
g_hRC = wglCreateContext(hDC);
if (!g_hRC)
return false;
// Init gl3w
wglMakeCurrent(hDC, g_hRC);
int err = gl3wInit();
if (err)
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(g_hRC);
g_hRC = NULL;
return false;
}
// Setup
if (!Setup())
{
assert(false);
Cleanup();
wglMakeCurrent(NULL, NULL);
wglDeleteContext(g_hRC);
g_hRC = NULL;
return false;
}
ReleaseDC(hWnd, hDC);
return true;
}
void CleanupOpenGLContext(HWND hWnd)
{
HDC hDC = GetDC(hWnd);
wglMakeCurrent(hDC, g_hRC);
Cleanup();
wglMakeCurrent(NULL, NULL);
ReleaseDC(hWnd, hDC);
wglDeleteContext(g_hRC);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
RECT rc;
GetClientRect(hWnd, &rc);
HDC hdc = BeginPaint(hWnd, &ps);
wglMakeCurrent(hdc, g_hRC);
Display(&rc);
wglMakeCurrent(NULL, NULL);
EndPaint(hWnd, &ps);
}
break;
case WM_CLOSE:
PostQuitMessage(0);
break;
case WM_ERASEBKGND:
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
// Register Class
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SHADERTEST));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"ShaderTest";
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
RegisterClassExW(&wcex);
// Create Window
HWND hWnd = CreateWindowW(L"ShaderTest", L"ShaderTest", WS_OVERLAPPEDWINDOW,
50, 50, 100, 100, nullptr, nullptr, hInstance, nullptr);
if (!hWnd)
return 7;
RECT rc;
rc.left = 0;
rc.top = 0;
rc.right = 320;
rc.bottom = 240;
AdjustWindowRect(&rc, GetWindowLong(hWnd, GWL_STYLE), FALSE);
SetWindowPos(hWnd, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
if (!InitOpenGLContext(hWnd))
{
DestroyWindow(hWnd);
return 7;
}
// Show window
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
// Main message loop:
MSG msg;
while (GetMessage(&msg, nullptr, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
CleanupOpenGLContext(hWnd);
DestroyWindow(hWnd);
return (int) msg.wParam;
}
Integer textures need to have nearest filtering (not linear or mipmap):
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
I am stuck trying to get this code to work in Visual Studio 2012 using glut. It renders a 10/10 3D grid but it will not respond to my input from the keyboard. I am trying to get the camera to rotate around the origin when i hit the left arrow key.
// This example shows how to create a camera for 3D graphics.
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include <iostream>
#include <cmath>
#include <math.h>
using namespace std;
int g_winWidth = 1024;
int g_winHeight = 512;
bool keyStatus[256];
float angle = 0.0f; //angle for rotating camera
float beginning_angle = 0.0f;
float cx = 10.0, cy = 10.0, cz = -10.0;
void initialGL()
{
glEnable(GL_DEPTH_TEST);
glClearColor (1.0f, 1.0f, 1.0f, 0.0f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
}
//initialize the keyboard keys
void initialization()
{
for(int i =0; i<256; i++)
keyStatus[i] = false;
}
//function to draw the colored x,y, and z axis
void drawCS()
{
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glScalef(10.0f, 10.0f, 10.0f);
glLineWidth(2.5f);
glBegin(GL_LINES);
//axis x
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.3f, 0.0f, 0.0f);
//text x
glVertex3f(0.4f, 0.05f, 0.0f);
glVertex3f(0.5f, -0.05f, 0.0f);
glVertex3f(0.4f, -0.05f, 0.0f);
glVertex3f(0.5f, 0.05f, 0.0f);
//axis y
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.3f, 0.0f);
//text y
glVertex3f(0.0f, 0.5f, 0.0f);
glVertex3f(0.0f, 0.4f, 0.0f);
glVertex3f(-0.05f, 0.55f, 0.0f);
glVertex3f(0.0f, 0.5f, 0.0f);
glVertex3f(0.05f, 0.55f, 0.0f);
glVertex3f(0.0f, 0.5f, 0.0f);
//axis z
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.3f);
//text z
glVertex3f(-0.025f, 0.025f, 0.4f);
glVertex3f(0.025f, 0.025f, 0.4f);
glVertex3f(0.025f, 0.025f, 0.4f);
glVertex3f(-0.025f, -0.025f, 0.4f);
glVertex3f(-0.025f, -0.025f, 0.4f);
glVertex3f(0.025f, -0.025f, 0.4f);
glEnd();
glLineWidth(1.0f);
glPopMatrix();
}
//function to draw the grid
void drawGrid()
{
int size = 10; // determining the grid size and the numbers of cells
if(size%2 != 0) ++size;
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
//glScalef(30.0f, 30.0f, 30.0f);
glBegin(GL_LINES);
for (int i =0; i<size+1; i++) {
if((float)i == size/2.0f) {
glColor3f(0.0f, 0.0f, 0.0f);
} else {
glColor3f(0.8f, 0.8f, 0.8f);
}
glVertex3f(-size/2.0f, 0.0f, -size/2.0f+i);
glVertex3f(size/2.0f, 0.0f, -size/2.0f+i);
glVertex3f(-size/2.0f+i, 0.0f, -size/2.0f);
glVertex3f(-size/2.0f+i, 0.0f, size/2.0f);
}
glEnd();
glPopMatrix();
}
//function to display everything that is happening in window
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawGrid();// call to function to draw the grid
drawCS();//call to function to draw the x,y,z axis
glutSwapBuffers();
}
void reshape(int w, int h)
{
g_winWidth = w;
g_winHeight = h;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//this function sets the initial position of the camera in 3D space
/*
Need to find a way to rotate around the origin from left to right
*/
gluLookAt( cx, cy, cz, //camera position
0.0f, 0.0f, 0.0f, //what camera looks at
0.0f, 1.0f, 0.0f); //
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, g_winWidth/g_winHeight, 0.1, 100);//specifies the view for the scene
glViewport(0, 0, w, h);
//angle += 0.1f;
}
//keyboard function for the exit key
void keyboard(unsigned char key, int x, int y)
{
keyStatus[key] = true;
switch (key) {
case 27:
exit(0);
break;
default:
break;
}
}
//sets the keyboard callback to the current window
void keyboardUp(unsigned char key, int x, int y)
{
keyStatus[key] = false;
}
//function for arrow keys output
void processSpecialKeys(int key, int xx, int yy) {
switch(key) {
case GLUT_KEY_LEFT :
//What the left arrow key does
angle -= 0.01f;
cx = sin(angle);
cz = -cos(angle);
break;
case GLUT_KEY_RIGHT :
//What the right arrow key does
break;
case GLUT_KEY_UP :
//What the up arrow key does
break;
case GLUT_KEY_DOWN :
//What the down arrow key does
break;
}
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(g_winWidth, g_winHeight);
glutInitWindowPosition(0, 0);
glutCreateWindow("Camera");
initialGL();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(display);
glutKeyboardFunc(keyboard);
glutKeyboardUpFunc(keyboardUp);
glutSpecialFunc(processSpecialKeys);
glEnable(GL_DEPTH_TEST);
initialization();
glutMainLoop();
return 1;//changed from EXIT_SUCCESS
}
I tried rendering a cube using OpenGL, in Windows. But the display window is black. I enabled the Z-Buffer, I clear the depth bit in the glClear function, etc. But no luck. And the problem is that every example or documentation I follow, is incomplete, or omit some information, and I'm very, very confused right now. I don't know what am I doing right and what am I doing wrong.
All I want is to display a cube, to know that the renderer is ready for 3D graphics (I can display 2D graphics with no problems). Nothing else.
This is the code of my main program:
#include "demo.h"
#include "renderfunc.c"
HDC hDC;
HGLRC hRC;
void enableGL(HWND hWnd)
{
hDC = GetDC(hWnd);
int nPixelFormat;
static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
24,
0,0,0,0,0,0,
0,0,
0,0,0,0,0,
32,
0,
0,
PFD_MAIN_PLANE,
0,
0,0,0 };
if(!hDC)
{
MessageBox(hWnd,L"Can't Create A GL Device Context.",L"ERROR",MB_OK|MB_ICONEXCLAMATION);
return;
}
nPixelFormat = ChoosePixelFormat(hDC, &pfd);
if(!nPixelFormat)
{
MessageBox(hWnd,L"Can't find a proper Pixel Format.",L"ERROR",MB_OK|MB_ICONEXCLAMATION);
return;
}
SetPixelFormat(hDC, nPixelFormat, &pfd);
/* Those lines has to be here*/
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC,hRC);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/* UNCOMMENT THIS SECTION FOR 3D */
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_EQUAL); //In some examples this is GL_LESS
glDepthMask(GL_TRUE);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //Accurate perspective calculations
return;
}
GLvoid ChangeSize(GLsizei width, GLsizei height)
{
if(height==0)
height=1;
glViewport(0,0,width,height);
//glLoadIdentity();
/* THIS SECTION IS FOR 3D GRAPHICS */
/* Comment glLoadIdentity above, and uncomment this section */
/* If you enable Z-buffer */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
return;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
enableGL(hWnd);
return 0;
case WM_CLOSE:
PostQuitMessage(0);
return 0;
case WM_DESTROY:
ReleaseDC(hWnd,hDC);
wglMakeCurrent(hDC, NULL);
wglDeleteContext(hRC);
PostQuitMessage(0);
return 0;
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
return 0;
}
return 0;
case WM_PAINT:
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* GL ANIMATION GOES HERE */
//Change this for whatever you want to render
renderCubeTest();
/* -------------------- */
SwapBuffers(hDC);
ValidateRect(hWnd, NULL);
return 0;
case WM_SIZE:
ChangeSize(LOWORD(lParam), HIWORD(lParam));
return 0;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
{
WNDCLASS wc;
HWND hWnd;
MSG msg;
//String with the name of the class of our window
LPCTSTR classname = L"OpenGL";
//String with the title of our window
LPCTSTR windowtitle = L"Cubes Demo By Ninjihaku Software";
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
//wc.hIcon = (HICON) LoadImage(hInstance, MAKEINTRESOURCE(IDI_APPICON), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED);
wc.hIcon = NULL;
wc.hCursor = (HCURSOR) LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = classname;
if(RegisterClass(&wc) == 0)
return false;
//hWnd = CreateWindow(classname, windowtitle, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 100, 100, 640, 480, NULL, NULL, hInstance, NULL);
hWnd = CreateWindowEx(WS_EX_APPWINDOW | WS_EX_WINDOWEDGE, classname, windowtitle, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, 640, 480, NULL, NULL, hInstance, NULL);
if(hWnd == NULL)
return FALSE;
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
while(GetMessage(&msg, NULL, 0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
DestroyWindow(hWnd);
return (int) msg.wParam;
}
Then the renderCubeTest() function included in renderfunc.c:
void renderCubeTest()
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glTranslatef(1.5f, 0.0f, -7.0f); // Move right and into the screen
glBegin(GL_QUADS); // Begin drawing the color cube with 6 quads
// Top face (y = 1.0f)
// Define vertices in counter-clockwise (CCW) order with normal pointing out
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
// Bottom face (y = -1.0f)
glColor3f(1.0f, 0.5f, 0.0f); // Orange
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
// Front face (z = 1.0f)
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
// Back face (z = -1.0f)
glColor3f(1.0f, 1.0f, 0.0f); // Yellow
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
// Left face (x = -1.0f)
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face (x = 1.0f)
glColor3f(1.0f, 0.0f, 1.0f); // Magenta
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glEnd(); // End of drawing color-cube
glFlush();
glPopMatrix();
return;
}
I hope someone can help me and tell me what's wrong with this.
glDepthFunc(GL_EQUAL);
I suspect this is the problem - what it basically does is tell OpenGL that pixels should only be rendered to the screen if the new pixel's depth value is equal to the current pixel's depth value. This is most certainly not what you want.
Instead, you should use either GL_LEQUAL (note the "L" before "EQUAL") or GL_LESS, as these are the normal comparison functions.
I implement a simple sphere camera by using OpenGL and I render a cube for observasion. But the cube is not displayed correctly. Like this:
Some surfaces of the cube are invisible, some are not. Can someone solve the problem? Here is the code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <gl/glut.h>
#define MAX_EPSILON_ERROR 10.0f
#define THRESHOLD 0.30f
#define REFRESH_DELAY 10 //ms
////////////////////////////////////////////////////////////////////////////////
// constants
const unsigned int window_width = 512;
const unsigned int window_height = 512;
// mouse controls
int mouse_old_x, mouse_old_y;
int mouse_buttons = 0;
float rotate_x = 0.0, rotate_y = 0.0;
float translate_z = -3.0;
// Auto-Verification Code
int fpsCount = 0; // FPS count for averaging
int fpsLimit = 1; // FPS limit for sampling
int g_Index = 0;
float avgFPS = 0.0f;
unsigned int frameCount = 0;
unsigned int g_TotalErrors = 0;
bool g_bQAReadback = false;
int *pArgc = NULL;
char **pArgv = NULL;
#define MAX(a,b) ((a > b) ? a : b)
////////////////////////////////////////////////////////////////////////////////
// declaration, forward
void cleanup();
// GL functionality
bool initGL(int *argc, char **argv);
// rendering callbacks
void display();
void keyboard(unsigned char key, int x, int y);
void mouse(int button, int state, int x, int y);
void motion(int x, int y);
void timerEvent(int value);
////////////////////////////////////////////////////////////////////////////////
// Program main
////////////////////////////////////////////////////////////////////////////////
int main(int argc, char **argv)
{
// First initialize OpenGL context
if (false == initGL(&argc, argv))
{
return false;
}
// register callbacks
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutMotionFunc(motion);
// start rendering mainloop
glutMainLoop();
atexit(cleanup);
return 0;
}
////////////////////////////////////////////////////////////////////////////////
//! Initialize GL
////////////////////////////////////////////////////////////////////////////////
bool initGL(int *argc, char **argv)
{
glutInit(argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowSize(window_width, window_height);
glutCreateWindow("Cuda GL Interop (VBO)");
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutMotionFunc(motion);
glutTimerFunc(REFRESH_DELAY, timerEvent,0);
//// initialize necessary OpenGL extensions
//glewInit();
//if (! glewIsSupported("GL_VERSION_2_0 "))
//{
// fprintf(stderr, "ERROR: Support for necessary OpenGL extensions missing.");
// fflush(stderr);
// return false;
//}
// default initialization
glClearColor(0.0, 0.0, 0.0, 1.0);
glDisable(GL_DEPTH_TEST);
// viewport
glViewport(0, 0, window_width, window_height);
// projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLfloat)window_width / (GLfloat) window_height, 2, 10.0);
// SDK_CHECK_ERROR_GL();
return true;
}
////////////////////////////////////////////////////////////////////////////////
//! Display callback
////////////////////////////////////////////////////////////////////////////////
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// set view matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, translate_z);
glRotatef(rotate_x, 1.0, 0.0, 0.0);
glRotatef(rotate_y, 0.0, 1.0, 0.0);
glBegin(GL_QUADS);
glColor3f(0.0f, 1.0f, 0.0f); // 颜色改成绿色
glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右上顶点 (顶面)
glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左上顶点 (顶面)
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的左下顶点 (顶面)
glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的右下顶点 (顶面)
glColor3f(1.0f,0.5f,0.0f); // 颜色改成橙色
glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的右上顶点(底面)
glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的左上顶点(底面)
glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左下顶点(底面)
glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右下顶点(底面)
glColor3f(1.0f,0.0f,0.0f); // 颜色改成红色
glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的右上顶点(前面)
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的左上顶点(前面)
glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的左下顶点(前面)
glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的右下顶点(前面)
glColor3f(1.0f,1.0f,0.0f); // 颜色改成黄色
glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右上顶点(后面)
glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左上顶点(后面)
glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左下顶点(后面)
glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右下顶点(后面)
glColor3f(0.0f,0.0f,1.0f); // 颜色改成蓝色
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的右上顶点(左面)
glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左上顶点(左面)
glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左下顶点(左面)
glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的右下顶点(左面)
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色
glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右上顶点(右面)
glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的左上顶点(右面)
glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的左下顶点(右面)
glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右下顶点(右面)
glEnd();
glutSwapBuffers();
}
void timerEvent(int value)
{
glutPostRedisplay();
glutTimerFunc(REFRESH_DELAY, timerEvent,0);
}
void cleanup()
{
//sdkDeleteTimer(&timer);
}
////////////////////////////////////////////////////////////////////////////////
//! Keyboard events handler
////////////////////////////////////////////////////////////////////////////////
void keyboard(unsigned char key, int /*x*/, int /*y*/)
{
switch (key)
{
case (27) :
exit(EXIT_SUCCESS);
break;
}
}
////////////////////////////////////////////////////////////////////////////////
//! Mouse event handlers
////////////////////////////////////////////////////////////////////////////////
void mouse(int button, int state, int x, int y)
{
if (state == GLUT_DOWN)
{
mouse_buttons |= 1<<button;
}
else if (state == GLUT_UP)
{
mouse_buttons = 0;
}
mouse_old_x = x;
mouse_old_y = y;
}
void motion(int x, int y)
{
float dx, dy;
dx = (float)(x - mouse_old_x);
dy = (float)(y - mouse_old_y);
if (mouse_buttons & 1)
{
rotate_x += dy * 0.2f;
rotate_y += dx * 0.2f;
}
else if (mouse_buttons & 4)
{
translate_z += dy * 0.01f;
}
mouse_old_x = x;
mouse_old_y = y;
}
Left click for rotation, and right click to change the radius.
Request a depth buffer:
glutInitDisplayMode(GLUT_DEPTH | GLUT_RGB | GLUT_DOUBLE);
^^^^^^^^^^
And enable depth testing:
glEnable(GL_DEPTH_TEST);