Hi,
ich hab jetzt nochmal komplett von null angefangen, ohne Wrapper-Klassen.
Ein einfaches Programm, um ein weißes Dreieck zu rendern.
//OpenGL Klasse
Code: Alles auswählen
#include "stdafx.h"
#include "opengl.h"
MyOpenGLContext::MyOpenGLContext()
{
}
MyOpenGLContext::MyOpenGLContext(HWND hwnd)
{
this->CreateContext(hwnd);
}
MyOpenGLContext::~MyOpenGLContext()
{
wglMakeCurrent(this->DeviceContext, 0); // Remove the rendering context from our device context
wglDeleteContext(this->RenderContext); // Delete our rendering context
ReleaseDC(this->WindowHandle, this->DeviceContext); // Release the device context from our window
}
bool MyOpenGLContext::CreateContext(HWND hwnd)
{
this->WindowHandle = hwnd;
this->DeviceContext = GetDC(hwnd);
PIXELFORMATDESCRIPTOR pfd; // Create a new PIXELFORMATDESCRIPTOR (PFD)
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); // Clear our PFD
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); // Set the size of the PFD to the size of the class
pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; // Enable double buffering, opengl support and drawing to a window
pfd.iPixelType = PFD_TYPE_RGBA; // Set our application to use RGBA pixels
pfd.cColorBits = 32; // Give us 32 bits of color information (the higher, the more colors)
pfd.cDepthBits = 32; // Give us 32 bits of depth information (the higher, the more depth levels)
pfd.iLayerType = PFD_MAIN_PLANE; // Set the layer of the PFD
int nPixelFormat = ChoosePixelFormat(this->DeviceContext, &pfd); // Check if our PFD is valid and get a pixel format back
if (nPixelFormat == 0) // If it fails
{
return false;
}
BOOL bResult = SetPixelFormat(this->DeviceContext, nPixelFormat, &pfd); // Try and set the pixel format based on our PFD
if (!bResult) // If it fails
{
return false;
}
HGLRC tempOpenGLContext = wglCreateContext(this->DeviceContext); // Create an OpenGL 2.1 context for our device context
wglMakeCurrent(this->DeviceContext, tempOpenGLContext); // Make the OpenGL 2.1 context current and active
GLenum error = glewInit(); // Enable GLEW
if (error != GLEW_OK) // If GLEW fails
{
return false;
}
int attributes[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, 3, // Set the MAJOR version of OpenGL to 3
WGL_CONTEXT_MINOR_VERSION_ARB, 2, // Set the MINOR version of OpenGL to 2
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, // Set our OpenGL context to be forward compatible
0
};
if (wglewIsSupported("WGL_ARB_create_context") == 1) { // If the OpenGL 3.x context creation extension is available
this->RenderContext = wglCreateContextAttribsARB(this->DeviceContext, NULL, attributes); // Create and OpenGL 3.x context based on the given attributes
wglMakeCurrent(NULL, NULL); // Remove the temporary context from being active
wglDeleteContext(tempOpenGLContext); // Delete the temporary OpenGL 2.1 context
wglMakeCurrent(this->DeviceContext, this->RenderContext); // Make our OpenGL 3.0 context current
}
else
{
this->RenderContext = tempOpenGLContext; // If we didn't have support for OpenGL 3.x and up, use the OpenGL 2.1 context
}
int glVersion[2] = {-1, -1}; // Set some default values for the version
glGetIntegerv(GL_MAJOR_VERSION, &glVersion[0]); // Get back the OpenGL MAJOR version we are using
glGetIntegerv(GL_MINOR_VERSION, &glVersion[1]); // Get back the OpenGL MAJOR version we are using
glDisable(GL_CULL_FACE),
glDisable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);
this->Shader = new AbstractShader();
bool shaderinit = this->Shader->InitShader("DefaultShader.vs", "DefaultShader.fs");
this->IndexBuffer = 0;
this->PositionBuffer = 0;
return true;
}
void MyOpenGLContext::SetupScene()
{
glClearColor(0.4f, 0.6f, 0.9f, 0.0f);
//IndexBuffer
glGenBuffers(1, &this->IndexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->IndexBuffer);
unsigned int indices[] = { 0,1,2 };
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
//PositionBuffer
glGenBuffers(1, &this->PositionBuffer);
glBindBuffer(GL_ARRAY_BUFFER, this->PositionBuffer);
static const float g_vertex_buffer_data[] = {
0.0f, 0.5f,
0.5f, -0.5f,
-0.5f, -0.5,
};
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
int loc = this->Shader->GetAttribLocation("vertex0");
glVertexAttribPointer(loc, 2, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void MyOpenGLContext::ResizeWindow(int width, int height)
{
this->WindowWidth = width;
this->WindowHeight = height;
}
void MyOpenGLContext::RenderScene()
{
glViewport(0, 0, this->WindowWidth, this->WindowHeight); // Set the viewport size to fill the window
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // Clear required buffers
this->Shader->Bind(); // Bind our shader
glEnableVertexAttribArray(this->Shader->GetAttribLocation("vertex0"));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->IndexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, this->PositionBuffer);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
this->Shader->Unbind(); // Unbind our shader
SwapBuffers(this->DeviceContext); // Swap buffers so we can see our rendering
}
//Shader Klasse
Code: Alles auswählen
#include "stdafx.h"
#include "AbstractShader.h"
AbstractShader::AbstractShader()
{
this->VertexShader = NULL;
this->FragmentShader = NULL;
this->ShaderProgram = NULL;
}
AbstractShader::~AbstractShader()
{
if (this->FragmentShader != NULL)
{
glDetachShader(this->ShaderProgram, this->FragmentShader);
glDeleteShader(this->FragmentShader);
}
if (this->VertexShader != NULL)
{
glDetachShader(this->ShaderProgram, this->VertexShader);
glDeleteShader(this->VertexShader);
}
if (this->ShaderProgram != NULL)
{
glDeleteProgram(this->ShaderProgram);
}
}
bool AbstractShader::InitShader(std::string vertexshader, std::string fragmentshader)
{
this->ShaderProgram = glCreateProgram();
this->VertexShader = glCreateShader(GL_VERTEX_SHADER);
this->FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
std::string vertexshaderpath = "./Resources/Shaders/" + vertexshader;
//Vertex-Shader erstellen
std::string vertexbuffer = this->readFile(vertexshaderpath);
if (vertexbuffer.empty())
{
return false;
}
const char* tmp = static_cast<const char*>(vertexbuffer.c_str());
glShaderSource(this->VertexShader, 1, (const char**)&tmp, 0);
glCompileShader(this->VertexShader);
int result;
glGetShaderiv(this->VertexShader, GL_COMPILE_STATUS, &result);
if(!result)
{
this->OutputShaderLog(this->VertexShader);
return false;
}
//Fragment-Shader erstellen
std::string fragshaderpath = "./Resources/Shaders/" + fragmentshader;
std::string fragmentbuffer = this->readFile(fragshaderpath);
if (fragmentbuffer.empty())
{
return false;
}
tmp = static_cast<const char*>(fragmentbuffer.c_str());
glShaderSource(this->FragmentShader, 1, (const char**)&tmp, 0);
glCompileShader(this->FragmentShader);
glGetShaderiv(this->FragmentShader, GL_COMPILE_STATUS, &result);
if(!result)
{
this->OutputShaderLog(this->FragmentShader);
return false;
}
glAttachShader(this->ShaderProgram, this->VertexShader);
glAttachShader(this->ShaderProgram, this->FragmentShader);
glBindAttribLocation(this->ShaderProgram, 0, "vertex0");
glLinkProgram(this->ShaderProgram);
glGetProgramiv(this->ShaderProgram, GL_LINK_STATUS, &result);
if(!result)
{
this->OutputProgramLog(this->ShaderProgram);
return false;
}
return true;
}
void AbstractShader::OutputShaderLog(unsigned int shaderID)
{
std::vector<char> infoLog;
GLint infoLen;
glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &infoLen);
infoLog.resize(infoLen);
glGetShaderInfoLog(shaderID, infoLog.size(), &infoLen, &infoLog[0]);
}
void AbstractShader::OutputProgramLog(unsigned int programID)
{
std::vector<char> infoLog;
GLint infoLen;
GLint result;
glGetProgramiv(programID, GL_LINK_STATUS, &result);
if(result)
{
return;
}
glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &infoLen);
infoLog.resize(infoLen);
glGetProgramInfoLog(programID, infoLog.size(), &infoLen, &infoLog[0]);
}
std::string AbstractShader::readFile(const std::string &filename)
{
std::ifstream file(filename.c_str());
if(!file.good())
{
//THROW_GraphicsException("error_readingfile","The Shader-Sourcefile could not be read",0);
return std::string();
}
std::string stringBuffer(std::istreambuf_iterator<char>(file), (std::istreambuf_iterator<char>()));
return stringBuffer;
}
void AbstractShader::Bind()
{
glUseProgram(this->ShaderProgram);
}
void AbstractShader::Unbind()
{
glUseProgram(NULL);
}
unsigned int AbstractShader::GetAttribLocation(const std::string &name)
{
return glGetAttribLocation(this->ShaderProgram, name.c_str());
}
main.cpp
Code: Alles auswählen
#include "stdafx.h"
#include "main.h"
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_SIZE: // If our window is resizing
{
OpenGL->ResizeWindow(LOWORD(lParam), HIWORD(lParam)); // Send the new window size to our OpenGLContext
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
break;
}
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
bool CreateNewWindow(LPCWSTR title, int width, int height)
{
WNDCLASS windowClass;
HWND hWnd;
DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
hInstance = GetModuleHandle(NULL);
windowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
windowClass.lpfnWndProc = (WNDPROC) WndProc;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = hInstance;
windowClass.hIcon = LoadIcon(NULL, IDI_WINLOGO);
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowClass.hbrBackground = NULL;
windowClass.lpszMenuName = NULL;
windowClass.lpszClassName = title;
if (!RegisterClass(&windowClass))
{
return false;
}
OpenGL = new MyOpenGLContext();
hWnd = CreateWindowEx(dwExStyle, title, title, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, width, height, NULL, NULL, hInstance, NULL);
OpenGL->CreateContext(hWnd); // Create our OpenGL context on the given window we just created
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
return true;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
/**
The following 6 lines of code do conversion between char arrays and LPCWSTR variables
which are used in the Windows API.
*/
char *orig = "OpenGL 3 Project"; // Our windows title
size_t origsize = strlen(orig) + 1;
const size_t newsize = 100;
size_t convertedChars = 0;
wchar_t wcstring[newsize];
mbstowcs_s(&convertedChars, wcstring, origsize, orig, _TRUNCATE);
CreateNewWindow(wcstring, 500, 500); // Create our OpenGL window
OpenGL->SetupScene(); // Setup our OpenGL scene
while (running)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{ // If we have a message to process, process it
if (msg.message == WM_QUIT)
{
running = false; // Set running to false if we have a message to quit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{ // If we don't have a message to process
OpenGL->RenderScene(); // Render our scene (which also handles swapping of buffers)
}
}
return (int) msg.wParam;
}
Alle Werte sind so wie sie sein sollten, GLSLDevil hat auch nichts auszusetzen.
Trotzdem wird nichts gerendert. Irgendwas grundsätzliches mach ich falsch.
Kann mir jemand sagen, was?
Gruß